summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnsible Core Team <info@ansible.com>2020-03-09 09:40:35 +0000
committerAnsible Core Team <info@ansible.com>2020-03-09 09:40:35 +0000
commite39b1dec45fe86210b669d6b1b117753b5b2c9f9 (patch)
tree0dd2d950fd7aa778fd90dd36b77effafe23a9dc9
parenta16d88b068f7086ace193e020c5157e0065a6685 (diff)
downloadansible-e39b1dec45fe86210b669d6b1b117753b5b2c9f9.tar.gz
Migrated to cisco.mso
-rw-r--r--lib/ansible/module_utils/network/aci/mso.py569
-rw-r--r--lib/ansible/modules/network/aci/mso_label.py167
-rw-r--r--lib/ansible/modules/network/aci/mso_role.py224
-rw-r--r--lib/ansible/modules/network/aci/mso_schema.py192
-rw-r--r--lib/ansible/modules/network/aci/mso_schema_site.py200
-rw-r--r--lib/ansible/modules/network/aci/mso_schema_site_anp.py213
-rw-r--r--lib/ansible/modules/network/aci/mso_schema_site_anp_epg.py228
-rw-r--r--lib/ansible/modules/network/aci/mso_schema_site_anp_epg_domain.py401
-rw-r--r--lib/ansible/modules/network/aci/mso_schema_site_anp_epg_staticleaf.py261
-rw-r--r--lib/ansible/modules/network/aci/mso_schema_site_anp_epg_staticport.py315
-rw-r--r--lib/ansible/modules/network/aci/mso_schema_site_anp_epg_subnet.py281
-rw-r--r--lib/ansible/modules/network/aci/mso_schema_site_bd.py225
-rw-r--r--lib/ansible/modules/network/aci/mso_schema_site_bd_l3out.py222
-rw-r--r--lib/ansible/modules/network/aci/mso_schema_site_bd_subnet.py266
-rw-r--r--lib/ansible/modules/network/aci/mso_schema_site_vrf.py212
-rw-r--r--lib/ansible/modules/network/aci/mso_schema_site_vrf_region.py225
-rw-r--r--lib/ansible/modules/network/aci/mso_schema_site_vrf_region_cidr.py257
-rw-r--r--lib/ansible/modules/network/aci/mso_schema_site_vrf_region_cidr_subnet.py271
-rw-r--r--lib/ansible/modules/network/aci/mso_schema_template.py247
-rw-r--r--lib/ansible/modules/network/aci/mso_schema_template_anp.py205
-rw-r--r--lib/ansible/modules/network/aci/mso_schema_template_anp_epg.py373
-rw-r--r--lib/ansible/modules/network/aci/mso_schema_template_anp_epg_contract.py262
-rw-r--r--lib/ansible/modules/network/aci/mso_schema_template_anp_epg_subnet.py258
-rw-r--r--lib/ansible/modules/network/aci/mso_schema_template_bd.py295
-rw-r--r--lib/ansible/modules/network/aci/mso_schema_template_bd_subnet.py241
-rw-r--r--lib/ansible/modules/network/aci/mso_schema_template_contract_filter.py340
-rw-r--r--lib/ansible/modules/network/aci/mso_schema_template_deploy.py142
-rw-r--r--lib/ansible/modules/network/aci/mso_schema_template_externalepg.py226
-rw-r--r--lib/ansible/modules/network/aci/mso_schema_template_filter_entry.py363
-rw-r--r--lib/ansible/modules/network/aci/mso_schema_template_l3out.py223
-rw-r--r--lib/ansible/modules/network/aci/mso_schema_template_vrf.py205
-rw-r--r--lib/ansible/modules/network/aci/mso_site.py246
-rw-r--r--lib/ansible/modules/network/aci/mso_tenant.py200
-rw-r--r--lib/ansible/modules/network/aci/mso_user.py248
-rw-r--r--lib/ansible/plugins/doc_fragments/mso.py71
-rw-r--r--test/integration/targets/mso_label/aliases2
-rw-r--r--test/integration/targets/mso_label/tasks/main.yml283
-rw-r--r--test/integration/targets/mso_role/aliases2
-rw-r--r--test/integration/targets/mso_role/tasks/main.yml289
-rw-r--r--test/integration/targets/mso_site/aliases2
-rw-r--r--test/integration/targets/mso_site/tasks/main.yml283
-rw-r--r--test/integration/targets/mso_tenant/aliases2
-rw-r--r--test/integration/targets/mso_tenant/tasks/main.yml289
-rw-r--r--test/integration/targets/mso_user/aliases2
-rw-r--r--test/integration/targets/mso_user/tasks/main.yml292
-rw-r--r--test/sanity/ignore.txt28
46 files changed, 0 insertions, 10348 deletions
diff --git a/lib/ansible/module_utils/network/aci/mso.py b/lib/ansible/module_utils/network/aci/mso.py
deleted file mode 100644
index a6036d2bb8..0000000000
--- a/lib/ansible/module_utils/network/aci/mso.py
+++ /dev/null
@@ -1,569 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com>
-# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)
-
-from __future__ import (absolute_import, division, print_function)
-__metaclass__ = type
-
-from copy import deepcopy
-from ansible.module_utils.basic import AnsibleModule, json
-from ansible.module_utils.six import PY3
-from ansible.module_utils.six.moves.urllib.parse import urlencode, urljoin
-from ansible.module_utils.urls import fetch_url
-from ansible.module_utils._text import to_bytes, to_native
-
-
-if PY3:
- def cmp(a, b):
- return (a > b) - (a < b)
-
-
-def issubset(subset, superset):
- ''' Recurse through nested dictionary and compare entries '''
-
- # Both objects are the same object
- if subset is superset:
- return True
-
- # Both objects are identical
- if subset == superset:
- return True
-
- # Both objects have a different type
- if type(subset) != type(superset):
- return False
-
- for key, value in subset.items():
- # Ignore empty values
- if value is None:
- return True
-
- # Item from subset is missing from superset
- if key not in superset:
- return False
-
- # Item has different types in subset and superset
- if type(superset[key]) != type(value):
- return False
-
- # Compare if item values are subset
- if isinstance(value, dict):
- if not issubset(superset[key], value):
- return False
- elif isinstance(value, list):
- try:
- # NOTE: Fails for lists of dicts
- if not set(value) <= set(superset[key]):
- return False
- except TypeError:
- # Fall back to exact comparison for lists of dicts
- if not cmp(value, superset[key]):
- return False
- elif isinstance(value, set):
- if not value <= superset[key]:
- return False
- else:
- if not value == superset[key]:
- return False
-
- return True
-
-
-def update_qs(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)
- return '?' + urlencode(accepted_params)
-
-
-def mso_argument_spec():
- return dict(
- host=dict(type='str', required=True, aliases=['hostname']),
- port=dict(type='int', required=False),
- username=dict(type='str', default='admin'),
- password=dict(type='str', required=True, no_log=True),
- 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),
- )
-
-
-def mso_reference_spec():
- return dict(
- name=dict(type='str', required=True),
- schema=dict(type='str'),
- template=dict(type='str'),
- )
-
-
-def mso_subnet_spec():
- return dict(
- subnet=dict(type='str', required=True, aliases=['ip']),
- description=dict(type='str'),
- scope=dict(type='str', choices=['private', 'public']),
- shared=dict(type='bool'),
- no_default_gateway=dict(type='bool'),
- )
-
-
-def mso_contractref_spec():
- return dict(
- name=dict(type='str', required=True),
- schema=dict(type='str'),
- template=dict(type='str'),
- type=dict(type='str', required=True, choices=['consumer', 'provider']),
- )
-
-
-class MSOModule(object):
-
- def __init__(self, module):
- self.module = module
- self.params = module.params
- self.result = dict(changed=False)
- self.headers = {'Content-Type': 'text/json'}
-
- # normal output
- self.existing = dict()
-
- # info output
- self.previous = dict()
- self.proposed = dict()
- self.sent = dict()
-
- # debug output
- self.has_modified = False
- self.filter_string = ''
- self.method = None
- self.path = None
- self.response = None
- self.status = None
- self.url = None
-
- # Ensure protocol is set
- self.params['protocol'] = 'https' if self.params.get('use_ssl', True) else 'http'
-
- # Set base_uri
- if self.params.get('port') is not None:
- self.baseuri = '{protocol}://{host}:{port}/api/v1/'.format(**self.params)
- else:
- self.baseuri = '{protocol}://{host}/api/v1/'.format(**self.params)
-
- if self.module._debug:
- self.module.warn('Enable debug output because ANSIBLE_DEBUG was set.')
- self.params['output_level'] = 'debug'
-
- if self.params.get('password'):
- # Perform password-based authentication, log on using password
- self.login()
- else:
- self.module.fail_json(msg="Parameter 'password' is required for authentication")
-
- def login(self):
- ''' Log in to MSO '''
-
- # Perform login request
- self.url = urljoin(self.baseuri, 'auth/login')
- payload = {'username': self.params.get('username'), 'password': self.params.get('password')}
- resp, auth = fetch_url(self.module,
- self.url,
- data=json.dumps(payload),
- method='POST',
- headers=self.headers,
- timeout=self.params.get('timeout'),
- use_proxy=self.params.get('use_proxy'))
-
- # Handle MSO response
- if auth.get('status') != 201:
- self.response = auth.get('msg')
- self.status = auth.get('status')
- self.fail_json(msg='Authentication failed: {msg}'.format(**auth))
-
- payload = json.loads(resp.read())
-
- self.headers['Authorization'] = 'Bearer {token}'.format(**payload)
-
- def request(self, path, method=None, data=None, qs=None):
- ''' Generic HTTP method for MSO requests. '''
- self.path = path
-
- if method is not None:
- self.method = method
-
- # If we PATCH with empty operations, return
- if method == 'PATCH' and not data:
- return {}
-
- self.url = urljoin(self.baseuri, path)
-
- if qs is not None:
- self.url = self.url + update_qs(qs)
-
- resp, info = fetch_url(self.module,
- self.url,
- headers=self.headers,
- data=json.dumps(data),
- method=self.method,
- timeout=self.params.get('timeout'),
- use_proxy=self.params.get('use_proxy'),
- )
- self.response = info.get('msg')
- self.status = info.get('status')
-
- # self.result['info'] = info
-
- # Get change status from HTTP headers
- if 'modified' in info:
- self.has_modified = True
- if info.get('modified') == 'false':
- self.result['changed'] = False
- elif info.get('modified') == 'true':
- self.result['changed'] = True
-
- # 200: OK, 201: Created, 202: Accepted, 204: No Content
- if self.status in (200, 201, 202, 204):
- output = resp.read()
- if output:
- return json.loads(output)
-
- # 404: Not Found
- elif self.method == 'DELETE' and self.status == 404:
- return {}
-
- # 400: Bad Request, 401: Unauthorized, 403: Forbidden,
- # 405: Method Not Allowed, 406: Not Acceptable
- # 500: Internal Server Error, 501: Not Implemented
- elif self.status >= 400:
- try:
- output = resp.read()
- payload = json.loads(output)
- except (ValueError, AttributeError):
- try:
- payload = json.loads(info['body'])
- except Exception:
- self.fail_json(msg='MSO Error:', data=data, info=info)
- if 'code' in payload:
- self.fail_json(msg='MSO Error {code}: {message}'.format(**payload), data=data, info=info, payload=payload)
- else:
- self.fail_json(msg='MSO Error:'.format(**payload), data=data, info=info, payload=payload)
-
- return {}
-
- def query_objs(self, path, key=None, **kwargs):
- ''' Query the MSO REST API for objects in a path '''
- found = []
- objs = self.request(path, method='GET')
-
- if objs == {}:
- return found
-
- if key is None:
- key = path
-
- if key not in objs:
- self.fail_json(msg="Key '%s' missing from data", data=objs)
-
- for obj in objs[key]:
- for kw_key, kw_value in kwargs.items():
- if kw_value is None:
- continue
- if obj[kw_key] != kw_value:
- break
- else:
- found.append(obj)
- return found
-
- def get_obj(self, path, **kwargs):
- ''' Get a specific object from a set of MSO REST objects '''
- objs = self.query_objs(path, **kwargs)
- if len(objs) == 0:
- return {}
- if len(objs) > 1:
- self.fail_json(msg='More than one object matches unique filter: {0}'.format(kwargs))
- return objs[0]
-
- def lookup_schema(self, schema):
- ''' Look up schema and return its id '''
- if schema is None:
- return schema
-
- s = self.get_obj('schemas', displayName=schema)
- if not s:
- self.module.fail_json(msg="Schema '%s' is not a valid schema name." % schema)
- if 'id' not in s:
- self.module.fail_json(msg="Schema lookup failed for schema '%s': %s" % (schema, s))
- return s.get('id')
-
- def lookup_domain(self, domain):
- ''' Look up a domain and return its id '''
- if domain is None:
- return domain
-
- d = self.get_obj('auth/domains', key='domains', name=domain)
- if not d:
- self.module.fail_json(msg="Domain '%s' is not a valid domain name." % domain)
- if 'id' not in d:
- self.module.fail_json(msg="Domain lookup failed for domain '%s': %s" % (domain, d))
- return d.get('id')
-
- def lookup_roles(self, roles):
- ''' Look up roles and return their ids '''
- if roles is None:
- return roles
-
- ids = []
- for role in roles:
- r = self.get_obj('roles', name=role)
- if not r:
- self.module.fail_json(msg="Role '%s' is not a valid role name." % role)
- if 'id' not in r:
- self.module.fail_json(msg="Role lookup failed for role '%s': %s" % (role, r))
- ids.append(dict(roleId=r.get('id')))
- return ids
-
- def lookup_site(self, site):
- ''' Look up a site and return its id '''
- if site is None:
- return site
-
- s = self.get_obj('sites', name=site)
- if not s:
- self.module.fail_json(msg="Site '%s' is not a valid site name." % site)
- if 'id' not in s:
- self.module.fail_json(msg="Site lookup failed for site '%s': %s" % (site, s))
- return s.get('id')
-
- def lookup_sites(self, sites):
- ''' Look up sites and return their ids '''
- if sites is None:
- return sites
-
- ids = []
- for site in sites:
- s = self.get_obj('sites', name=site)
- if not s:
- self.module.fail_json(msg="Site '%s' is not a valid site name." % site)
- if 'id' not in s:
- self.module.fail_json(msg="Site lookup failed for site '%s': %s" % (site, s))
- ids.append(dict(siteId=s.get('id'), securityDomains=[]))
- return ids
-
- def lookup_tenant(self, tenant):
- ''' Look up a tenant and return its id '''
- if tenant is None:
- return tenant
-
- t = self.get_obj('tenants', key='tenants', name=tenant)
- if not t:
- self.module.fail_json(msg="Tenant '%s' is not valid tenant name." % tenant)
- if 'id' not in t:
- self.module.fail_json(msg="Tenant lookup failed for tenant '%s': %s" % (tenant, t))
- return t.get('id')
-
- def lookup_users(self, users):
- ''' Look up users and return their ids '''
- if users is None:
- return users
-
- ids = []
- for user in users:
- u = self.get_obj('users', username=user)
- if not u:
- self.module.fail_json(msg="User '%s' is not a valid user name." % user)
- if 'id' not in u:
- self.module.fail_json(msg="User lookup failed for user '%s': %s" % (user, u))
- ids.append(dict(userId=u.get('id')))
- return ids
-
- def create_label(self, label, label_type):
- ''' Create a new label '''
- return self.request('labels', method='POST', data=dict(displayName=label, type=label_type))
-
- def lookup_labels(self, labels, label_type):
- ''' Look up labels and return their ids (create if necessary) '''
- if labels is None:
- return None
-
- ids = []
- for label in labels:
- l = self.get_obj('labels', displayName=label)
- if not l:
- l = self.create_label(label, label_type)
- if 'id' not in l:
- self.module.fail_json(msg="Label lookup failed for label '%s': %s" % (label, l))
- ids.append(l.get('id'))
- return ids
-
- def anp_ref(self, **data):
- ''' Create anpRef string '''
- return '/schemas/{schema_id}/templates/{template}/anps/{anp}'.format(**data)
-
- def epg_ref(self, **data):
- ''' Create epgRef string '''
- return '/schemas/{schema_id}/templates/{template}/anps/{anp}/epgs/{epg}'.format(**data)
-
- def bd_ref(self, **data):
- ''' Create bdRef string '''
- return '/schemas/{schema_id}/templates/{template}/bds/{bd}'.format(**data)
-
- def contract_ref(self, **data):
- ''' Create contractRef string '''
- # Support the contract argspec
- if 'name' in data:
- data['contract'] = data.get('name')
- return '/schemas/{schema_id}/templates/{template}/contracts/{contract}'.format(**data)
-
- def filter_ref(self, **data):
- ''' Create a filterRef string '''
- return '/schemas/{schema_id}/templates/{template}/filters/{filter}'.format(**data)
-
- def vrf_ref(self, **data):
- ''' Create vrfRef string '''
- return '/schemas/{schema_id}/templates/{template}/vrfs/{vrf}'.format(**data)
-
- def make_reference(self, data, reftype, schema_id, template):
- ''' Create a reference from a dictionary '''
- # Removes entry from payload
- if data is None:
- return None
-
- if data.get('schema') is not None:
- schema_obj = self.get_obj('schemas', displayName=data.get('schema'))
- if not schema_obj:
- self.fail_json(msg="Referenced schema '{schema}' in {reftype}ref does not exist".format(reftype=reftype, **data))
- schema_id = schema_obj.get('id')
-
- if data.get('template') is not None:
- template = data.get('template')
-
- refname = '%sName' % reftype
-
- return {
- refname: data.get('name'),
- 'schemaId': schema_id,
- 'templateName': template,
- }
-
- def make_subnets(self, data):
- ''' Create a subnets list from input '''
- if data is None:
- return None
-
- subnets = []
- for subnet in data:
- subnets.append(dict(
- ip=subnet.get('ip'),
- description=subnet.get('description', subnet.get('ip')),
- scope=subnet.get('scope', 'private'),
- shared=subnet.get('shared', False),
- noDefaultGateway=subnet.get('no_default_gateway', False),
- ))
-
- return subnets
-
- def sanitize(self, updates, collate=False, required=None, unwanted=None):
- ''' Clean up unset keys from a request payload '''
- if required is None:
- required = []
- if unwanted is None:
- unwanted = []
- self.proposed = deepcopy(self.existing)
- self.sent = deepcopy(self.existing)
-
- for key in self.existing:
- # Remove References
- if key.endswith('Ref'):
- del(self.proposed[key])
- del(self.sent[key])
- continue
-
- # Removed unwanted keys
- elif key in unwanted:
- del(self.proposed[key])
- del(self.sent[key])
- continue
-
- # Clean up self.sent
- for key in updates:
- # Always retain 'id'
- if key in required:
- pass
-
- # Remove unspecified values
- elif not collate and updates[key] is None:
- if key in self.existing:
- del(self.sent[key])
- continue
-
- # Remove identical values
- elif not collate and key in self.existing and updates[key] == self.existing[key]:
- del(self.sent[key])
- continue
-
- # Add everything else
- if updates[key] is not None:
- self.sent[key] = updates[key]
-
- # Update self.proposed
- self.proposed.update(self.sent)
-
- def exit_json(self, **kwargs):
- ''' Custom written method to exit from module. '''
-
- if self.params.get('state') in ('absent', 'present'):
- if self.params.get('output_level') in ('debug', 'info'):
- self.result['previous'] = self.previous
- # FIXME: Modified header only works for PATCH
- if not self.has_modified and self.previous != self.existing:
- self.result['changed'] = True
-
- # Return the gory details when we need it
- if self.params.get('output_level') == 'debug':
- self.result['method'] = self.method
- self.result['response'] = self.response
- self.result['status'] = self.status
- self.result['url'] = self.url
-
- if self.params.get('state') in ('absent', 'present'):
- self.result['sent'] = self.sent
- self.result['proposed'] = self.proposed
-
- self.result['current'] = self.existing
-
- if self.module._diff and self.result.get('changed') is True:
- self.result['diff'] = dict(
- before=self.previous,
- after=self.existing,
- )
-
- self.result.update(**kwargs)
- self.module.exit_json(**self.result)
-
- def fail_json(self, msg, **kwargs):
- ''' Custom written method to return info on failure. '''
-
- if self.params.get('state') in ('absent', 'present'):
- if self.params.get('output_level') in ('debug', 'info'):
- self.result['previous'] = self.previous
- # FIXME: Modified header only works for PATCH
- if not self.has_modified and self.previous != self.existing:
- self.result['changed'] = True
-
- # Return the gory details when we need it
- if self.params.get('output_level') == 'debug':
- if self.url is not None:
- self.result['method'] = self.method
- self.result['response'] = self.response
- self.result['status'] = self.status
- self.result['url'] = self.url
-
- if self.params.get('state') in ('absent', 'present'):
- self.result['sent'] = self.sent
- self.result['proposed'] = self.proposed
-
- self.result['current'] = self.existing
-
- self.result.update(**kwargs)
- self.module.fail_json(msg=msg, **self.result)
diff --git a/lib/ansible/modules/network/aci/mso_label.py b/lib/ansible/modules/network/aci/mso_label.py
deleted file mode 100644
index 590a5ae1c0..0000000000
--- a/lib/ansible/modules/network/aci/mso_label.py
+++ /dev/null
@@ -1,167 +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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_label
-short_description: Manage labels
-description:
-- Manage labels on Cisco ACI Multi-Site.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- label:
- description:
- - The name of the label.
- type: str
- required: yes
- aliases: [ name ]
- type:
- description:
- - The type of the label.
- type: str
- choices: [ site ]
- default: site
- 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: mso
-'''
-
-EXAMPLES = r'''
-- name: Add a new label
- mso_label:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- label: Belgium
- type: site
- state: present
- delegate_to: localhost
-
-- name: Remove a label
- mso_label:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- label: Belgium
- state: absent
- delegate_to: localhost
-
-- name: Query a label
- mso_label:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- label: Belgium
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all labels
- mso_label:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec, issubset
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- label=dict(type='str', aliases=['name']),
- type=dict(type='str', default='site', choices=['site']),
- state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_if=[
- ['state', 'absent', ['label']],
- ['state', 'present', ['label']],
- ],
- )
-
- label = module.params.get('label')
- label_type = module.params.get('type')
- state = module.params.get('state')
-
- mso = MSOModule(module)
-
- label_id = None
- path = 'labels'
-
- # Query for existing object(s)
- if label:
- mso.existing = mso.get_obj(path, displayName=label)
- if mso.existing:
- label_id = mso.existing.get('id')
- # If we found an existing object, continue with it
- path = 'labels/{id}'.format(id=label_id)
- else:
- mso.existing = mso.query_objs(path)
-
- if state == 'query':
- pass
-
- elif state == 'absent':
- mso.previous = mso.existing
- if mso.existing:
- if module.check_mode:
- mso.existing = {}
- else:
- mso.existing = mso.request(path, method='DELETE')
-
- elif state == 'present':
- mso.previous = mso.existing
-
- payload = dict(
- id=label_id,
- displayName=label,
- type=label_type,
- )
-
- mso.sanitize(payload, collate=True)
-
- if mso.existing:
- if not issubset(mso.sent, mso.existing):
- if module.check_mode:
- mso.existing = mso.proposed
- else:
- mso.existing = mso.request(path, method='PUT', data=mso.sent)
- else:
- if module.check_mode:
- mso.existing = mso.proposed
- else:
- mso.existing = mso.request(path, method='POST', data=mso.sent)
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_role.py b/lib/ansible/modules/network/aci/mso_role.py
deleted file mode 100644
index 215d5b54f5..0000000000
--- a/lib/ansible/modules/network/aci/mso_role.py
+++ /dev/null
@@ -1,224 +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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_role
-short_description: Manage roles
-description:
-- Manage roles on Cisco ACI Multi-Site.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- role:
- description:
- - The name of the role.
- type: str
- required: yes
- aliases: [ name ]
- display_name:
- description:
- - The name of the role to be displayed in the web UI.
- type: str
- description:
- description:
- - The description of the role.
- type: str
- permissions:
- description:
- - A list of permissions tied to this role.
- type: list
- choices:
- - backup-db
- - manage-audit-records
- - manage-labels
- - manage-roles
- - manage-schemas
- - manage-sites
- - manage-tenants
- - manage-tenant-schemas
- - manage-users
- - platform-logs
- - view-all-audit-records
- - view-labels
- - view-roles
- - view-schemas
- - view-sites
- - view-tenants
- - view-tenant-schemas
- - view-users
- 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: mso
-'''
-
-EXAMPLES = r'''
-- name: Add a new role
- mso_role:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- role: readOnly
- display_name: Read Only
- description: Read-only access for troubleshooting
- permissions:
- - view-roles
- - view-schemas
- - view-sites
- - view-tenants
- - view-tenant-schemas
- - view-users
- state: present
- delegate_to: localhost
-
-- name: Remove a role
- mso_role:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- role: readOnly
- state: absent
- delegate_to: localhost
-
-- name: Query a role
- mso_role:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- role: readOnly
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all roles
- mso_role:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec, issubset
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- role=dict(type='str', aliases=['name']),
- display_name=dict(type='str'),
- description=dict(type='str'),
- permissions=dict(type='list', choices=[
- 'backup-db',
- 'manage-audit-records',
- 'manage-labels',
- 'manage-roles',
- 'manage-schemas',
- 'manage-sites',
- 'manage-tenants',
- 'manage-tenant-schemas',
- 'manage-users',
- 'platform-logs',
- 'view-all-audit-records',
- 'view-labels',
- 'view-roles',
- 'view-schemas',
- 'view-sites',
- 'view-tenants',
- 'view-tenant-schemas',
- 'view-users',
- ]),
- state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_if=[
- ['state', 'absent', ['role']],
- ['state', 'present', ['role']],
- ],
- )
-
- role = module.params.get('role')
- description = module.params.get('description')
- permissions = module.params.get('permissions')
- state = module.params.get('state')
-
- mso = MSOModule(module)
-
- role_id = None
- path = 'roles'
-
- # Query for existing object(s)
- if role:
- mso.existing = mso.get_obj(path, name=role)
- if mso.existing:
- role_id = mso.existing.get('id')
- # If we found an existing object, continue with it
- path = 'roles/{id}'.format(id=role_id)
- else:
- mso.existing = mso.query_objs(path)
-
- if state == 'query':
- pass
-
- elif state == 'absent':
- mso.previous = mso.existing
- if mso.existing:
- if module.check_mode:
- mso.existing = {}
- else:
- mso.existing = mso.request(path, method='DELETE')
-
- elif state == 'present':
- mso.previous = mso.existing
-
- payload = dict(
- id=role_id,
- name=role,
- displayName=role,
- description=description,
- permissions=permissions,
- )
-
- mso.sanitize(payload, collate=True)
-
- if mso.existing:
- if not issubset(mso.sent, mso.existing):
- if module.check_mode:
- mso.existing = mso.proposed
- else:
- mso.existing = mso.request(path, method='PUT', data=mso.sent)
- else:
- if module.check_mode:
- mso.existing = mso.proposed
- else:
- mso.existing = mso.request(path, method='POST', data=mso.sent)
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_schema.py b/lib/ansible/modules/network/aci/mso_schema.py
deleted file mode 100644
index 263e20ec16..0000000000
--- a/lib/ansible/modules/network/aci/mso_schema.py
+++ /dev/null
@@ -1,192 +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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_schema
-short_description: Manage schemas
-description:
-- Manage schemas on Cisco ACI Multi-Site.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- schema:
- description:
- - The name of the schema.
- type: str
- required: yes
- aliases: [ name ]
- templates:
- description:
- - A list of templates for this schema.
- type: list
- sites:
- description:
- - A list of sites mapped to templates in this schema.
- type: list
- 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
-notes:
-- Due to restrictions of the MSO REST API this module cannot create empty schemas (i.e. schemas without templates).
- Use the M(mso_schema_template) to automatically create schemas with templates.
-seealso:
-- module: mso_schema_site
-- module: mso_schema_template
-extends_documentation_fragment: mso
-'''
-
-EXAMPLES = r'''
-- name: Add a new schema
- mso_schema:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- state: present
- templates:
- - name: Template1
- displayName: Template 1
- tenantId: north_europe
- anps:
- <...>
- - name: Template2
- displayName: Template 2
- tenantId: nort_europe
- anps:
- <...>
- delegate_to: localhost
-
-- name: Remove schemas
- mso_schema:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- state: absent
- delegate_to: localhost
-
-- name: Query a schema
- mso_schema:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all schemas
- mso_schema:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec, issubset
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- schema=dict(type='str', aliases=['name']),
- templates=dict(type='list'),
- sites=dict(type='list'),
- # messages=dict(type='dict'),
- # associations=dict(type='list'),
- # health_faults=dict(type='list'),
- # references=dict(type='dict'),
- # policy_states=dict(type='list'),
- state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_if=[
- ['state', 'absent', ['schema']],
- ['state', 'present', ['schema', 'templates']],
- ],
- )
-
- schema = module.params.get('schema')
- templates = module.params.get('templates')
- sites = module.params.get('sites')
- state = module.params.get('state')
-
- mso = MSOModule(module)
-
- schema_id = None
- path = 'schemas'
-
- # Query for existing object(s)
- if schema:
- mso.existing = mso.get_obj(path, displayName=schema)
- if mso.existing:
- schema_id = mso.existing.get('id')
- path = 'schemas/{id}'.format(id=schema_id)
- else:
- mso.existing = mso.query_objs(path)
-
- if state == 'query':
- pass
-
- elif state == 'absent':
- mso.previous = mso.existing
- if mso.existing:
- if module.check_mode:
- mso.existing = {}
- else:
- mso.existing = mso.request(path, method='DELETE')
-
- elif state == 'present':
- mso.previous = mso.existing
-
- payload = dict(
- id=schema_id,
- displayName=schema,
- templates=templates,
- sites=sites,
- )
-
- mso.sanitize(payload, collate=True)
-
- if mso.existing:
- if not issubset(mso.sent, mso.existing):
- if module.check_mode:
- mso.existing = mso.proposed
- else:
- mso.existing = mso.request(path, method='PUT', data=mso.sent)
- else:
- if module.check_mode:
- mso.existing = mso.proposed
- else:
- mso.existing = mso.request(path, method='POST', data=mso.sent)
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_schema_site.py b/lib/ansible/modules/network/aci/mso_schema_site.py
deleted file mode 100644
index 4371b43f12..0000000000
--- a/lib/ansible/modules/network/aci/mso_schema_site.py
+++ /dev/null
@@ -1,200 +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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_schema_site
-short_description: Manage sites in schemas
-description:
-- Manage sites on Cisco ACI Multi-Site.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- schema:
- description:
- - The name of the schema.
- type: str
- required: yes
- site:
- description:
- - The name of the site to manage.
- type: str
- required: yes
- template:
- description:
- - The name of the template.
- type: str
- required: yes
- 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
-seealso:
-- module: mso_schema_template
-- module: mso_site
-extends_documentation_fragment: mso
-'''
-
-EXAMPLES = r'''
-- name: Add a new site to a schema
- mso_schema_site:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- site: bdsol-pod51
- template: Template 1
- state: present
- delegate_to: localhost
-
-- name: Remove a site from a schema
- mso_schema_site:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- site: bdsol-pod51
- template: Template 1
- state: absent
- delegate_to: localhost
-
-- name: Query a schema site
- mso_schema_site:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- site: bdsol-pod51
- template: Template 1
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all schema sites
- mso_schema_site:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- site: bdsol-pod51
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- schema=dict(type='str', required=True),
- site=dict(type='str', aliases=['name']),
- template=dict(type='str'),
- state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_if=[
- ['state', 'absent', ['site', 'template']],
- ['state', 'present', ['site', 'template']],
- ],
- )
-
- schema = module.params.get('schema')
- site = module.params.get('site')
- template = module.params.get('template')
- state = module.params.get('state')
-
- mso = MSOModule(module)
-
- # Get schema
- schema_obj = mso.get_obj('schemas', displayName=schema)
- if not schema_obj:
- mso.fail_json(msg="Provided schema '{0}' does not exist".format(schema))
-
- # Schema exists
- schema_path = 'schemas/{id}'.format(**schema_obj)
-
- # Get site
- site_id = mso.lookup_site(site)
-
- mso.existing = {}
- if 'sites' in schema_obj:
- sites = [(s.get('siteId'), s.get('templateName')) for s in schema_obj.get('sites')]
- if template:
- if (site_id, template) in sites:
- site_idx = sites.index((site_id, template))
- mso.existing = schema_obj.get('sites')[site_idx]
- else:
- mso.existing = schema_obj.get('sites')
-
- if state == 'query':
- if not mso.existing:
- if template:
- mso.fail_json(msg="Template '{0}' not found".format(template))
- else:
- mso.existing = []
- mso.exit_json()
-
- sites_path = '/sites'
- site_path = '/sites/{0}'.format(site)
- ops = []
-
- mso.previous = mso.existing
- if state == 'absent':
- if mso.existing:
- # Remove existing site
- mso.sent = mso.existing = {}
- ops.append(dict(op='remove', path=site_path))
-
- elif state == 'present':
- if not mso.existing:
- # Add new site
- payload = dict(
- siteId=site_id,
- templateName=template,
- anps=[],
- bds=[],
- contracts=[],
- externalEpgs=[],
- intersiteL3outs=[],
- serviceGraphs=[],
- vrfs=[],
- )
-
- mso.sanitize(payload, collate=True)
-
- ops.append(dict(op='add', path=sites_path + '/-', value=mso.sent))
-
- mso.existing = mso.proposed
-
- if not module.check_mode:
- mso.request(schema_path, method='PATCH', data=ops)
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_schema_site_anp.py b/lib/ansible/modules/network/aci/mso_schema_site_anp.py
deleted file mode 100644
index 75d54c615d..0000000000
--- a/lib/ansible/modules/network/aci/mso_schema_site_anp.py
+++ /dev/null
@@ -1,213 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2019, 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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_schema_site_anp
-short_description: Manage site-local Application Network Profiles (ANPs) in schema template
-description:
-- Manage site-local ANPs in schema template on Cisco ACI Multi-Site.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- schema:
- description:
- - The name of the schema.
- type: str
- required: yes
- site:
- description:
- - The name of the site.
- type: str
- required: yes
- template:
- description:
- - The name of the template.
- type: str
- required: yes
- anp:
- description:
- - The name of the ANP to manage.
- 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
-seealso:
-- module: mso_schema_site
-- module: mso_schema_site_anp_epg
-- module: mso_schema_template_anp
-extends_documentation_fragment: mso
-'''
-
-EXAMPLES = r'''
-- name: Add a new site ANP
- mso_schema_site_anp:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- anp: ANP1
- state: present
- delegate_to: localhost
-
-- name: Remove a site ANP
- mso_schema_site_anp:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- anp: ANP1
- state: absent
- delegate_to: localhost
-
-- name: Query a specific site ANPs
- mso_schema_site_anp:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- anp: ANP1
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all site ANPs
- mso_schema_site_anp:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec, issubset
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- schema=dict(type='str', required=True),
- site=dict(type='str', required=True),
- template=dict(type='str', required=True),
- anp=dict(type='str', aliases=['name']), # This parameter is 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', ['anp']],
- ['state', 'present', ['anp']],
- ],
- )
-
- schema = module.params.get('schema')
- site = module.params.get('site')
- template = module.params.get('template')
- anp = module.params.get('anp')
- state = module.params.get('state')
-
- mso = MSOModule(module)
-
- # Get schema_id
- schema_obj = mso.get_obj('schemas', displayName=schema)
- if not schema_obj:
- mso.fail_json(msg="Provided schema '{0}' does not exist".format(schema))
-
- schema_path = 'schemas/{id}'.format(**schema_obj)
- schema_id = schema_obj.get('id')
-
- # Get site
- site_id = mso.lookup_site(site)
-
- # Get site_idx
- sites = [(s.get('siteId'), s.get('templateName')) for s in schema_obj.get('sites')]
- if (site_id, template) not in sites:
- mso.fail_json(msg="Provided site/template '{0}-{1}' does not exist. Existing sites/templates: {2}".format(site, template, ', '.join(sites)))
-
- # Schema-access uses indexes
- site_idx = sites.index((site_id, template))
- # Path-based access uses site_id-template
- site_template = '{0}-{1}'.format(site_id, template)
-
- # Get ANP
- anp_ref = mso.anp_ref(schema_id=schema_id, template=template, anp=anp)
- anps = [a.get('anpRef') for a in schema_obj.get('sites')[site_idx]['anps']]
-
- if anp is not None and anp_ref in anps:
- anp_idx = anps.index(anp_ref)
- anp_path = '/sites/{0}/anps/{1}'.format(site_template, anp)
- mso.existing = schema_obj.get('sites')[site_idx]['anps'][anp_idx]
-
- if state == 'query':
- if anp is None:
- mso.existing = schema_obj.get('sites')[site_idx]['anps']
- elif not mso.existing:
- mso.fail_json(msg="ANP '{anp}' not found".format(anp=anp))
- mso.exit_json()
-
- anps_path = '/sites/{0}/anps'.format(site_template)
- ops = []
-
- mso.previous = mso.existing
- if state == 'absent':
- if mso.existing:
- mso.sent = mso.existing = {}
- ops.append(dict(op='remove', path=anp_path))
-
- elif state == 'present':
-
- payload = dict(
- anpRef=dict(
- schemaId=schema_id,
- templateName=template,
- anpName=anp,
- ),
- )
-
- mso.sanitize(payload, collate=True)
-
- if not mso.existing:
- ops.append(dict(op='add', path=anps_path + '/-', value=mso.sent))
-
- mso.existing = mso.proposed
-
- if not module.check_mode:
- mso.request(schema_path, method='PATCH', data=ops)
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_schema_site_anp_epg.py b/lib/ansible/modules/network/aci/mso_schema_site_anp_epg.py
deleted file mode 100644
index 5128f833df..0000000000
--- a/lib/ansible/modules/network/aci/mso_schema_site_anp_epg.py
+++ /dev/null
@@ -1,228 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2019, 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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_schema_site_anp_epg
-short_description: Manage site-local Endpoint Groups (EPGs) in schema template
-description:
-- Manage site-local EPGs in schema template on Cisco ACI Multi-Site.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- schema:
- description:
- - The name of the schema.
- type: str
- required: yes
- site:
- description:
- - The name of the site.
- type: str
- required: yes
- template:
- description:
- - The name of the template.
- type: str
- required: yes
- anp:
- description:
- - The name of the ANP.
- type: str
- epg:
- description:
- - The name of the EPG to manage.
- 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
-seealso:
-- module: mso_schema_site_anp
-- module: mso_schema_site_anp_epg_subnet
-- module: mso_schema_template_anp_epg
-extends_documentation_fragment: mso
-'''
-
-EXAMPLES = r'''
-- name: Add a new site EPG
- mso_schema_site_anp_epg:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- anp: ANP1
- epg: EPG1
- state: present
- delegate_to: localhost
-
-- name: Remove a site EPG
- mso_schema_site_anp_epg:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- anp: ANP1
- epg: EPG1
- state: absent
- delegate_to: localhost
-
-- name: Query a specific site EPGs
- mso_schema_site_anp_epg:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- anp: ANP1
- epg: EPG1
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all site EPGs
- mso_schema_site_anp_epg:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- anp: ANP1
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec, issubset
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- schema=dict(type='str', required=True),
- site=dict(type='str', required=True),
- template=dict(type='str', required=True),
- anp=dict(type='str', required=True),
- epg=dict(type='str', aliases=['name']), # This parameter is 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', ['epg']],
- ['state', 'present', ['epg']],
- ],
- )
-
- schema = module.params.get('schema')
- site = module.params.get('site')
- template = module.params.get('template')
- anp = module.params.get('anp')
- epg = module.params.get('epg')
- state = module.params.get('state')
-
- mso = MSOModule(module)
-
- # Get schema_id
- schema_obj = mso.get_obj('schemas', displayName=schema)
- if not schema_obj:
- mso.fail_json(msg="Provided schema '{0}' does not exist".format(schema))
-
- schema_path = 'schemas/{id}'.format(**schema_obj)
- schema_id = schema_obj.get('id')
-
- # Get site
- site_id = mso.lookup_site(site)
- sites = [(s.get('siteId'), s.get('templateName')) for s in schema_obj.get('sites')]
- if (site_id, template) not in sites:
- mso.fail_json(msg="Provided site/template '{0}-{1}' does not exist. Existing sites/templates: {2}".format(site, template, ', '.join(sites)))
-
- # Schema-access uses indexes
- site_idx = sites.index((site_id, template))
- # Path-based access uses site_id-template
- site_template = '{0}-{1}'.format(site_id, template)
-
- # Get ANP
- anp_ref = mso.anp_ref(schema_id=schema_id, template=template, anp=anp)
- anps = [a.get('anpRef') for a in schema_obj.get('sites')[site_idx]['anps']]
- if anp_ref not in anps:
- mso.fail_json(msg="Provided anp '{0}' does not exist. Existing anps: {1}".format(anp, ', '.join(anps)))
- anp_idx = anps.index(anp_ref)
-
- # Get EPG
- epg_ref = mso.epg_ref(schema_id=schema_id, template=template, anp=anp, epg=epg)
- epgs = [e.get('epgRef') for e in schema_obj.get('sites')[site_idx]['anps'][anp_idx]['epgs']]
- if epg is not None and epg_ref in epgs:
- epg_idx = epgs.index(epg_ref)
- epg_path = '/sites/{0}/anps/{1}/epgs/{2}'.format(site_template, anp, epg)
- mso.existing = schema_obj.get('sites')[site_idx]['anps'][anp_idx]['epgs'][epg_idx]
-
- if state == 'query':
- if epg is None:
- mso.existing = schema_obj.get('sites')[site_idx]['anps'][anp_idx]['epgs']
- elif not mso.existing:
- mso.fail_json(msg="EPG '{epg}' not found".format(epg=epg))
- mso.exit_json()
-
- epgs_path = '/sites/{0}/anps/{1}/epgs'.format(site_template, anp)
- ops = []
-
- mso.previous = mso.existing
- if state == 'absent':
- if mso.existing:
- mso.sent = mso.existing = {}
- ops.append(dict(op='remove', path=epg_path))
-
- elif state == 'present':
-
- payload = dict(
- epgRef=dict(
- schemaId=schema_id,
- templateName=template,
- anpName=anp,
- epgName=epg,
- ),
- )
-
- mso.sanitize(payload, collate=True)
-
- if not mso.existing:
- ops.append(dict(op='add', path=epgs_path + '/-', value=mso.sent))
-
- mso.existing = mso.proposed
-
- if not module.check_mode:
- mso.request(schema_path, method='PATCH', data=ops)
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_schema_site_anp_epg_domain.py b/lib/ansible/modules/network/aci/mso_schema_site_anp_epg_domain.py
deleted file mode 100644
index fe6734fdaf..0000000000
--- a/lib/ansible/modules/network/aci/mso_schema_site_anp_epg_domain.py
+++ /dev/null
@@ -1,401 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2019, Nirav Katarmal (@nkatarmal-crest) <nirav.katarmal@crestdatasys.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: mso_schema_site_anp_epg_domain
-short_description: Manage site-local EPG domains in schema template
-description:
-- Manage site-local EPG domains in schema template on Cisco ACI Multi-Site.
-author:
-- Nirav Katarmal (@nkatarmal-crest)
-version_added: '2.9'
-options:
- schema:
- description:
- - The name of the schema.
- type: str
- required: yes
- site:
- description:
- - The name of the site.
- type: str
- required: yes
- template:
- description:
- - The name of the template.
- type: str
- required: yes
- anp:
- description:
- - The name of the ANP.
- type: str
- epg:
- description:
- - The name of the EPG.
- type: str
- domain_association_type:
- description:
- - The type of domain to associate.
- type: str
- choices: [ vmmDomain, l3ExtDomain, l2ExtDomain, physicalDomain, fibreChannel ]
- domain_profile:
- description:
- - The domain profile name.
- type: str
- deployment_immediacy:
- description:
- - The deployment immediacy of the domain.
- - C(immediate) means B(Deploy immediate).
- - C(lazy) means B(deploy on demand).
- type: str
- choices: [ immediate, lazy ]
- resolution_immediacy:
- description:
- - Determines when the policies should be resolved and available.
- - Defaults to C(lazy) when unset during creation.
- type: str
- choices: [ immediate, lazy, pre-provision ]
- micro_seg_vlan_type:
- description:
- - Virtual LAN type for microsegmentation. This attribute can only be used with vmmDomain domain association.
- type: str
- micro_seg_vlan:
- description:
- - Virtual LAN for microsegmentation. This attribute can only be used with vmmDomain domain association.
- type: int
- port_encap_vlan_type:
- description:
- - Virtual LAN type for port encap. This attribute can only be used with vmmDomain domain association.
- type: str
- port_encap_vlan:
- description:
- - Virtual LAN type for port encap. This attribute can only be used with vmmDomain domain association.
- type: int
- vlan_encap_mode:
- description:
- - Which VLAN enacap mode to use. This attribute can only be used with vmmDomain domain association.
- type: str
- choices: [ static, dynamic ]
- allow_micro_segmentation:
- description:
- - Specifies microsegmentation is enabled or not. This attribute can only be used with vmmDomain domain association.
- type: bool
- switch_type:
- description:
- - Which switch type to use with this domain association. This attribute can only be used with vmmDomain domain association.
- type: str
- switching_mode:
- description:
- - Which switching mode to use with this domain association. This attribute can only be used with vmmDomain domain association.
- type: str
- enhanced_lagpolicy_name:
- description:
- - EPG enhanced lagpolicy name. This attribute can only be used with vmmDomain domain association.
- type: str
- enhanced_lagpolicy_dn:
- description:
- - Distinguished name of EPG lagpolicy. This attribute can only be used with vmmDomain domain association.
- 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
-notes:
-- The ACI MultiSite PATCH API has a deficiency requiring some objects to be referenced by index.
- This can cause silent corruption on concurrent access when changing/removing on object as
- the wrong object may be referenced. This module is affected by this deficiency.
-seealso:
-- module: mso_schema_site_anp_epg
-- module: mso_schema_template_anp_epg
-extends_documentation_fragment: mso
-'''
-
-EXAMPLES = r'''
-- name: Add a new static leaf to a site EPG
- mso_schema_site_anp_epg_domain:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- anp: ANP1
- epg: EPG1
- domain_association_type: vmmDomain
- domain_profile: 'VMware-VMM'
- deployment_immediacy: lazy
- resolution_immediacy: pre-provision
- state: present
- delegate_to: localhost
-
-- name: Remove a static leaf from a site EPG
- mso_schema_site_anp_epg_domain:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- anp: ANP1
- epg: EPG1
- domain_association_type: vmmDomain
- domain_profile: 'VMware-VMM'
- deployment_immediacy: lazy
- resolution_immediacy: pre-provision
- state: absent
- delegate_to: localhost
-
-- name: Query a specific site EPG static leaf
- mso_schema_site_anp_epg_domain:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- anp: ANP1
- epg: EPG1
- domain_association_type: vmmDomain
- domain_profile: 'VMware-VMM'
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all site EPG static leafs
- mso_schema_site_anp_epg_domain:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- anp: ANP1
- epg: EPG1
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- schema=dict(type='str', required=True),
- site=dict(type='str', required=True),
- template=dict(type='str', required=True),
- anp=dict(type='str', required=True),
- epg=dict(type='str', required=True),
- domain_association_type=dict(type='str', choices=['vmmDomain', 'l3ExtDomain', 'l2ExtDomain', 'physicalDomain', 'fibreChannel']),
- domain_profile=dict(type='str'),
- deployment_immediacy=dict(type='str', choices=['immediate', 'lazy']),
- resolution_immediacy=dict(type='str', choices=['immediate', 'lazy', 'pre-provision']),
- state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
- micro_seg_vlan_type=dict(type='str'),
- micro_seg_vlan=dict(type='int'),
- port_encap_vlan_type=dict(type='str'),
- port_encap_vlan=dict(type='int'),
- vlan_encap_mode=dict(type='str', choices=['static', 'dynamic']),
- allow_micro_segmentation=dict(type='bool'),
- switch_type=dict(type='str'),
- switching_mode=dict(type='str'),
- enhanced_lagpolicy_name=dict(type='str'),
- enhanced_lagpolicy_dn=dict(type='str'),
-
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_if=[
- ['state', 'absent', ['domain_association_type', 'domain_profile', 'deployment_immediacy', 'resolution_immediacy']],
- ['state', 'present', ['domain_association_type', 'domain_profile', 'deployment_immediacy', 'resolution_immediacy']],
- ],
- )
-
- schema = module.params.get('schema')
- site = module.params.get('site')
- template = module.params.get('template')
- anp = module.params.get('anp')
- epg = module.params.get('epg')
- domain_association_type = module.params.get('domain_association_type')
- domain_profile = module.params.get('domain_profile')
- deployment_immediacy = module.params.get('deployment_immediacy')
- resolution_immediacy = module.params.get('resolution_immediacy')
- state = module.params.get('state')
- micro_seg_vlan_type = module.params.get('micro_seg_vlan_type')
- micro_seg_vlan = module.params.get('micro_seg_vlan')
- port_encap_vlan_type = module.params.get('port_encap_vlan_type')
- port_encap_vlan = module.params.get('port_encap_vlan')
- vlan_encap_mode = module.params.get('vlan_encap_mode')
- allow_micro_segmentation = module.params.get('allow_micro_segmentation')
- switch_type = module.params.get('switch_type')
- switching_mode = module.params.get('switching_mode')
- enhanced_lagpolicy_name = module.params.get('enhanced_lagpolicy_name')
- enhanced_lagpolicy_dn = module.params.get('enhanced_lagpolicy_dn')
-
- mso = MSOModule(module)
-
- # Get schema_id
- schema_obj = mso.get_obj('schemas', displayName=schema)
- if not schema_obj:
- mso.fail_json(msg="Provided schema '{0}' does not exist".format(schema))
-
- schema_path = 'schemas/{id}'.format(**schema_obj)
- schema_id = schema_obj.get('id')
-
- # Get site
- site_id = mso.lookup_site(site)
-
- # Get site_idx
- sites = [(s.get('siteId'), s.get('templateName')) for s in schema_obj.get('sites')]
- if (site_id, template) not in sites:
- mso.fail_json(msg="Provided site/template '{0}-{1}' does not exist. Existing sites/templates: {2}".format(site, template, ', '.join(sites)))
-
- # Schema-access uses indexes
- site_idx = sites.index((site_id, template))
- # Path-based access uses site_id-template
- site_template = '{0}-{1}'.format(site_id, template)
-
- # Get ANP
- anp_ref = mso.anp_ref(schema_id=schema_id, template=template, anp=anp)
- anps = [a.get('anpRef') for a in schema_obj.get('sites')[site_idx]['anps']]
- if anp_ref not in anps:
- mso.fail_json(msg="Provided anp '{0}' does not exist. Existing anps: {1}".format(anp, ', '.join(anps)))
- anp_idx = anps.index(anp_ref)
-
- # Get EPG
- epg_ref = mso.epg_ref(schema_id=schema_id, template=template, anp=anp, epg=epg)
- print(epg_ref)
- epgs = [e.get('epgRef') for e in schema_obj.get('sites')[site_idx]['anps'][anp_idx]['epgs']]
- if epg_ref not in epgs:
- mso.fail_json(msg="Provided epg '{0}' does not exist. Existing epgs: {1} epgref {2}".format(epg, str(schema_obj.get('sites')[site_idx]), epg_ref))
- epg_idx = epgs.index(epg_ref)
-
- if domain_association_type == 'vmmDomain':
- domain_dn = 'uni/vmmp-VMware/dom-{0}'.format(domain_profile)
- elif domain_association_type == 'l3ExtDomain':
- domain_dn = 'uni/l3dom-{0}'.format(domain_profile)
- elif domain_association_type == 'l2ExtDomain':
- domain_dn = 'uni/l2dom-{0}'.format(domain_profile)
- elif domain_association_type == 'physicalDomain':
- domain_dn = 'uni/phys-{0}'.format(domain_profile)
- elif domain_association_type == 'fibreChannel':
- domain_dn = 'uni/fc-{0}'.format(domain_profile)
- else:
- domain_dn = ''
-
- # Get Domains
- domains = [dom.get('dn') for dom in schema_obj.get('sites')[site_idx]['anps'][anp_idx]['epgs'][epg_idx]['domainAssociations']]
- if domain_dn in domains:
- domain_idx = domains.index(domain_dn)
- domain_path = '/sites/{0}/anps/{1}/epgs/{2}/domainAssociations/{3}'.format(site_template, anp, epg, domain_idx)
- mso.existing = schema_obj.get('sites')[site_idx]['anps'][anp_idx]['epgs'][epg_idx]['domainAssociations'][domain_idx]
-
- if state == 'query':
- if domain_association_type is None or domain_profile is None:
- mso.existing = schema_obj.get('sites')[site_idx]['anps'][anp_idx]['epgs'][epg_idx]['domainAssociations']
- elif not mso.existing:
- mso.fail_json(msg="Domain association '{domain_association_type}/{domain_profile}' not found".format(
- domain_association_type=domain_association_type,
- domain_profile=domain_profile))
- mso.exit_json()
-
- domains_path = '/sites/{0}/anps/{1}/epgs/{2}/domainAssociations'.format(site_template, anp, epg)
- ops = []
- if domain_association_type == 'vmmDomain':
- vmmDomainProperties = {}
- if micro_seg_vlan_type and micro_seg_vlan:
- microSegVlan = dict(vlanType=micro_seg_vlan_type, vlan=micro_seg_vlan)
- vmmDomainProperties['microSegVlan'] = microSegVlan
- elif not micro_seg_vlan_type and micro_seg_vlan:
- mso.fail_json(msg="micro_seg_vlan_type is required when micro_seg_vlan is provided.")
- elif micro_seg_vlan_type and not micro_seg_vlan:
- mso.fail_json(msg="micro_seg_vlan is required when micro_seg_vlan_type is provided.")
-
- if micro_seg_vlan_type and micro_seg_vlan:
- portEncapVlan = dict(vlanType=port_encap_vlan_type, vlan=port_encap_vlan)
- vmmDomainProperties['portEncapVlan'] = portEncapVlan
- elif not port_encap_vlan_type and port_encap_vlan:
- mso.fail_json(msg="port_encap_vlan_type is required when port_encap_vlan is provided.")
- elif port_encap_vlan_type and not port_encap_vlan:
- mso.fail_json(msg="port_encap_vlan is required when port_encap_vlan_type is provided.")
-
- if vlan_encap_mode:
- vmmDomainProperties['vlanEncapMode'] = vlan_encap_mode
-
- if allow_micro_segmentation:
- vmmDomainProperties['allowMicroSegmentation'] = allow_micro_segmentation
- if switch_type:
- vmmDomainProperties['switchType'] = switch_type
- if switching_mode:
- vmmDomainProperties['switchingMode'] = switching_mode
-
- if enhanced_lagpolicy_name and enhanced_lagpolicy_dn:
- enhancedLagPol = dict(name=enhanced_lagpolicy_name, dn=enhanced_lagpolicy_dn)
- epgLagPol = dict(enhancedLagPol=enhancedLagPol)
- vmmDomainProperties['epgLagPol'] = epgLagPol
- elif not enhanced_lagpolicy_name and enhanced_lagpolicy_dn:
- mso.fail_json(msg="enhanced_lagpolicy_name is required when enhanced_lagpolicy_dn is provided.")
- elif enhanced_lagpolicy_name and not enhanced_lagpolicy_dn:
- mso.fail_json(msg="enhanced_lagpolicy_dn is required when enhanced_lagpolicy_name is provided.")
-
- payload = dict(
- dn=domain_dn,
- domainType=domain_association_type,
- deploymentImmediacy=deployment_immediacy,
- resolutionImmediacy=resolution_immediacy,
- )
-
- if vmmDomainProperties:
- payload['vmmDomainProperties'] = vmmDomainProperties
- else:
- payload = dict(
- dn=domain_dn,
- domainType=domain_association_type,
- deploymentImmediacy=deployment_immediacy,
- resolutionImmediacy=resolution_immediacy,
- )
-
- mso.previous = mso.existing
- if state == 'absent':
- if mso.existing:
- mso.sent = mso.existing = {}
- ops.append(dict(op='remove', path=domains_path))
- elif state == 'present':
- mso.sanitize(payload, collate=True)
-
- if mso.existing:
- ops.append(dict(op='replace', path=domain_path, value=mso.sent))
- else:
- ops.append(dict(op='add', path=domains_path + '/-', value=mso.sent))
-
- mso.existing = mso.proposed
-
- if not module.check_mode:
- mso.request(schema_path, method='PATCH', data=ops)
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_schema_site_anp_epg_staticleaf.py b/lib/ansible/modules/network/aci/mso_schema_site_anp_epg_staticleaf.py
deleted file mode 100644
index 4c296d7502..0000000000
--- a/lib/ansible/modules/network/aci/mso_schema_site_anp_epg_staticleaf.py
+++ /dev/null
@@ -1,261 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2019, 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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_schema_site_anp_epg_staticleaf
-short_description: Manage site-local EPG static leafs in schema template
-description:
-- Manage site-local EPG static leafs in schema template on Cisco ACI Multi-Site.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- schema:
- description:
- - The name of the schema.
- type: str
- required: yes
- site:
- description:
- - The name of the site.
- type: str
- required: yes
- template:
- description:
- - The name of the template.
- type: str
- required: yes
- anp:
- description:
- - The name of the ANP.
- type: str
- epg:
- description:
- - The name of the EPG.
- type: str
- pod:
- description:
- - The pod of the static leaf.
- type: str
- leaf:
- description:
- - The path of the static leaf.
- type: str
- aliases: [ name ]
- vlan:
- description:
- - The VLAN id of the static leaf.
- 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
-notes:
-- The ACI MultiSite PATCH API has a deficiency requiring some objects to be referenced by index.
- This can cause silent corruption on concurrent access when changing/removing on object as
- the wrong object may be referenced. This module is affected by this deficiency.
-seealso:
-- module: mso_schema_site_anp_epg
-- module: mso_schema_template_anp_epg
-extends_documentation_fragment: mso
-'''
-
-EXAMPLES = r'''
-- name: Add a new static leaf to a site EPG
- mso_schema_site_anp_epg_staticleaf:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- anp: ANP1
- epg: EPG1
- leaf: Leaf1
- vlan: 123
- state: present
- delegate_to: localhost
-
-- name: Remove a static leaf from a site EPG
- mso_schema_site_anp_epg_staticleaf:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- anp: ANP1
- epg: EPG1
- leaf: Leaf1
- state: absent
- delegate_to: localhost
-
-- name: Query a specific site EPG static leaf
- mso_schema_site_anp_epg_staticleaf:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- anp: ANP1
- epg: EPG1
- leaf: Leaf1
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all site EPG static leafs
- mso_schema_site_anp_epg_staticleaf:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- anp: ANP1
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- schema=dict(type='str', required=True),
- site=dict(type='str', required=True),
- template=dict(type='str', required=True),
- anp=dict(type='str', required=True),
- epg=dict(type='str', required=True),
- pod=dict(type='str'), # This parameter is not required for querying all objects
- leaf=dict(type='str', aliases=['name']),
- vlan=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=[
- ['state', 'absent', ['pod', 'leaf', 'vlan']],
- ['state', 'present', ['pod', 'leaf', 'vlan']],
- ],
- )
-
- schema = module.params.get('schema')
- site = module.params.get('site')
- template = module.params.get('template')
- anp = module.params.get('anp')
- epg = module.params.get('epg')
- pod = module.params.get('pod')
- leaf = module.params.get('leaf')
- vlan = module.params.get('vlan')
- state = module.params.get('state')
-
- leafpath = 'topology/{0}/node-{1}'.format(pod, leaf)
-
- mso = MSOModule(module)
-
- # Get schema_id
- schema_obj = mso.get_obj('schemas', displayName=schema)
- if not schema_obj:
- mso.fail_json(msg="Provided schema '{0}' does not exist".format(schema))
-
- schema_path = 'schemas/{id}'.format(**schema_obj)
- schema_id = schema_obj.get('id')
-
- # Get site
- site_id = mso.lookup_site(site)
-
- # Get site_idx
- sites = [(s.get('siteId'), s.get('templateName')) for s in schema_obj.get('sites')]
- if (site_id, template) not in sites:
- mso.fail_json(msg="Provided site/template '{0}-{1}' does not exist. Existing sites/templates: {2}".format(site, template, ', '.join(sites)))
-
- # Schema-access uses indexes
- site_idx = sites.index((site_id, template))
- # Path-based access uses site_id-template
- site_template = '{0}-{1}'.format(site_id, template)
-
- # Get ANP
- anp_ref = mso.anp_ref(schema_id=schema_id, template=template, anp=anp)
- anps = [a.get('anpRef') for a in schema_obj.get('sites')[site_idx]['anps']]
- if anp_ref not in anps:
- mso.fail_json(msg="Provided anp '{0}' does not exist. Existing anps: {1}".format(anp, ', '.join(anps)))
- anp_idx = anps.index(anp_ref)
-
- # Get EPG
- epg_ref = mso.epg_ref(schema_id=schema_id, template=template, anp=anp, epg=epg)
- epgs = [e.get('epgRef') for e in schema_obj.get('sites')[site_idx]['anps'][anp_idx]['epgs']]
- if epg_ref not in epgs:
- mso.fail_json(msg="Provided epg '{0}' does not exist. Existing epgs: {1}".format(epg, ', '.join(epgs)))
- epg_idx = epgs.index(epg_ref)
-
- # Get Leaf
- leafs = [(l.get('path'), l.get('portEncapVlan')) for l in schema_obj.get('sites')[site_idx]['anps'][anp_idx]['epgs'][epg_idx]['staticLeafs']]
- if (leafpath, vlan) in leafs:
- leaf_idx = leafs.index((leafpath, vlan))
- # FIXME: Changes based on index are DANGEROUS
- leaf_path = '/sites/{0}/anps/{1}/epgs/{2}/staticLeafs/{3}'.format(site_template, anp, epg, leaf_idx)
- mso.existing = schema_obj.get('sites')[site_idx]['anps'][anp_idx]['epgs'][epg_idx]['staticLeafs'][leaf_idx]
-
- if state == 'query':
- if leaf is None or vlan is None:
- mso.existing = schema_obj.get('sites')[site_idx]['anps'][anp_idx]['epgs'][epg_idx]['staticLeafs']
- elif not mso.existing:
- mso.fail_json(msg="Static leaf '{leaf}/{vlan}' not found".format(leaf=leaf, vlan=vlan))
- mso.exit_json()
-
- leafs_path = '/sites/{0}/anps/{1}/epgs/{2}/staticLeafs'.format(site_template, anp, epg)
- ops = []
-
- mso.previous = mso.existing
- if state == 'absent':
- if mso.existing:
- mso.sent = mso.existing = {}
- ops.append(dict(op='remove', path=leaf_path))
-
- elif state == 'present':
- payload = dict(
- path=leafpath,
- portEncapVlan=vlan,
- )
-
- mso.sanitize(payload, collate=True)
-
- if mso.existing:
- ops.append(dict(op='replace', path=leaf_path, value=mso.sent))
- else:
- ops.append(dict(op='add', path=leafs_path + '/-', value=mso.sent))
-
- mso.existing = mso.proposed
-
- if not module.check_mode:
- mso.request(schema_path, method='PATCH', data=ops)
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_schema_site_anp_epg_staticport.py b/lib/ansible/modules/network/aci/mso_schema_site_anp_epg_staticport.py
deleted file mode 100644
index c2db268ba1..0000000000
--- a/lib/ansible/modules/network/aci/mso_schema_site_anp_epg_staticport.py
+++ /dev/null
@@ -1,315 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2019, 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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_schema_site_anp_epg_staticport
-short_description: Manage site-local EPG static ports in schema template
-description:
-- Manage site-local EPG static ports in schema template on Cisco ACI Multi-Site.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- schema:
- description:
- - The name of the schema.
- type: str
- required: yes
- site:
- description:
- - The name of the site.
- type: str
- required: yes
- template:
- description:
- - The name of the template.
- type: str
- required: yes
- anp:
- description:
- - The name of the ANP.
- type: str
- epg:
- description:
- - The name of the EPG.
- type: str
- type:
- description:
- - The path type of the static port
- type: str
- choices: [ port, vpc ]
- default: port
- pod:
- description:
- - The pod of the static port.
- type: str
- leaf:
- description:
- - The leaf of the static port.
- type: str
- path:
- description:
- - The path of the static port.
- type: str
- vlan:
- description:
- - The port encap VLAN id of the static port.
- type: int
- deployment_immediacy:
- description:
- - The deployment immediacy of the static port.
- - C(immediate) means B(Deploy immediate).
- - C(lazy) means B(deploy on demand).
- type: str
- choices: [ immediate, lazy ]
- mode:
- description:
- - The mode of the static port.
- - C(native) means B(Access (802.1p)).
- - C(regular) means B(Trunk).
- - C(untagged) means B(Access (untagged)).
- type: str
- choices: [ native, regular, untagged ]
- 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
-notes:
-- The ACI MultiSite PATCH API has a deficiency requiring some objects to be referenced by index.
- This can cause silent corruption on concurrent access when changing/removing an object as
- the wrong object may be referenced. This module is affected by this deficiency.
-seealso:
-- module: mso_schema_site_anp_epg
-- module: mso_schema_template_anp_epg
-extends_documentation_fragment: mso
-'''
-
-EXAMPLES = r'''
-- name: Add a new static port to a site EPG
- mso_schema_site_anp_epg_staticport:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- anp: ANP1
- epg: EPG1
- type: port
- pod: pod-1
- leaf: 101
- path: eth1/1
- vlan: 126
- deployment_immediacy: immediate
- state: present
- delegate_to: localhost
-
-- name: Remove a static port from a site EPG
- mso_schema_site_anp_epg_staticport:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- anp: ANP1
- epg: EPG1
- type: port
- pod: pod-1
- leaf: 101
- path: eth1/1
- state: absent
- delegate_to: localhost
-
-- name: Query a specific site EPG static port
- mso_schema_site_anp_epg_staticport:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- anp: ANP1
- epg: EPG1
- type: port
- pod: pod-1
- leaf: 101
- path: eth1/1
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all site EPG static ports
- mso_schema_site_anp_epg_staticport:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- anp: ANP1
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- schema=dict(type='str', required=True),
- site=dict(type='str', required=True),
- template=dict(type='str', required=True),
- anp=dict(type='str', required=True),
- epg=dict(type='str', required=True),
- type=dict(type='str', default='port', choices=['port', 'vpc']),
- pod=dict(type='str'), # This parameter is not required for querying all objects
- leaf=dict(type='str'), # This parameter is not required for querying all objects
- path=dict(type='str'), # This parameter is not required for querying all objects
- vlan=dict(type='int'), # This parameter is not required for querying all objects
- deployment_immediacy=dict(type='str', choices=['immediate', 'lazy']),
- mode=dict(type='str', choices=['native', 'regular', 'untagged']),
- state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_if=[
- ['state', 'absent', ['type', 'pod', 'leaf', 'path', 'vlan']],
- ['state', 'present', ['type', 'pod', 'leaf', 'path', 'vlan']],
- ],
- )
-
- schema = module.params.get('schema')
- site = module.params.get('site')
- template = module.params.get('template')
- anp = module.params.get('anp')
- epg = module.params.get('epg')
- path_type = module.params.get('type')
- pod = module.params.get('pod')
- leaf = module.params.get('leaf')
- path = module.params.get('path')
- vlan = module.params.get('vlan')
- deployment_immediacy = module.params.get('deployment_immediacy')
- mode = module.params.get('mode')
- state = module.params.get('state')
-
- if path_type == 'port':
- portpath = 'topology/{0}/paths-{1}/pathep-[{2}]'.format(pod, leaf, path)
- elif path_type == 'vpc':
- portpath = 'topology/{0}/protpaths-{1}/pathep-[{2}]'.format(pod, leaf, path)
-
- mso = MSOModule(module)
-
- # Get schema_id
- schema_obj = mso.get_obj('schemas', displayName=schema)
- if not schema_obj:
- mso.fail_json(msg="Provided schema '{0}' does not exist".format(schema))
-
- schema_path = 'schemas/{id}'.format(**schema_obj)
- schema_id = schema_obj.get('id')
-
- # Get site
- site_id = mso.lookup_site(site)
-
- # Get site_idx
- sites = [(s.get('siteId'), s.get('templateName')) for s in schema_obj.get('sites')]
- if (site_id, template) not in sites:
- mso.fail_json(msg="Provided site/template '{0}-{1}' does not exist. Existing sites/templates: {2}".format(site, template, ', '.join(sites)))
-
- # Schema-access uses indexes
- site_idx = sites.index((site_id, template))
- # Path-based access uses site_id-template
- site_template = '{0}-{1}'.format(site_id, template)
-
- # Get ANP
- anp_ref = mso.anp_ref(schema_id=schema_id, template=template, anp=anp)
- anps = [a.get('anpRef') for a in schema_obj.get('sites')[site_idx]['anps']]
- if anp_ref not in anps:
- mso.fail_json(msg="Provided anp '{0}' does not exist. Existing anps: {1}".format(anp, ', '.join(anps)))
- anp_idx = anps.index(anp_ref)
-
- # Get EPG
- epg_ref = mso.epg_ref(schema_id=schema_id, template=template, anp=anp, epg=epg)
- epgs = [e.get('epgRef') for e in schema_obj.get('sites')[site_idx]['anps'][anp_idx]['epgs']]
- if epg_ref not in epgs:
- mso.fail_json(msg="Provided epg '{0}' does not exist. Existing epgs: {1}".format(epg, ', '.join(epgs)))
- epg_idx = epgs.index(epg_ref)
-
- # Get Leaf
- portpaths = [p.get('path') for p in schema_obj.get('sites')[site_idx]['anps'][anp_idx]['epgs'][epg_idx]['staticPorts']]
- if portpath in portpaths:
- portpath_idx = portpaths.index(portpath)
- # FIXME: Changes based on index are DANGEROUS
- port_path = '/sites/{0}/anps/{1}/epgs/{2}/staticPorts/{3}'.format(site_template, anp, epg, portpath_idx)
- mso.existing = schema_obj.get('sites')[site_idx]['anps'][anp_idx]['epgs'][epg_idx]['staticPorts'][portpath_idx]
-
- if state == 'query':
- if leaf is None or vlan is None:
- mso.existing = schema_obj.get('sites')[site_idx]['anps'][anp_idx]['epgs'][epg_idx]['staticPorts']
- elif not mso.existing:
- mso.fail_json(msg="Static port '{portpath}' not found".format(portpath=portpath))
- mso.exit_json()
-
- ports_path = '/sites/{0}/anps/{1}/epgs/{2}/staticPorts'.format(site_template, anp, epg)
- ops = []
-
- mso.previous = mso.existing
- if state == 'absent':
- if mso.existing:
- mso.sent = mso.existing = {}
- ops.append(dict(op='remove', path=port_path))
-
- elif state == 'present':
- if not mso.existing:
- if deployment_immediacy is None:
- deployment_immediacy = 'lazy'
- if mode is None:
- mode = 'untagged'
-
- payload = dict(
- deploymentImmediacy=deployment_immediacy,
- mode=mode,
- path=portpath,
- portEncapVlan=vlan,
- type=path_type,
- )
-
- mso.sanitize(payload, collate=True)
-
- if mso.existing:
- ops.append(dict(op='replace', path=port_path, value=mso.sent))
- else:
- ops.append(dict(op='add', path=ports_path + '/-', value=mso.sent))
-
- mso.existing = mso.proposed
-
- if not module.check_mode:
- mso.request(schema_path, method='PATCH', data=ops)
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_schema_site_anp_epg_subnet.py b/lib/ansible/modules/network/aci/mso_schema_site_anp_epg_subnet.py
deleted file mode 100644
index 92d168ce1d..0000000000
--- a/lib/ansible/modules/network/aci/mso_schema_site_anp_epg_subnet.py
+++ /dev/null
@@ -1,281 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2019, 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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_schema_site_anp_epg_subnet
-short_description: Manage site-local EPG subnets in schema template
-description:
-- Manage site-local EPG subnets in schema template on Cisco ACI Multi-Site.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- schema:
- description:
- - The name of the schema.
- type: str
- required: yes
- site:
- description:
- - The name of the site.
- type: str
- required: yes
- template:
- description:
- - The name of the template.
- type: str
- required: yes
- anp:
- description:
- - The name of the ANP.
- type: str
- epg:
- description:
- - The name of the EPG.
- type: str
- subnet:
- description:
- - The IP range in CIDR notation.
- type: str
- required: true
- aliases: [ ip ]
- description:
- description:
- - The description of this subnet.
- type: str
- scope:
- description:
- - The scope of the subnet.
- type: str
- choices: [ private, public ]
- shared:
- description:
- - Whether this subnet is shared between VRFs.
- type: bool
- no_default_gateway:
- description:
- - Whether this subnet has a default gateway.
- 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
-notes:
-- The ACI MultiSite PATCH API has a deficiency requiring some objects to be referenced by index.
- This can cause silent corruption on concurrent access when changing/removing on object as
- the wrong object may be referenced. This module is affected by this deficiency.
-seealso:
-- module: mso_schema_site_anp_epg
-- module: mso_schema_template_anp_epg_subnet
-extends_documentation_fragment: mso
-'''
-
-EXAMPLES = r'''
-- name: Add a new subnet to a site EPG
- mso_schema_site_anp_epg_subnet:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- anp: ANP1
- epg: EPG1
- subnet: 10.0.0.0/24
- state: present
- delegate_to: localhost
-
-- name: Remove a subnet from a site EPG
- mso_schema_site_anp_epg_subnet:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- anp: ANP1
- epg: EPG1
- subnet: 10.0.0.0/24
- state: absent
- delegate_to: localhost
-
-- name: Query a specific site EPG subnet
- mso_schema_site_anp_epg_subnet:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- anp: ANP1
- epg: EPG1
- subnet: 10.0.0.0/24
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all site EPG subnets
- mso_schema_site_anp_epg_subnet:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- anp: ANP1
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec, mso_subnet_spec, issubset
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- schema=dict(type='str', required=True),
- site=dict(type='str', required=True),
- template=dict(type='str', required=True),
- anp=dict(type='str', required=True),
- epg=dict(type='str', required=True),
- state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
- )
- argument_spec.update(mso_subnet_spec())
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_if=[
- ['state', 'absent', ['subnet']],
- ['state', 'present', ['subnet']],
- ],
- )
-
- schema = module.params.get('schema')
- site = module.params.get('site')
- template = module.params.get('template')
- anp = module.params.get('anp')
- epg = module.params.get('epg')
- subnet = module.params.get('subnet')
- description = module.params.get('description')
- scope = module.params.get('scope')
- shared = module.params.get('shared')
- no_default_gateway = module.params.get('no_default_gateway')
- state = module.params.get('state')
-
- mso = MSOModule(module)
-
- # Get schema_id
- schema_obj = mso.get_obj('schemas', displayName=schema)
- if not schema_obj:
- mso.fail_json(msg="Provided schema '{0}' does not exist".format(schema))
-
- schema_path = 'schemas/{id}'.format(**schema_obj)
- schema_id = schema_obj.get('id')
-
- # Get site
- site_id = mso.lookup_site(site)
-
- # Get site_idx
- sites = [(s.get('siteId'), s.get('templateName')) for s in schema_obj.get('sites')]
- if (site_id, template) not in sites:
- mso.fail_json(msg="Provided site/template '{0}-{1}' does not exist. Existing sites/templates: {2}".format(site, template, ', '.join(sites)))
-
- # Schema-access uses indexes
- site_idx = sites.index((site_id, template))
- # Path-based access uses site_id-template
- site_template = '{0}-{1}'.format(site_id, template)
-
- # Get ANP
- anp_ref = mso.anp_ref(schema_id=schema_id, template=template, anp=anp)
- anps = [a.get('anpRef') for a in schema_obj.get('sites')[site_idx]['anps']]
- if anp_ref not in anps:
- mso.fail_json(msg="Provided anp '{0}' does not exist. Existing anps: {1}".format(anp, ', '.join(anps)))
- anp_idx = anps.index(anp_ref)
-
- # Get EPG
- epg_ref = mso.epg_ref(schema_id=schema_id, template=template, anp=anp, epg=epg)
- epgs = [e.get('epgRef') for e in schema_obj.get('sites')[site_idx]['anps'][anp_idx]['epgs']]
- if epg_ref not in epgs:
- mso.fail_json(msg="Provided epg '{0}' does not exist. Existing epgs: {1}".format(epg, ', '.join(epgs)))
- epg_idx = epgs.index(epg_ref)
-
- # Get Subnet
- subnets = [s.get('ip') for s in schema_obj.get('sites')[site_idx]['anps'][anp_idx]['epgs'][epg_idx]['subnets']]
- if subnet in subnets:
- subnet_idx = subnets.index(subnet)
- # FIXME: Changes based on index are DANGEROUS
- subnet_path = '/sites/{0}/anps/{1}/epgs/{2}/subnets/{3}'.format(site_template, anp, epg, subnet_idx)
- mso.existing = schema_obj.get('sites')[site_idx]['anps'][anp_idx]['epgs'][epg_idx]['subnets'][subnet_idx]
-
- if state == 'query':
- if subnet is None:
- mso.existing = schema_obj.get('sites')[site_idx]['anps'][anp_idx]['epgs'][epg_idx]['subnets']
- elif not mso.existing:
- mso.fail_json(msg="Subnet '{subnet}' not found".format(subnet=subnet))
- mso.exit_json()
-
- subnets_path = '/sites/{0}/anps/{1}/epgs/{2}/subnets'.format(site_template, anp, epg)
- ops = []
-
- mso.previous = mso.existing
- if state == 'absent':
- if mso.existing:
- mso.sent = mso.existing = {}
- ops.append(dict(op='remove', path=subnet_path))
-
- elif state == 'present':
- if not mso.existing:
- if description is None:
- description = subnet
- if scope is None:
- scope = 'private'
- if shared is None:
- shared = False
- if no_default_gateway is None:
- no_default_gateway = False
-
- payload = dict(
- ip=subnet,
- description=description,
- scope=scope,
- shared=shared,
- noDefaultGateway=no_default_gateway,
- )
-
- mso.sanitize(payload, collate=True)
-
- if mso.existing:
- ops.append(dict(op='replace', path=subnet_path, value=mso.sent))
- else:
- ops.append(dict(op='add', path=subnets_path + '/-', value=mso.sent))
-
- mso.existing = mso.proposed
-
- if not module.check_mode:
- mso.request(schema_path, method='PATCH', data=ops)
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_schema_site_bd.py b/lib/ansible/modules/network/aci/mso_schema_site_bd.py
deleted file mode 100644
index 636cbbf9ab..0000000000
--- a/lib/ansible/modules/network/aci/mso_schema_site_bd.py
+++ /dev/null
@@ -1,225 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2019, 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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_schema_site_bd
-short_description: Manage site-local Bridge Domains (BDs) in schema template
-description:
-- Manage site-local BDs in schema template on Cisco ACI Multi-Site.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- schema:
- description:
- - The name of the schema.
- type: str
- required: yes
- site:
- description:
- - The name of the site.
- type: str
- required: yes
- template:
- description:
- - The name of the template.
- type: str
- required: yes
- bd:
- description:
- - The name of the BD to manage.
- type: str
- aliases: [ name ]
- host_route:
- description:
- - Whether host-based routing is enabled.
- 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
-seealso:
-- module: mso_schema_site
-- module: mso_schema_site_bd_l3out
-- module: mso_schema_site_bd_subnet
-- module: mso_schema_template_bd
-extends_documentation_fragment: mso
-'''
-
-EXAMPLES = r'''
-- name: Add a new site BD
- mso_schema_site_bd:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- bd: BD1
- state: present
- delegate_to: localhost
-
-- name: Remove a site BD
- mso_schema_site_bd:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- bd: BD1
- state: absent
- delegate_to: localhost
-
-- name: Query a specific site BD
- mso_schema_site_bd:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- bd: BD1
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all site BDs
- mso_schema_site_bd:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- schema=dict(type='str', required=True),
- site=dict(type='str', required=True),
- template=dict(type='str', required=True),
- bd=dict(type='str', aliases=['name']), # This parameter is not required for querying all objects
- host_route=dict(type='bool'),
- state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_if=[
- ['state', 'absent', ['bd']],
- ['state', 'present', ['bd']],
- ],
- )
-
- schema = module.params.get('schema')
- site = module.params.get('site')
- template = module.params.get('template')
- bd = module.params.get('bd')
- host_route = module.params.get('host_route')
- state = module.params.get('state')
-
- mso = MSOModule(module)
-
- # Get schema_id
- schema_obj = mso.get_obj('schemas', displayName=schema)
- if not schema_obj:
- mso.fail_json(msg="Provided schema '{0}' does not exist".format(schema))
-
- schema_path = 'schemas/{id}'.format(**schema_obj)
- schema_id = schema_obj.get('id')
-
- # Get site
- site_id = mso.lookup_site(site)
-
- # Get site_idx
- sites = [(s.get('siteId'), s.get('templateName')) for s in schema_obj.get('sites')]
- if (site_id, template) not in sites:
- mso.fail_json(msg="Provided site/template '{0}-{1}' does not exist. Existing sites/templates: {2}".format(site, template, ', '.join(sites)))
-
- # Schema-access uses indexes
- site_idx = sites.index((site_id, template))
- # Path-based access uses site_id-template
- site_template = '{0}-{1}'.format(site_id, template)
-
- # Get BD
- bd_ref = mso.bd_ref(schema_id=schema_id, template=template, bd=bd)
- bds = [v.get('bdRef') for v in schema_obj.get('sites')[site_idx]['bds']]
- if bd is not None and bd_ref in bds:
- bd_idx = bds.index(bd_ref)
- bd_path = '/sites/{0}/bds/{1}'.format(site_template, bd)
- mso.existing = schema_obj.get('sites')[site_idx]['bds'][bd_idx]
-
- if state == 'query':
- if bd is None:
- mso.existing = schema_obj.get('sites')[site_idx]['bds']
- elif not mso.existing:
- mso.fail_json(msg="BD '{bd}' not found".format(bd=bd))
- mso.exit_json()
-
- bds_path = '/sites/{0}/bds'.format(site_template)
- ops = []
-
- mso.previous = mso.existing
- if state == 'absent':
- if mso.existing:
- mso.sent = mso.existing = {}
- ops.append(dict(op='remove', path=bd_path))
-
- elif state == 'present':
- if not mso.existing:
- if host_route is None:
- host_route = False
-
- payload = dict(
- bdRef=dict(
- schemaId=schema_id,
- templateName=template,
- bdName=bd,
- ),
- hostBasedRouting=host_route,
- )
-
- mso.sanitize(payload, collate=True)
-
- if mso.existing:
- ops.append(dict(op='replace', path=bd_path, value=mso.sent))
- else:
- ops.append(dict(op='add', path=bds_path + '/-', value=mso.sent))
-
- mso.existing = mso.proposed
-
- if not module.check_mode:
- mso.request(schema_path, method='PATCH', data=ops)
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_schema_site_bd_l3out.py b/lib/ansible/modules/network/aci/mso_schema_site_bd_l3out.py
deleted file mode 100644
index a296d44c6c..0000000000
--- a/lib/ansible/modules/network/aci/mso_schema_site_bd_l3out.py
+++ /dev/null
@@ -1,222 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2019, 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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_schema_site_bd_l3out
-short_description: Manage site-local BD l3out's in schema template
-description:
-- Manage site-local BDs l3out's in schema template on Cisco ACI Multi-Site.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- schema:
- description:
- - The name of the schema.
- type: str
- required: yes
- site:
- description:
- - The name of the site.
- type: str
- required: yes
- template:
- description:
- - The name of the template.
- type: str
- required: yes
- bd:
- description:
- - The name of the BD.
- type: str
- aliases: [ name ]
- l3out:
- description:
- - The name of the l3out.
- 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
-notes:
-- The ACI MultiSite PATCH API has a deficiency requiring some objects to be referenced by index.
- This can cause silent corruption on concurrent access when changing/removing on object as
- the wrong object may be referenced. This module is affected by this deficiency.
-seealso:
-- module: mso_schema_site_bd
-- module: mso_schema_template_bd
-extends_documentation_fragment: mso
-'''
-
-EXAMPLES = r'''
-- name: Add a new site BD l3out
- mso_schema_site_bd_l3out:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- bd: BD1
- l3out: L3out1
- state: present
- delegate_to: localhost
-
-- name: Remove a site BD l3out
- mso_schema_site_bd_l3out:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- bd: BD1
- l3out: L3out1
- state: absent
- delegate_to: localhost
-
-- name: Query a specific site BD l3out
- mso_schema_site_bd_l3out:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- bd: BD1
- l3out: L3out1
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all site BD l3outs
- mso_schema_site_bd_l3out:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- bd: BD1
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- schema=dict(type='str', required=True),
- site=dict(type='str', required=True),
- template=dict(type='str', required=True),
- bd=dict(type='str', required=True),
- l3out=dict(type='str', aliases=['name']), # This parameter is 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', ['l3out']],
- ['state', 'present', ['l3out']],
- ],
- )
-
- schema = module.params.get('schema')
- site = module.params.get('site')
- template = module.params.get('template')
- bd = module.params.get('bd')
- l3out = module.params.get('l3out')
- state = module.params.get('state')
-
- mso = MSOModule(module)
-
- # Get schema_id
- schema_obj = mso.get_obj('schemas', displayName=schema)
- if not schema_obj:
- mso.fail_json(msg="Provided schema '{0}' does not exist".format(schema))
-
- schema_path = 'schemas/{id}'.format(**schema_obj)
- schema_id = schema_obj.get('id')
-
- # Get site
- site_id = mso.lookup_site(site)
-
- # Get site_idx
- sites = [(s.get('siteId'), s.get('templateName')) for s in schema_obj.get('sites')]
- if (site_id, template) not in sites:
- mso.fail_json(msg="Provided site/template '{0}-{1}' does not exist. Existing sites/templates: {2}".format(site, template, ', '.join(sites)))
-
- # Schema-access uses indexes
- site_idx = sites.index((site_id, template))
- # Path-based access uses site_id-template
- site_template = '{0}-{1}'.format(site_id, template)
-
- # Get BD
- bd_ref = mso.bd_ref(schema_id=schema_id, template=template, bd=bd)
- bds = [v.get('bdRef') for v in schema_obj.get('sites')[site_idx]['bds']]
- if bd_ref not in bds:
- mso.fail_json(msg="Provided BD '{0}' does not exist. Existing BDs: {1}".format(bd, ', '.join(bds)))
- bd_idx = bds.index(bd_ref)
-
- # Get L3out
- l3outs = schema_obj.get('sites')[site_idx]['bds'][bd_idx]['l3Outs']
- if l3out is not None and l3out in l3outs:
- l3out_idx = l3outs.index(l3out)
- # FIXME: Changes based on index are DANGEROUS
- l3out_path = '/sites/{0}/bds/{1}/l3Outs/{2}'.format(site_template, bd, l3out_idx)
- mso.existing = schema_obj.get('sites')[site_idx]['bds'][bd_idx]['l3Outs'][l3out_idx]
-
- if state == 'query':
- if l3out is None:
- mso.existing = schema_obj.get('sites')[site_idx]['bds'][bd_idx]['l3Outs']
- elif not mso.existing:
- mso.fail_json(msg="L3out '{l3out}' not found".format(l3out=l3out))
- mso.exit_json()
-
- l3outs_path = '/sites/{0}/bds/{1}/l3Outs'.format(site_template, bd)
- ops = []
-
- mso.previous = mso.existing
- if state == 'absent':
- if mso.existing:
- mso.sent = mso.existing = {}
- ops.append(dict(op='remove', path=l3out_path))
-
- elif state == 'present':
- mso.sent = l3out
- if not mso.existing:
- ops.append(dict(op='add', path=l3outs_path + '/-', value=l3out))
-
- mso.existing = mso.sent
-
- if not module.check_mode:
- mso.request(schema_path, method='PATCH', data=ops)
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_schema_site_bd_subnet.py b/lib/ansible/modules/network/aci/mso_schema_site_bd_subnet.py
deleted file mode 100644
index f2c74f1ea0..0000000000
--- a/lib/ansible/modules/network/aci/mso_schema_site_bd_subnet.py
+++ /dev/null
@@ -1,266 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2019, 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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_schema_site_bd_subnet
-short_description: Manage site-local BD subnets in schema template
-description:
-- Manage site-local BD subnets in schema template on Cisco ACI Multi-Site.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- schema:
- description:
- - The name of the schema.
- type: str
- required: yes
- site:
- description:
- - The name of the site.
- type: str
- required: yes
- template:
- description:
- - The name of the template.
- type: str
- required: yes
- bd:
- description:
- - The name of the BD.
- type: str
- aliases: [ name ]
- subnet:
- description:
- - The IP range in CIDR notation.
- type: str
- required: true
- aliases: [ ip ]
- description:
- description:
- - The description of this subnet.
- type: str
- scope:
- description:
- - The scope of the subnet.
- type: str
- choices: [ private, public ]
- shared:
- description:
- - Whether this subnet is shared between VRFs.
- type: bool
- no_default_gateway:
- description:
- - Whether this subnet has a default gateway.
- 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
-notes:
-- The ACI MultiSite PATCH API has a deficiency requiring some objects to be referenced by index.
- This can cause silent corruption on concurrent access when changing/removing on object as
- the wrong object may be referenced. This module is affected by this deficiency.
-seealso:
-- module: mso_schema_site_bd
-- module: mso_schema_template_bd
-extends_documentation_fragment: mso
-'''
-
-EXAMPLES = r'''
-- name: Add a new site BD subnet
- mso_schema_site_bd_subnet:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- bd: BD1
- subnet: 11.11.11.0/24
- state: present
- delegate_to: localhost
-
-- name: Remove a site BD subnet
- mso_schema_site_bd_subnet:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- bd: BD1
- subnet: 11.11.11.0/24
- state: absent
- delegate_to: localhost
-
-- name: Query a specific site BD subnet
- mso_schema_site_bd_subnet:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- bd: BD1
- subnet: 11.11.11.0/24
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all site BD subnets
- mso_schema_site_bd_subnet:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- bd: BD1
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec, mso_subnet_spec
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- schema=dict(type='str', required=True),
- site=dict(type='str', required=True),
- template=dict(type='str', required=True),
- bd=dict(type='str', aliases=['name']), # This parameter is not required for querying all objects
- state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
- )
- argument_spec.update(mso_subnet_spec())
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_if=[
- ['state', 'absent', ['bd']],
- ['state', 'present', ['bd']],
- ],
- )
-
- schema = module.params.get('schema')
- site = module.params.get('site')
- template = module.params.get('template')
- bd = module.params.get('bd')
- subnet = module.params.get('subnet')
- description = module.params.get('description')
- scope = module.params.get('scope')
- shared = module.params.get('shared')
- no_default_gateway = module.params.get('no_default_gateway')
- state = module.params.get('state')
-
- mso = MSOModule(module)
-
- # Get schema_id
- schema_obj = mso.get_obj('schemas', displayName=schema)
- if not schema_obj:
- mso.fail_json(msg="Provided schema '{0}' does not exist".format(schema))
-
- schema_path = 'schemas/{id}'.format(**schema_obj)
- schema_id = schema_obj.get('id')
-
- # Get site
- site_id = mso.lookup_site(site)
-
- # Get site_idx
- sites = [(s.get('siteId'), s.get('templateName')) for s in schema_obj.get('sites')]
- if (site_id, template) not in sites:
- mso.fail_json(msg="Provided site/template '{0}-{1}' does not exist. Existing sites/templates: {2}".format(site, template, ', '.join(sites)))
-
- # Schema-access uses indexes
- site_idx = sites.index((site_id, template))
- # Path-based access uses site_id-template
- site_template = '{0}-{1}'.format(site_id, template)
-
- # Get BD
- bd_ref = mso.bd_ref(schema_id=schema_id, template=template, bd=bd)
- bds = [v.get('bdRef') for v in schema_obj.get('sites')[site_idx]['bds']]
- if bd_ref not in bds:
- mso.fail_json(msg="Provided BD '{0}' does not exist. Existing BDs: {1}".format(bd, ', '.join(bds)))
- bd_idx = bds.index(bd_ref)
-
- # Get Subnet
- subnets = [s.get('ip') for s in schema_obj.get('sites')[site_idx]['bds'][bd_idx]['subnets']]
- if subnet in subnets:
- subnet_idx = subnets.index(subnet)
- # FIXME: Changes based on index are DANGEROUS
- subnet_path = '/sites/{0}/bds/{1}/subnets/{2}'.format(site_template, bd, subnet_idx)
- mso.existing = schema_obj.get('sites')[site_idx]['bds'][bd_idx]['subnets'][subnet_idx]
-
- if state == 'query':
- if subnet is None:
- mso.existing = schema_obj.get('sites')[site_idx]['bds'][bd_idx]['subnets']
- elif not mso.existing:
- mso.fail_json(msg="Subnet IP '{subnet}' not found".format(subnet=subnet))
- mso.exit_json()
-
- subnets_path = '/sites/{0}/bds/{1}/subnets'.format(site_template, bd)
- ops = []
-
- mso.previous = mso.existing
- if state == 'absent':
- if mso.existing:
- mso.sent = mso.existing = {}
- ops.append(dict(op='remove', path=subnet_path))
-
- elif state == 'present':
- if not mso.existing:
- if description is None:
- description = subnet
- if scope is None:
- scope = 'private'
- if shared is None:
- shared = False
- if no_default_gateway is None:
- no_default_gateway = False
-
- payload = dict(
- ip=subnet,
- description=description,
- scope=scope,
- shared=shared,
- noDefaultGateway=no_default_gateway,
- )
-
- mso.sanitize(payload, collate=True)
-
- if mso.existing:
- ops.append(dict(op='replace', path=subnet_path, value=mso.sent))
- else:
- ops.append(dict(op='add', path=subnets_path + '/-', value=mso.sent))
-
- mso.existing = mso.proposed
-
- if not module.check_mode:
- mso.request(schema_path, method='PATCH', data=ops)
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_schema_site_vrf.py b/lib/ansible/modules/network/aci/mso_schema_site_vrf.py
deleted file mode 100644
index 7e9e3ff3a2..0000000000
--- a/lib/ansible/modules/network/aci/mso_schema_site_vrf.py
+++ /dev/null
@@ -1,212 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2019, 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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_schema_site_vrf
-short_description: Manage site-local VRFs in schema template
-description:
-- Manage site-local VRFs in schema template on Cisco ACI Multi-Site.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- schema:
- description:
- - The name of the schema.
- type: str
- required: yes
- site:
- description:
- - The name of the site.
- type: str
- required: yes
- template:
- description:
- - The name of the template.
- type: str
- required: yes
- vrf:
- description:
- - The name of the VRF to manage.
- 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
-seealso:
-- module: mso_schema_site
-- module: mso_schema_template_vrf
-extends_documentation_fragment: mso
-'''
-
-EXAMPLES = r'''
-- name: Add a new site VRF
- mso_schema_site_vrf:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- vrf: VRF1
- state: present
- delegate_to: localhost
-
-- name: Remove a site VRF
- mso_schema_site_vrf:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- vrf: VRF1
- state: absent
- delegate_to: localhost
-
-- name: Query a specific site VRF
- mso_schema_site_vrf:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- vrf: VRF1
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all site VRFs
- mso_schema_site_vrf:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- schema=dict(type='str', required=True),
- site=dict(type='str', required=True),
- template=dict(type='str', required=True),
- vrf=dict(type='str', aliases=['name']), # This parameter is 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', ['vrf']],
- ['state', 'present', ['vrf']],
- ],
- )
-
- schema = module.params.get('schema')
- site = module.params.get('site')
- template = module.params.get('template')
- vrf = module.params.get('vrf')
- state = module.params.get('state')
-
- mso = MSOModule(module)
-
- # Get schema_id
- schema_obj = mso.get_obj('schemas', displayName=schema)
- if not schema_obj:
- mso.fail_json(msg="Provided schema '{0}' does not exist".format(schema))
-
- schema_path = 'schemas/{id}'.format(**schema_obj)
- schema_id = schema_obj.get('id')
-
- # Get site
- site_id = mso.lookup_site(site)
-
- # Get site_idx
- sites = [(s.get('siteId'), s.get('templateName')) for s in schema_obj.get('sites')]
- if (site_id, template) not in sites:
- mso.fail_json(msg="Provided site/template '{0}-{1}' does not exist. Existing sites/templates: {2}".format(site, template, ', '.join(sites)))
-
- # Schema-access uses indexes
- site_idx = sites.index((site_id, template))
- # Path-based access uses site_id-template
- site_template = '{0}-{1}'.format(site_id, template)
-
- # Get VRF
- vrf_ref = mso.vrf_ref(schema_id=schema_id, template=template, vrf=vrf)
- vrfs = [v.get('vrfRef') for v in schema_obj.get('sites')[site_idx]['vrfs']]
- if vrf is not None and vrf_ref in vrfs:
- vrf_idx = vrfs.index(vrf_ref)
- vrf_path = '/sites/{0}/vrfs/{1}'.format(site_template, vrf)
- mso.existing = schema_obj.get('sites')[site_idx]['vrfs'][vrf_idx]
-
- if state == 'query':
- if vrf is None:
- mso.existing = schema_obj.get('sites')[site_idx]['vrfs']
- elif not mso.existing:
- mso.fail_json(msg="VRF '{vrf}' not found".format(vrf=vrf))
- mso.exit_json()
-
- vrfs_path = '/sites/{0}/vrfs'.format(site_template)
- ops = []
-
- mso.previous = mso.existing
- if state == 'absent':
- if mso.existing:
- mso.sent = mso.existing = {}
- ops.append(dict(op='remove', path=vrf_path))
-
- elif state == 'present':
- payload = dict(
- vrfRef=dict(
- schemaId=schema_id,
- templateName=template,
- vrfName=vrf,
- ),
- )
-
- mso.sanitize(payload, collate=True)
-
- if mso.existing:
- ops.append(dict(op='replace', path=vrf_path, value=mso.sent))
- else:
- ops.append(dict(op='add', path=vrfs_path + '/-', value=mso.sent))
-
- mso.existing = mso.proposed
-
- if not module.check_mode:
- mso.request(schema_path, method='PATCH', data=ops)
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_schema_site_vrf_region.py b/lib/ansible/modules/network/aci/mso_schema_site_vrf_region.py
deleted file mode 100644
index 1f314d9ae7..0000000000
--- a/lib/ansible/modules/network/aci/mso_schema_site_vrf_region.py
+++ /dev/null
@@ -1,225 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2019, 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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_schema_site_vrf_region
-short_description: Manage site-local VRF regions in schema template
-description:
-- Manage site-local VRF regions in schema template on Cisco ACI Multi-Site.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- schema:
- description:
- - The name of the schema.
- type: str
- required: yes
- site:
- description:
- - The name of the site.
- type: str
- required: yes
- template:
- description:
- - The name of the template.
- type: str
- required: yes
- vrf:
- description:
- - The name of the VRF.
- type: str
- region:
- description:
- - The name of the region to manage.
- 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
-seealso:
-- module: mso_schema_site_vrf
-- module: mso_schema_template_vrf
-extends_documentation_fragment: mso
-'''
-
-EXAMPLES = r'''
-- name: Add a new site VRF region
- mso_schema_template_vrf_region:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- vrf: VRF1
- region: us-west-1
- state: present
- delegate_to: localhost
-
-- name: Remove a site VRF region
- mso_schema_template_vrf_region:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- vrf: VRF1
- region: us-west-1
- state: absent
- delegate_to: localhost
-
-- name: Query a specific site VRF region
- mso_schema_template_vrf_region:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- vrf: VRF1
- region: us-west-1
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all site VRF regions
- mso_schema_template_vrf_region:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- vrf: VRF1
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- schema=dict(type='str', required=True),
- site=dict(type='str', required=True),
- template=dict(type='str', required=True),
- vrf=dict(type='str', required=True),
- region=dict(type='str', aliases=['name']), # This parameter is 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', ['region']],
- ['state', 'present', ['region']],
- ],
- )
-
- schema = module.params.get('schema')
- site = module.params.get('site')
- template = module.params.get('template')
- vrf = module.params.get('vrf')
- region = module.params.get('region')
- state = module.params.get('state')
-
- mso = MSOModule(module)
-
- # Get schema_id
- schema_obj = mso.get_obj('schemas', displayName=schema)
- if not schema_obj:
- mso.fail_json(msg="Provided schema '{0}' does not exist".format(schema))
-
- schema_path = 'schemas/{id}'.format(**schema_obj)
- schema_id = schema_obj.get('id')
-
- # Get site
- site_id = mso.lookup_site(site)
-
- # Get site_idx
- sites = [(s.get('siteId'), s.get('templateName')) for s in schema_obj.get('sites')]
- if (site_id, template) not in sites:
- mso.fail_json(msg="Provided site/template '{0}-{1}' does not exist. Existing sites/templates: {2}".format(site, template, ', '.join(sites)))
-
- # Schema-access uses indexes
- site_idx = sites.index((site_id, template))
- # Path-based access uses site_id-template
- site_template = '{0}-{1}'.format(site_id, template)
-
- # Get VRF
- vrf_ref = mso.vrf_ref(schema_id=schema_id, template=template, vrf=vrf)
- vrfs = [v.get('vrfRef') for v in schema_obj.get('sites')[site_idx]['vrfs']]
- if vrf_ref not in vrfs:
- mso.fail_json(msg="Provided vrf '{0}' does not exist. Existing vrfs: {1}".format(vrf, ', '.join(vrfs)))
- vrf_idx = vrfs.index(vrf_ref)
-
- # Get Region
- regions = [r.get('name') for r in schema_obj.get('sites')[site_idx]['vrfs'][vrf_idx]['regions']]
- if region is not None and region in regions:
- region_idx = regions.index(region)
- region_path = '/sites/{0}/vrfs/{1}/regions/{2}'.format(site_template, vrf, region)
- mso.existing = schema_obj.get('sites')[site_idx]['vrfs'][vrf_idx]['regions'][region_idx]
-
- if state == 'query':
- if region is None:
- mso.existing = schema_obj.get('sites')[site_idx]['vrfs'][vrf_idx]['regions']
- elif not mso.existing:
- mso.fail_json(msg="Region '{region}' not found".format(region=region))
- mso.exit_json()
-
- regions_path = '/sites/{0}/vrfs/{1}/regions'.format(site_template, vrf)
- ops = []
-
- mso.previous = mso.existing
- if state == 'absent':
- if mso.existing:
- mso.sent = mso.existing = {}
- ops.append(dict(op='remove', path=region_path))
-
- elif state == 'present':
-
- payload = dict(
- name=region,
- )
-
- mso.sanitize(payload, collate=True)
-
- if mso.existing:
- ops.append(dict(op='replace', path=region_path, value=mso.sent))
- else:
- ops.append(dict(op='add', path=regions_path + '/-', value=mso.sent))
-
- mso.existing = mso.proposed
-
- if not module.check_mode:
- mso.request(schema_path, method='PATCH', data=ops)
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_schema_site_vrf_region_cidr.py b/lib/ansible/modules/network/aci/mso_schema_site_vrf_region_cidr.py
deleted file mode 100644
index 842e58fe22..0000000000
--- a/lib/ansible/modules/network/aci/mso_schema_site_vrf_region_cidr.py
+++ /dev/null
@@ -1,257 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2019, 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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_schema_site_vrf_region_cidr
-short_description: Manage site-local VRF region CIDRs in schema template
-description:
-- Manage site-local VRF region CIDRs in schema template on Cisco ACI Multi-Site.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- schema:
- description:
- - The name of the schema.
- type: str
- required: yes
- site:
- description:
- - The name of the site.
- type: str
- required: yes
- template:
- description:
- - The name of the template.
- type: str
- required: yes
- vrf:
- description:
- - The name of the VRF.
- type: str
- region:
- description:
- - The name of the region.
- type: str
- cidr:
- description:
- - The name of the region CIDR to manage.
- type: str
- aliases: [ ip ]
- primary:
- description:
- - Whether this is the primary CIDR.
- 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
-notes:
-- The ACI MultiSite PATCH API has a deficiency requiring some objects to be referenced by index.
- This can cause silent corruption on concurrent access when changing/removing on object as
- the wrong object may be referenced. This module is affected by this deficiency.
-seealso:
-- module: mso_schema_site_vrf_region
-- module: mso_schema_site_vrf_region_cidr_subnet
-- module: mso_schema_template_vrf
-extends_documentation_fragment: mso
-'''
-
-EXAMPLES = r'''
-- name: Add a new site VRF region CIDR
- mso_schema_template_vrf_region_cidr:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- vrf: VRF1
- region: us-west-1
- cidr: 14.14.14.1/24
- state: present
- delegate_to: localhost
-
-- name: Remove a site VRF region CIDR
- mso_schema_template_vrf_region_cidr:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- vrf: VRF1
- region: us-west-1
- cidr: 14.14.14.1/24
- state: absent
- delegate_to: localhost
-
-- name: Query a specific site VRF region CIDR
- mso_schema_template_vrf_region_cidr:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- vrf: VRF1
- region: us-west-1
- cidr: 14.14.14.1/24
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all site VRF region CIDR
- mso_schema_template_vrf_region_cidr:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- vrf: VRF1
- region: us-west-1
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- schema=dict(type='str', required=True),
- site=dict(type='str', required=True),
- template=dict(type='str', required=True),
- vrf=dict(type='str', required=True),
- region=dict(type='str', required=True),
- cidr=dict(type='str', aliases=['ip']), # This parameter is not required for querying all objects
- primary=dict(type='bool'),
- state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_if=[
- ['state', 'absent', ['cidr']],
- ['state', 'present', ['cidr']],
- ],
- )
-
- schema = module.params.get('schema')
- site = module.params.get('site')
- template = module.params.get('template')
- vrf = module.params.get('vrf')
- region = module.params.get('region')
- cidr = module.params.get('cidr')
- primary = module.params.get('primary')
- state = module.params.get('state')
-
- mso = MSOModule(module)
-
- # Get schema_id
- schema_obj = mso.get_obj('schemas', displayName=schema)
- if not schema_obj:
- mso.fail_json(msg="Provided schema '{0}' does not exist".format(schema))
-
- schema_path = 'schemas/{id}'.format(**schema_obj)
- schema_id = schema_obj.get('id')
-
- # Get site
- site_id = mso.lookup_site(site)
-
- # Get site_idx
- sites = [(s.get('siteId'), s.get('templateName')) for s in schema_obj.get('sites')]
- if (site_id, template) not in sites:
- mso.fail_json(msg="Provided site/template '{0}-{1}' does not exist. Existing sites/templates: {2}".format(site, template, ', '.join(sites)))
-
- # Schema-access uses indexes
- site_idx = sites.index((site_id, template))
- # Path-based access uses site_id-template
- site_template = '{0}-{1}'.format(site_id, template)
-
- # Get VRF
- vrf_ref = mso.vrf_ref(schema_id=schema_id, template=template, vrf=vrf)
- vrfs = [v.get('vrfRef') for v in schema_obj.get('sites')[site_idx]['vrfs']]
- if vrf_ref not in vrfs:
- mso.fail_json(msg="Provided vrf '{0}' does not exist. Existing vrfs: {1}".format(vrf, ', '.join(vrfs)))
- vrf_idx = vrfs.index(vrf_ref)
-
- # Get Region
- regions = [r.get('name') for r in schema_obj.get('sites')[site_idx]['vrfs'][vrf_idx]['regions']]
- if region not in regions:
- mso.fail_json(msg="Provided region '{0}' does not exist. Existing regions: {1}".format(region, ', '.join(regions)))
- region_idx = regions.index(region)
-
- # Get CIDR
- cidrs = [c.get('ip') for c in schema_obj.get('sites')[site_idx]['vrfs'][vrf_idx]['regions'][region_idx]['cidrs']]
- if cidr is not None and cidr in cidrs:
- cidr_idx = cidrs.index(cidr)
- # FIXME: Changes based on index are DANGEROUS
- cidr_path = '/sites/{0}/vrfs/{1}/regions/{2}/cidrs/{3}'.format(site_template, vrf, region, cidr_idx)
- mso.existing = schema_obj.get('sites')[site_idx]['vrfs'][vrf_idx]['regions'][region_idx]['cidrs'][cidr_idx]
-
- if state == 'query':
- if cidr is None:
- mso.existing = schema_obj.get('sites')[site_idx]['vrfs'][vrf_idx]['regions'][region_idx]['cidrs']
- elif not mso.existing:
- mso.fail_json(msg="CIDR IP '{cidr}' not found".format(cidr=cidr))
- mso.exit_json()
-
- cidrs_path = '/sites/{0}/vrfs/{1}/regions/{2}/cidrs'.format(site_template, vrf, region)
- ops = []
-
- mso.previous = mso.existing
- if state == 'absent':
- if mso.existing:
- mso.sent = mso.existing = {}
- ops.append(dict(op='remove', path=cidr_path))
-
- elif state == 'present':
- if not mso.existing:
- if primary is None:
- primary = False
-
- payload = dict(
- ip=cidr,
- primary=primary,
- )
-
- mso.sanitize(payload, collate=True)
-
- if mso.existing:
- ops.append(dict(op='replace', path=cidr_path, value=mso.sent))
- else:
- ops.append(dict(op='add', path=cidrs_path + '/-', value=mso.sent))
-
- mso.existing = mso.proposed
-
- if not module.check_mode:
- mso.request(schema_path, method='PATCH', data=ops)
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_schema_site_vrf_region_cidr_subnet.py b/lib/ansible/modules/network/aci/mso_schema_site_vrf_region_cidr_subnet.py
deleted file mode 100644
index 1e26932e84..0000000000
--- a/lib/ansible/modules/network/aci/mso_schema_site_vrf_region_cidr_subnet.py
+++ /dev/null
@@ -1,271 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-# Copyright: (c) 2019, 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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_schema_site_vrf_region_cidr_subnet
-short_description: Manage site-local VRF regions in schema template
-description:
-- Manage site-local VRF regions in schema template on Cisco ACI Multi-Site.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- schema:
- description:
- - The name of the schema.
- type: str
- required: yes
- site:
- description:
- - The name of the site.
- type: str
- required: yes
- template:
- description:
- - The name of the template.
- type: str
- required: yes
- vrf:
- description:
- - The name of the VRF.
- type: str
- region:
- description:
- - The name of the region.
- type: str
- cidr:
- description:
- - The IP range of for the region CIDR.
- type: str
- subnet:
- description:
- - The IP subnet of this region CIDR.
- type: str
- aliases: [ ip ]
- zone:
- description:
- - The name of the zone for the region CIDR subnet.
- 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
-notes:
-- The ACI MultiSite PATCH API has a deficiency requiring some objects to be referenced by index.
- This can cause silent corruption on concurrent access when changing/removing on object as
- the wrong object may be referenced. This module is affected by this deficiency.
-seealso:
-- module: mso_schema_site_vrf_region_cidr
-- module: mso_schema_template_vrf
-extends_documentation_fragment: mso
-'''
-
-EXAMPLES = r'''
-- name: Add a new site VRF region CIDR subnet
- mso_schema_template_vrf_region_cidr_subnet:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- vrf: VRF1
- region: us-west-1
- cidr: 14.14.14.1/24
- subnet: 14.14.14.2/24
- zone: us-west-1a
- state: present
- delegate_to: localhost
-
-- name: Remove a site VRF region CIDR subnet
- mso_schema_site_vrf_region_cidr_subnet:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- vrf: VRF1
- region: us-west-1
- cidr: 14.14.14.1/24
- subnet: 14.14.14.2/24
- state: absent
- delegate_to: localhost
-
-- name: Query a specific site VRF region CIDR subnet
- mso_schema_site_vrf_region_cidr_subnet:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- vrf: VRF1
- region: us-west-1
- cidr: 14.14.14.1/24
- subnet: 14.14.14.2/24
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all site VRF region CIDR subnet
- mso_schema_site_vrf_region_cidr_subnet:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema1
- site: Site1
- template: Template1
- vrf: VRF1
- region: us-west-1
- cidr: 14.14.14.1/24
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- schema=dict(type='str', required=True),
- site=dict(type='str', required=True),
- template=dict(type='str', required=True),
- vrf=dict(type='str', required=True),
- region=dict(type='str', required=True),
- cidr=dict(type='str', required=True),
- subnet=dict(type='str', aliases=['ip']), # This parameter is not required for querying all objects
- zone=dict(type='str', aliases=['name']),
- state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_if=[
- ['state', 'absent', ['subnet']],
- ['state', 'present', ['subnet', 'zone']],
- ],
- )
-
- schema = module.params.get('schema')
- site = module.params.get('site')
- template = module.params.get('template')
- vrf = module.params.get('vrf')
- region = module.params.get('region')
- cidr = module.params.get('cidr')
- subnet = module.params.get('subnet')
- zone = module.params.get('zone')
- state = module.params.get('state')
-
- mso = MSOModule(module)
-
- # Get schema_id
- schema_obj = mso.get_obj('schemas', displayName=schema)
- if not schema_obj:
- mso.fail_json(msg="Provided schema '{0}' does not exist".format(schema))
-
- schema_path = 'schemas/{id}'.format(**schema_obj)
- schema_id = schema_obj.get('id')
-
- # Get site
- site_id = mso.lookup_site(site)
-
- # Get site_idx
- sites = [(s.get('siteId'), s.get('templateName')) for s in schema_obj.get('sites')]
- if (site_id, template) not in sites:
- mso.fail_json(msg="Provided site/template '{0}-{1}' does not exist. Existing sites/templates: {2}".format(site, template, ', '.join(sites)))
-
- # Schema-access uses indexes
- site_idx = sites.index((site_id, template))
- # Path-based access uses site_id-template
- site_template = '{0}-{1}'.format(site_id, template)
-
- # Get VRF
- vrf_ref = mso.vrf_ref(schema_id=schema_id, template=template, vrf=vrf)
- vrfs = [v.get('vrfRef') for v in schema_obj.get('sites')[site_idx]['vrfs']]
- if vrf_ref not in vrfs:
- mso.fail_json(msg="Provided vrf '{0}' does not exist. Existing vrfs: {1}".format(vrf, ', '.join(vrfs)))
- vrf_idx = vrfs.index(vrf_ref)
-
- # Get Region
- regions = [r.get('name') for r in schema_obj.get('sites')[site_idx]['vrfs'][vrf_idx]['regions']]
- if region not in regions:
- mso.fail_json(msg="Provided region '{0}' does not exist. Existing regions: {1}".format(region, ', '.join(regions)))
- region_idx = regions.index(region)
-
- # Get CIDR
- cidrs = [c.get('ip') for c in schema_obj.get('sites')[site_idx]['vrfs'][vrf_idx]['regions'][region_idx]['cidrs']]
- if cidr not in cidrs:
- mso.fail_json(msg="Provided CIDR IP '{0}' does not exist. Existing CIDR IPs: {1}".format(cidr, ', '.join(cidrs)))
- cidr_idx = cidrs.index(cidr)
-
- # Get Subnet
- subnets = [s.get('ip') for s in schema_obj.get('sites')[site_idx]['vrfs'][vrf_idx]['regions'][region_idx]['cidrs'][cidr_idx]['subnets']]
- if subnet is not None and subnet in subnets:
- subnet_idx = subnets.index(subnet)
- # FIXME: Changes based on index are DANGEROUS
- subnet_path = '/sites/{0}/vrfs/{1}/regions/{2}/cidrs/{3}/subnets/{4}'.format(site_template, vrf, region, cidr_idx, subnet_idx)
- mso.existing = schema_obj.get('sites')[site_idx]['vrfs'][vrf_idx]['regions'][region_idx]['cidrs'][cidr_idx]['subnets'][subnet_idx]
-
- if state == 'query':
- if subnet is None:
- mso.existing = schema_obj.get('sites')[site_idx]['vrfs'][vrf_idx]['regions'][region_idx]['cidrs'][cidr_idx]['subnets']
- elif not mso.existing:
- mso.fail_json(msg="Subnet IP '{subnet}' not found".format(subnet=subnet))
- mso.exit_json()
-
- subnets_path = '/sites/{0}/vrfs/{1}/regions/{2}/cidrs/{3}/subnets'.format(site_template, vrf, region, cidr_idx)
- ops = []
-
- mso.previous = mso.existing
- if state == 'absent':
- if mso.existing:
- mso.sent = mso.existing = {}
- ops.append(dict(op='remove', path=subnet_path))
-
- elif state == 'present':
-
- payload = dict(
- ip=subnet,
- zone=zone,
- )
-
- mso.sanitize(payload, collate=True)
-
- if mso.existing:
- ops.append(dict(op='replace', path=subnet_path, value=mso.sent))
- else:
- ops.append(dict(op='add', path=subnets_path + '/-', value=mso.sent))
-
- mso.existing = mso.proposed
-
- if not module.check_mode:
- mso.request(schema_path, method='PATCH', data=ops)
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_schema_template.py b/lib/ansible/modules/network/aci/mso_schema_template.py
deleted file mode 100644
index a2af7cb6b5..0000000000
--- a/lib/ansible/modules/network/aci/mso_schema_template.py
+++ /dev/null
@@ -1,247 +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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_schema_template
-short_description: Manage templates in schemas
-description:
-- Manage templates on Cisco ACI Multi-Site.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- tenant:
- description:
- - The tenant used for this template.
- type: str
- required: yes
- schema:
- description:
- - The name of the schema.
- type: str
- required: yes
- template:
- description:
- - The name of the template.
- type: str
- aliases: [ name ]
- display_name:
- description:
- - The name as displayed on the MSO web interface.
- 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
-notes:
-- Due to restrictions of the MSO REST API this module creates schemas when needed, and removes them when the last template has been removed.
-seealso:
-- module: mso_schema
-- module: mso_schema_site
-extends_documentation_fragment: mso
-'''
-
-EXAMPLES = r'''
-- name: Add a new template to a schema
- mso_schema_template:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- tenant: Tenant 1
- schema: Schema 1
- template: Template 1
- state: present
- delegate_to: localhost
-
-- name: Remove a template from a schema
- mso_schema_template:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- tenant: Tenant 1
- schema: Schema 1
- template: Template 1
- state: absent
- delegate_to: localhost
-
-- name: Query a template
- mso_schema_template:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- tenant: Tenant 1
- schema: Schema 1
- template: Template 1
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all templates
- mso_schema_template:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- tenant: Tenant 1
- schema: Schema 1
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- tenant=dict(type='str', required=True),
- schema=dict(type='str', required=True),
- template=dict(type='str', aliases=['name']),
- display_name=dict(type='str'),
- state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_if=[
- ['state', 'absent', ['template']],
- ['state', 'present', ['template']],
- ],
- )
-
- tenant = module.params.get('tenant')
- schema = module.params.get('schema')
- template = module.params.get('template')
- display_name = module.params.get('display_name')
- state = module.params.get('state')
-
- mso = MSOModule(module)
-
- # Get schema
- schema_obj = mso.get_obj('schemas', displayName=schema)
-
- mso.existing = {}
- if schema_obj:
- # Schema exists
- schema_path = 'schemas/{id}'.format(**schema_obj)
-
- # Get template
- templates = [t.get('name') for t in schema_obj.get('templates')]
- if template:
- if template in templates:
- template_idx = templates.index(template)
- mso.existing = schema_obj.get('templates')[template_idx]
- else:
- mso.existing = schema_obj.get('templates')
- else:
- schema_path = 'schemas'
-
- if state == 'query':
- if not mso.existing:
- if template:
- mso.fail_json(msg="Template '{0}' not found".format(template))
- else:
- mso.existing = []
- mso.exit_json()
-
- template_path = '/templates/{0}'.format(template)
- ops = []
-
- mso.previous = mso.existing
- if state == 'absent':
- mso.proposed = mso.sent = {}
-
- if not schema_obj:
- # There was no schema to begin with
- pass
- elif len(templates) == 1:
- # There is only one tenant, remove schema
- mso.existing = {}
- if not module.check_mode:
- mso.request(schema_path, method='DELETE')
- elif mso.existing:
- # Remove existing template
- mso.existing = {}
- ops.append(dict(op='remove', path=template_path))
- else:
- # There was no template to begin with
- pass
-
- elif state == 'present':
- tenant_id = mso.lookup_tenant(tenant)
-
- if display_name is None:
- display_name = mso.existing.get('displayName', template)
-
- if not schema_obj:
- # Schema does not exist, so we have to create it
- payload = dict(
- displayName=schema,
- templates=[dict(
- name=template,
- displayName=display_name,
- tenantId=tenant_id,
- )],
- sites=[],
- )
-
- mso.existing = payload.get('templates')[0]
-
- if not module.check_mode:
- mso.request(schema_path, method='POST', data=payload)
-
- elif mso.existing:
- # Template exists, so we have to update it
- payload = dict(
- name=template,
- displayName=display_name,
- tenantId=tenant_id,
- )
-
- mso.sanitize(payload, collate=True)
-
- ops.append(dict(op='replace', path=template_path + '/displayName', value=display_name))
- ops.append(dict(op='replace', path=template_path + '/tenantId', value=tenant_id))
-
- mso.existing = mso.proposed
- else:
- # Template does not exist, so we have to add it
- payload = dict(
- name=template,
- displayName=display_name,
- tenantId=tenant_id,
- )
-
- mso.sanitize(payload, collate=True)
-
- ops.append(dict(op='add', path='/templates/-', value=payload))
-
- mso.existing = mso.proposed
-
- if not module.check_mode:
- mso.request(schema_path, method='PATCH', data=ops)
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_schema_template_anp.py b/lib/ansible/modules/network/aci/mso_schema_template_anp.py
deleted file mode 100644
index 5be9caa9ed..0000000000
--- a/lib/ansible/modules/network/aci/mso_schema_template_anp.py
+++ /dev/null
@@ -1,205 +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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_schema_template_anp
-short_description: Manage Application Network Profiles (ANPs) in schema templates
-description:
-- Manage ANPs in schema templates on Cisco ACI Multi-Site.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- schema:
- description:
- - The name of the schema.
- type: str
- required: yes
- template:
- description:
- - The name of the template.
- type: str
- required: yes
- anp:
- description:
- - The name of the ANP to manage.
- type: str
- aliases: [ name ]
- display_name:
- description:
- - The name as displayed on the MSO web interface.
- 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
-seealso:
-- module: mso_schema_template
-- module: mso_schema_template_anp_epg
-extends_documentation_fragment: mso
-'''
-
-EXAMPLES = r'''
-- name: Add a new ANP
- mso_schema_template_anp:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- anp: ANP 1
- state: present
- delegate_to: localhost
-
-- name: Remove an ANP
- mso_schema_template_anp:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- anp: ANP 1
- state: absent
- delegate_to: localhost
-
-- name: Query a specific ANPs
- mso_schema_template_anp:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all ANPs
- mso_schema_template_anp:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec, issubset
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- schema=dict(type='str', required=True),
- template=dict(type='str', required=True),
- anp=dict(type='str', aliases=['name']), # This parameter is not required for querying all objects
- display_name=dict(type='str'),
- state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_if=[
- ['state', 'absent', ['anp']],
- ['state', 'present', ['anp']],
- ],
- )
-
- schema = module.params.get('schema')
- template = module.params.get('template')
- anp = module.params.get('anp')
- display_name = module.params.get('display_name')
- state = module.params.get('state')
-
- mso = MSOModule(module)
-
- # Get schema_id
- schema_obj = mso.get_obj('schemas', displayName=schema)
- if not schema_obj:
- mso.fail_json(msg="Provided schema '{0}' does not exist".format(schema))
-
- schema_path = 'schemas/{id}'.format(**schema_obj)
-
- # Get template
- templates = [t.get('name') for t in schema_obj.get('templates')]
- if template not in templates:
- mso.fail_json(msg="Provided template '{0}' does not exist. Existing templates: {1}".format(template, ', '.join(templates)))
- template_idx = templates.index(template)
-
- # Get ANP
- anps = [a.get('name') for a in schema_obj.get('templates')[template_idx]['anps']]
-
- if anp is not None and anp in anps:
- anp_idx = anps.index(anp)
- mso.existing = schema_obj.get('templates')[template_idx]['anps'][anp_idx]
-
- if state == 'query':
- if anp is None:
- mso.existing = schema_obj.get('templates')[template_idx]['anps']
- elif not mso.existing:
- mso.fail_json(msg="ANP '{anp}' not found".format(anp=anp))
- mso.exit_json()
-
- anps_path = '/templates/{0}/anps'.format(template)
- anp_path = '/templates/{0}/anps/{1}'.format(template, anp)
- ops = []
-
- mso.previous = mso.existing
- if state == 'absent':
- if mso.existing:
- mso.sent = mso.existing = {}
- ops.append(dict(op='remove', path=anp_path))
-
- elif state == 'present':
-
- if display_name is None and not mso.existing:
- display_name = anp
-
- epgs = []
- if mso.existing:
- epgs = None
-
- payload = dict(
- name=anp,
- displayName=display_name,
- epgs=epgs,
- )
-
- mso.sanitize(payload, collate=True)
-
- if mso.existing:
- if display_name is not None:
- ops.append(dict(op='replace', path=anp_path + '/displayName', value=display_name))
- else:
- ops.append(dict(op='add', path=anps_path + '/-', value=mso.sent))
-
- mso.existing = mso.proposed
-
- if not module.check_mode:
- mso.request(schema_path, method='PATCH', data=ops)
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_schema_template_anp_epg.py b/lib/ansible/modules/network/aci/mso_schema_template_anp_epg.py
deleted file mode 100644
index 6d91ddc618..0000000000
--- a/lib/ansible/modules/network/aci/mso_schema_template_anp_epg.py
+++ /dev/null
@@ -1,373 +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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_schema_template_anp_epg
-short_description: Manage Endpoint Groups (EPGs) in schema templates
-description:
-- Manage EPGs in schema templates on Cisco ACI Multi-Site.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- schema:
- description:
- - The name of the schema.
- type: str
- required: yes
- template:
- description:
- - The name of the template.
- type: str
- required: yes
- anp:
- description:
- - The name of the ANP.
- type: str
- required: yes
- epg:
- description:
- - The name of the EPG to manage.
- type: str
- aliases: [ name ]
- display_name:
- description:
- - The name as displayed on the MSO web interface.
- type: str
-# contracts:
-# description:
-# - A list of contracts associated to this ANP.
-# type: list
- bd:
- description:
- - The BD associated to this ANP.
- type: dict
- suboptions:
- name:
- description:
- - The name of the BD to associate with.
- required: true
- type: str
- schema:
- description:
- - The schema that defines the referenced BD.
- - If this parameter is unspecified, it defaults to the current schema.
- type: str
- template:
- description:
- - The template that defines the referenced BD.
- type: str
- vrf:
- version_added: '2.9'
- description:
- - The VRF associated to this ANP.
- type: dict
- suboptions:
- name:
- description:
- - The name of the VRF to associate with.
- required: true
- type: str
- schema:
- description:
- - The schema that defines the referenced VRF.
- - If this parameter is unspecified, it defaults to the current schema.
- type: str
- template:
- description:
- - The template that defines the referenced VRF.
- type: str
- subnets:
- description:
- - The subnets associated to this ANP.
- type: list
- suboptions:
- subnet:
- description:
- - The IP range in CIDR notation.
- type: str
- required: true
- aliases: [ ip ]
- description:
- description:
- - The description of this subnet.
- type: str
- scope:
- description:
- - The scope of the subnet.
- type: str
- choices: [ private, public ]
- shared:
- description:
- - Whether this subnet is shared between VRFs.
- type: bool
- no_default_gateway:
- description:
- - Whether this subnet has a default gateway.
- type: bool
- useg_epg:
- description:
- - Whether this is a USEG EPG.
- type: bool
-# useg_epg_attributes:
-# description:
-# - A dictionary consisting of USEG attributes.
-# type: dict
- intra_epg_isolation:
- description:
- - Whether intra EPG isolation is enforced.
- - When not specified, this parameter defaults to C(unenforced).
- type: str
- choices: [ enforced, unenforced ]
- intersite_multicaste_source:
- description:
- - Whether intersite multicast source is enabled.
- - When not specified, this parameter defaults to C(no).
- type: bool
- preferred_group:
- description:
- - Whether this EPG is added to preferred group or not.
- - When not specified, this parameter defaults to C(no).
- type: bool
- version_added: 2.9
- 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
-seealso:
-- module: mso_schema_template_anp
-- module: mso_schema_template_anp_epg_subnet
-- module: mso_schema_template_bd
-- module: mso_schema_template_contract_filter
-extends_documentation_fragment: mso
-'''
-
-EXAMPLES = r'''
-- name: Add a new EPG
- mso_schema_template_anp_epg:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- anp: ANP 1
- epg: EPG 1
- bd:
- name: bd1
- vrf:
- name: vrf1
- state: present
- delegate_to: localhost
-
-- name: Add a new EPG with preferred group.
- mso_schema_template_anp_epg:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- anp: ANP 1
- epg: EPG 1
- state: present
- preferred_group: yes
- delegate_to: localhost
-
-- name: Remove an EPG
- mso_schema_template_anp_epg:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- anp: ANP 1
- epg: EPG 1
- bd:
- name: bd1
- vrf:
- name: vrf1
- state: absent
- delegate_to: localhost
-
-- name: Query a specific EPG
- mso_schema_template_anp_epg:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- anp: ANP 1
- epg: EPG 1
- bd:
- name: bd1
- vrf:
- name: vrf1
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all EPGs
- mso_schema_template_anp_epg:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- anp: ANP 1
- epg: EPG 1
- bd:
- name: bd1
- vrf:
- name: vrf1
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec, mso_reference_spec, mso_subnet_spec, issubset
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- schema=dict(type='str', required=True),
- template=dict(type='str', required=True),
- anp=dict(type='str', required=True),
- epg=dict(type='str', aliases=['name']), # This parameter is not required for querying all objects
- bd=dict(type='dict', options=mso_reference_spec()),
- vrf=dict(type='dict', options=mso_reference_spec()),
- display_name=dict(type='str'),
- useg_epg=dict(type='bool'),
- intra_epg_isolation=dict(type='str', choices=['enforced', 'unenforced']),
- intersite_multicaste_source=dict(type='bool'),
- subnets=dict(type='list', options=mso_subnet_spec()),
- state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
- preferred_group=dict(type='bool'),
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_if=[
- ['state', 'absent', ['epg']],
- ['state', 'present', ['epg']],
- ],
- )
-
- schema = module.params.get('schema')
- template = module.params.get('template')
- anp = module.params.get('anp')
- epg = module.params.get('epg')
- display_name = module.params.get('display_name')
- bd = module.params.get('bd')
- vrf = module.params.get('vrf')
- useg_epg = module.params.get('useg_epg')
- intra_epg_isolation = module.params.get('intra_epg_isolation')
- intersite_multicaste_source = module.params.get('intersite_multicaste_source')
- subnets = module.params.get('subnets')
- state = module.params.get('state')
- preferred_group = module.params.get('preferred_group')
-
- mso = MSOModule(module)
-
- # Get schema_id
- schema_obj = mso.get_obj('schemas', displayName=schema)
- if schema_obj:
- schema_id = schema_obj.get('id')
- else:
- mso.fail_json(msg="Provided schema '{0}' does not exist".format(schema))
-
- schema_path = 'schemas/{id}'.format(**schema_obj)
-
- # Get template
- templates = [t.get('name') for t in schema_obj.get('templates')]
- if template not in templates:
- mso.fail_json(msg="Provided template '{0}' does not exist. Existing templates: {1}".format(template, ', '.join(templates)))
- template_idx = templates.index(template)
-
- # Get ANP
- anps = [a.get('name') for a in schema_obj.get('templates')[template_idx]['anps']]
- if anp not in anps:
- mso.fail_json(msg="Provided anp '{0}' does not exist. Existing anps: {1}".format(anp, ', '.join(anps)))
- anp_idx = anps.index(anp)
-
- # Get EPG
- epgs = [e.get('name') for e in schema_obj.get('templates')[template_idx]['anps'][anp_idx]['epgs']]
- if epg is not None and epg in epgs:
- epg_idx = epgs.index(epg)
- mso.existing = schema_obj.get('templates')[template_idx]['anps'][anp_idx]['epgs'][epg_idx]
-
- if state == 'query':
- if epg is None:
- mso.existing = schema_obj.get('templates')[template_idx]['anps'][anp_idx]['epgs']
- elif not mso.existing:
- mso.fail_json(msg="EPG '{epg}' not found".format(epg=epg))
- mso.exit_json()
-
- epgs_path = '/templates/{0}/anps/{1}/epgs'.format(template, anp)
- epg_path = '/templates/{0}/anps/{1}/epgs/{2}'.format(template, anp, epg)
- ops = []
-
- mso.previous = mso.existing
- if state == 'absent':
- if mso.existing:
- mso.sent = mso.existing = {}
- ops.append(dict(op='remove', path=epg_path))
-
- elif state == 'present':
- bd_ref = mso.make_reference(bd, 'bd', schema_id, template)
- vrf_ref = mso.make_reference(vrf, 'vrf', schema_id, template)
- subnets = mso.make_subnets(subnets)
-
- if display_name is None and not mso.existing:
- display_name = epg
-
- payload = dict(
- name=epg,
- displayName=display_name,
- uSegEpg=useg_epg,
- intraEpg=intra_epg_isolation,
- proxyArp=intersite_multicaste_source,
- # FIXME: Missing functionality
- # uSegAttrs=[],
- contractRelationships=[],
- subnets=subnets,
- bdRef=bd_ref,
- preferredGroup=preferred_group,
- vrfRef=vrf_ref,
- )
-
- mso.sanitize(payload, collate=True)
-
- if mso.existing:
- ops.append(dict(op='replace', path=epg_path, value=mso.sent))
- else:
- ops.append(dict(op='add', path=epgs_path + '/-', value=mso.sent))
-
- mso.existing = mso.proposed
-
- if not module.check_mode:
- mso.request(schema_path, method='PATCH', data=ops)
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_schema_template_anp_epg_contract.py b/lib/ansible/modules/network/aci/mso_schema_template_anp_epg_contract.py
deleted file mode 100644
index c05a9e4dab..0000000000
--- a/lib/ansible/modules/network/aci/mso_schema_template_anp_epg_contract.py
+++ /dev/null
@@ -1,262 +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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_schema_template_anp_epg_contract
-short_description: Manage EPG contracts in schema templates
-description:
-- Manage EPG contracts in schema templates on Cisco ACI Multi-Site.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- schema:
- description:
- - The name of the schema.
- type: str
- required: yes
- template:
- description:
- - The name of the template to change.
- type: str
- required: yes
- anp:
- description:
- - The name of the ANP.
- type: str
- required: yes
- epg:
- description:
- - The name of the EPG to manage.
- type: str
- required: yes
- contract:
- description:
- - A contract associated to this EPG.
- type: dict
- suboptions:
- name:
- description:
- - The name of the Contract to associate with.
- required: true
- type: str
- schema:
- description:
- - The schema that defines the referenced BD.
- - If this parameter is unspecified, it defaults to the current schema.
- type: str
- template:
- description:
- - The template that defines the referenced BD.
- type: str
- type:
- description:
- - The type of contract.
- type: str
- required: true
- choices: [ consumer, provider ]
- 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
-seealso:
-- module: mso_schema_template_anp_epg
-- module: mso_schema_template_contract_filter
-extends_documentation_fragment: mso
-'''
-
-EXAMPLES = r'''
-- name: Add a contract to an EPG
- mso_schema_template_anp_epg_contract:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- anp: ANP 1
- epg: EPG 1
- contract:
- name: Contract 1
- type: consumer
- state: present
- delegate_to: localhost
-
-- name: Remove a Contract
- mso_schema_template_anp_epg_contract:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- anp: ANP 1
- epg: EPG 1
- contract:
- name: Contract 1
- state: absent
- delegate_to: localhost
-
-- name: Query a specific Contract
- mso_schema_template_anp_epg_contract:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- anp: ANP 1
- epg: EPG 1
- contract:
- name: Contract 1
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all Contracts
- mso_schema_template_anp_epg_contract:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- anp: ANP 1
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec, mso_contractref_spec, issubset
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- schema=dict(type='str', required=True),
- template=dict(type='str', required=True),
- anp=dict(type='str', required=True),
- epg=dict(type='str', required=True),
- contract=dict(type='dict', options=mso_contractref_spec()),
- 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']],
- ['state', 'present', ['contract']],
- ],
- )
-
- schema = module.params.get('schema')
- template = module.params.get('template')
- anp = module.params.get('anp')
- epg = module.params.get('epg')
- contract = module.params.get('contract')
- state = module.params.get('state')
-
- mso = MSOModule(module)
-
- if contract:
- if contract.get('schema') is None:
- contract['schema'] = schema
- contract['schema_id'] = mso.lookup_schema(contract.get('schema'))
- if contract.get('template') is None:
- contract['template'] = template
-
- # Get schema_id
- schema_obj = mso.get_obj('schemas', displayName=schema)
- if schema_obj:
- schema_id = schema_obj.get('id')
- else:
- mso.fail_json(msg="Provided schema '{0}' does not exist".format(schema))
-
- schema_path = 'schemas/{id}'.format(**schema_obj)
-
- # Get template
- templates = [t.get('name') for t in schema_obj.get('templates')]
- if template not in templates:
- mso.fail_json(msg="Provided template '{0}' does not exist. Existing templates: {1}".format(template, ', '.join(templates)))
- template_idx = templates.index(template)
-
- # Get ANP
- anps = [a.get('name') for a in schema_obj.get('templates')[template_idx]['anps']]
- if anp not in anps:
- mso.fail_json(msg="Provided anp '{0}' does not exist. Existing anps: {1}".format(anp, ', '.join(anps)))
- anp_idx = anps.index(anp)
-
- # Get EPG
- epgs = [e.get('name') for e in schema_obj.get('templates')[template_idx]['anps'][anp_idx]['epgs']]
- if epg not in epgs:
- mso.fail_json(msg="Provided epg '{epg}' does not exist. Existing epgs: {epgs}".format(epg=epg, epgs=', '.join(epgs)))
- epg_idx = epgs.index(epg)
-
- # Get Contract
- if contract:
- contracts = [(c.get('contractRef'),
- c.get('relationshipType')) for c in schema_obj.get('templates')[template_idx]['anps'][anp_idx]['epgs'][epg_idx]['contractRelationships']]
- contract_ref = mso.contract_ref(**contract)
- if (contract_ref, contract.get('type')) in contracts:
- contract_idx = contracts.index((contract_ref, contract.get('type')))
- contract_path = '/templates/{0}/anps/{1}/epgs/{2}/contractRelationships/{3}'.format(template, anp, epg, contract)
- mso.existing = schema_obj.get('templates')[template_idx]['anps'][anp_idx]['epgs'][epg_idx]['contractRelationships'][contract_idx]
-
- if state == 'query':
- if not contract:
- mso.existing = schema_obj.get('templates')[template_idx]['anps'][anp_idx]['epgs'][epg_idx]['contractRelationships']
- elif not mso.existing:
- mso.fail_json(msg="Contract '{0}' not found".format(contract_ref))
- mso.exit_json()
-
- contracts_path = '/templates/{0}/anps/{1}/epgs/{2}/contractRelationships'.format(template, anp, epg)
- ops = []
-
- mso.previous = mso.existing
- if state == 'absent':
- if mso.existing:
- mso.sent = mso.existing = {}
- ops.append(dict(op='remove', path=contract_path))
-
- elif state == 'present':
- payload = dict(
- relationshipType=contract.get('type'),
- contractRef=dict(
- contractName=contract.get('name'),
- templateName=contract.get('template'),
- schemaId=contract.get('schema_id'),
- ),
- )
-
- mso.sanitize(payload, collate=True)
-
- if mso.existing:
- ops.append(dict(op='replace', path=contract_path, value=mso.sent))
- else:
- ops.append(dict(op='add', path=contracts_path + '/-', value=mso.sent))
-
- mso.existing = mso.proposed
-
- if not module.check_mode:
- mso.request(schema_path, method='PATCH', data=ops)
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_schema_template_anp_epg_subnet.py b/lib/ansible/modules/network/aci/mso_schema_template_anp_epg_subnet.py
deleted file mode 100644
index d7307f54c9..0000000000
--- a/lib/ansible/modules/network/aci/mso_schema_template_anp_epg_subnet.py
+++ /dev/null
@@ -1,258 +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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_schema_template_anp_epg_subnet
-short_description: Manage EPG subnets in schema templates
-description:
-- Manage EPG subnets in schema templates on Cisco ACI Multi-Site.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- schema:
- description:
- - The name of the schema.
- type: str
- required: yes
- template:
- description:
- - The name of the template to change.
- type: str
- required: yes
- anp:
- description:
- - The name of the ANP.
- type: str
- required: yes
- epg:
- description:
- - The name of the EPG to manage.
- type: str
- required: yes
- subnet:
- description:
- - The IP range in CIDR notation.
- type: str
- required: true
- aliases: [ ip ]
- description:
- description:
- - The description of this subnet.
- type: str
- scope:
- description:
- - The scope of the subnet.
- type: str
- choices: [ private, public ]
- shared:
- description:
- - Whether this subnet is shared between VRFs.
- type: bool
- no_default_gateway:
- description:
- - Whether this subnet has a default gateway.
- 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
-notes:
-- Due to restrictions of the MSO REST API concurrent modifications to EPG subnets can be dangerous and corrupt data.
-extends_documentation_fragment: mso
-'''
-
-EXAMPLES = r'''
-- name: Add a new subnet to an EPG
- mso_schema_template_anp_epg_subnet:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- anp: ANP 1
- epg: EPG 1
- subnet: 10.0.0.0/24
- state: present
- delegate_to: localhost
-
-- name: Remove a subnet from an EPG
- mso_schema_template_anp_epg_subnet:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- anp: ANP 1
- epg: EPG 1
- subnet: 10.0.0.0/24
- state: absent
- delegate_to: localhost
-
-- name: Query a specific EPG subnet
- mso_schema_template_anp_epg_subnet:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- anp: ANP 1
- epg: EPG 1
- subnet: 10.0.0.0/24
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all EPGs subnets
- mso_schema_template_anp_epg_subnet:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- anp: ANP 1
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec, mso_reference_spec, mso_subnet_spec
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- schema=dict(type='str', required=True),
- template=dict(type='str', required=True),
- anp=dict(type='str', required=True),
- epg=dict(type='str', required=True),
- state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
- )
- argument_spec.update(mso_subnet_spec())
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_if=[
- ['state', 'absent', ['subnet']],
- ['state', 'present', ['subnet']],
- ],
- )
-
- schema = module.params.get('schema')
- template = module.params.get('template')
- anp = module.params.get('anp')
- epg = module.params.get('epg')
- subnet = module.params.get('subnet')
- description = module.params.get('description')
- scope = module.params.get('scope')
- shared = module.params.get('shared')
- no_default_gateway = module.params.get('no_default_gateway')
- state = module.params.get('state')
-
- mso = MSOModule(module)
-
- # Get schema
- schema_obj = mso.get_obj('schemas', displayName=schema)
- if not schema_obj:
- mso.fail_json(msg="Provided schema '{0}' does not exist".format(schema))
-
- schema_path = 'schemas/{id}'.format(**schema_obj)
-
- # Get template
- templates = [t.get('name') for t in schema_obj.get('templates')]
- if template not in templates:
- mso.fail_json(msg="Provided template '{template}' does not exist. Existing templates: {templates}".format(template=template,
- templates=', '.join(templates)))
- template_idx = templates.index(template)
-
- # Get ANP
- anps = [a.get('name') for a in schema_obj.get('templates')[template_idx]['anps']]
- if anp not in anps:
- mso.fail_json(msg="Provided anp '{anp}' does not exist. Existing anps: {anps}".format(anp=anp, anps=', '.join(anps)))
- anp_idx = anps.index(anp)
-
- # Get EPG
- epgs = [e.get('name') for e in schema_obj.get('templates')[template_idx]['anps'][anp_idx]['epgs']]
- if epg not in epgs:
- mso.fail_json(msg="Provided epg '{epg}' does not exist. Existing epgs: {epgs}".format(epg=epg, epgs=', '.join(epgs)))
- epg_idx = epgs.index(epg)
-
- # Get Subnet
- subnets = [s.get('ip') for s in schema_obj.get('templates')[template_idx]['anps'][anp_idx]['epgs'][epg_idx]['subnets']]
- if subnet in subnets:
- subnet_idx = subnets.index(subnet)
- # FIXME: Changes based on index are DANGEROUS
- subnet_path = '/templates/{0}/anps/{1}/epgs/{2}/subnets/{3}'.format(template, anp, epg, subnet_idx)
- mso.existing = schema_obj.get('templates')[template_idx]['anps'][anp_idx]['epgs'][epg_idx]['subnets'][subnet_idx]
-
- if state == 'query':
- if subnet is None:
- mso.existing = schema_obj.get('templates')[template_idx]['anps'][anp_idx]['epgs'][epg_idx]['subnets']
- elif not mso.existing:
- mso.fail_json(msg="Subnet '{subnet}' not found".format(subnet=subnet))
- mso.exit_json()
-
- subnets_path = '/templates/{0}/anps/{1}/epgs/{2}/subnets'.format(template, anp, epg)
- ops = []
-
- mso.previous = mso.existing
- if state == 'absent':
- if mso.existing:
- mso.existing = {}
- ops.append(dict(op='remove', path=subnet_path))
-
- elif state == 'present':
- if not mso.existing:
- if description is None:
- description = subnet
- if scope is None:
- scope = 'private'
- if shared is None:
- shared = False
- if no_default_gateway is None:
- no_default_gateway = False
-
- payload = dict(
- ip=subnet,
- description=description,
- scope=scope,
- shared=shared,
- noDefaultGateway=no_default_gateway,
- )
-
- mso.sanitize(payload, collate=True)
-
- if mso.existing:
- ops.append(dict(op='replace', path=subnet_path, value=mso.sent))
- else:
- ops.append(dict(op='add', path=subnets_path + '/-', value=mso.sent))
-
- mso.existing = mso.proposed
-
- if not module.check_mode:
- mso.request(schema_path, method='PATCH', data=ops)
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_schema_template_bd.py b/lib/ansible/modules/network/aci/mso_schema_template_bd.py
deleted file mode 100644
index 0673d902e8..0000000000
--- a/lib/ansible/modules/network/aci/mso_schema_template_bd.py
+++ /dev/null
@@ -1,295 +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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_schema_template_bd
-short_description: Manage Bridge Domains (BDs) in schema templates
-description:
-- Manage BDs in schema templates on Cisco ACI Multi-Site.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- schema:
- description:
- - The name of the schema.
- type: str
- required: yes
- template:
- description:
- - The name of the template.
- type: str
- required: yes
- bd:
- description:
- - The name of the BD to manage.
- type: str
- aliases: [ name ]
- display_name:
- description:
- - The name as displayed on the MSO web interface.
- type: str
- vrf:
- description:
- - The VRF associated to this BD. This is required only when creating a new BD.
- type: dict
- suboptions:
- name:
- description:
- - The name of the VRF to associate with.
- required: true
- type: str
- schema:
- description:
- - The schema that defines the referenced VRF.
- - If this parameter is unspecified, it defaults to the current schema.
- type: str
- template:
- description:
- - The template that defines the referenced VRF.
- - If this parameter is unspecified, it defaults to the current template.
- type: str
- subnets:
- description:
- - The subnets associated to this BD.
- type: list
- suboptions:
- subnet:
- description:
- - The IP range in CIDR notation.
- type: str
- required: true
- aliases: [ ip ]
- description:
- description:
- - The description of this subnet.
- type: str
- scope:
- description:
- - The scope of the subnet.
- type: str
- choices: [ private, public ]
- shared:
- description:
- - Whether this subnet is shared between VRFs.
- type: bool
- no_default_gateway:
- description:
- - Whether this subnet has a default gateway.
- type: bool
- intersite_bum_traffic:
- description:
- - Whether to allow intersite BUM traffic.
- type: bool
- optimize_wan_bandwidth:
- description:
- - Whether to optimize WAN bandwidth.
- type: bool
- layer2_stretch:
- description:
- - Whether to enable L2 stretch.
- type: bool
- layer2_unknown_unicast:
- description:
- - Layer2 unknown unicast.
- type: str
- choices: [ flood, proxy ]
- layer3_multicast:
- description:
- - Whether to enable L3 multicast.
- 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
-extends_documentation_fragment: mso
-'''
-
-EXAMPLES = r'''
-- name: Add a new BD
- mso_schema_template_bd:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- bd: BD 1
- vrf:
- name: VRF1
- state: present
- delegate_to: localhost
-
-- name: Remove an BD
- mso_schema_template_bd:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- bd: BD1
- state: absent
- delegate_to: localhost
-
-- name: Query a specific BDs
- mso_schema_template_bd:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- bd: BD1
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all BDs
- mso_schema_template_bd:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec, mso_reference_spec, mso_subnet_spec
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- schema=dict(type='str', required=True),
- template=dict(type='str', required=True),
- bd=dict(type='str', aliases=['name']), # This parameter is not required for querying all objects
- display_name=dict(type='str'),
- intersite_bum_traffic=dict(type='bool'),
- optimize_wan_bandwidth=dict(type='bool'),
- layer2_stretch=dict(type='bool'),
- layer2_unknown_unicast=dict(type='str', choices=['flood', 'proxy']),
- layer3_multicast=dict(type='bool'),
- vrf=dict(type='dict', options=mso_reference_spec()),
- subnets=dict(type='list', options=mso_subnet_spec()),
- state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_if=[
- ['state', 'absent', ['bd']],
- ['state', 'present', ['bd', 'vrf']],
- ],
- )
-
- schema = module.params.get('schema')
- template = module.params.get('template')
- bd = module.params.get('bd')
- display_name = module.params.get('display_name')
- intersite_bum_traffic = module.params.get('intersite_bum_traffic')
- optimize_wan_bandwidth = module.params.get('optimize_wan_bandwidth')
- layer2_stretch = module.params.get('layer2_stretch')
- layer2_unknown_unicast = module.params.get('layer2_unknown_unicast')
- layer3_multicast = module.params.get('layer3_multicast')
- vrf = module.params.get('vrf')
- subnets = module.params.get('subnets')
- state = module.params.get('state')
-
- mso = MSOModule(module)
-
- # Get schema_id
- schema_obj = mso.get_obj('schemas', displayName=schema)
- if schema_obj:
- schema_id = schema_obj.get('id')
- else:
- mso.fail_json(msg="Provided schema '{0}' does not exist".format(schema))
-
- schema_path = 'schemas/{id}'.format(**schema_obj)
-
- # Get template
- templates = [t.get('name') for t in schema_obj.get('templates')]
- if template not in templates:
- mso.fail_json(msg="Provided template '{0}' does not exist. Existing templates: {1}".format(template, ', '.join(templates)))
- template_idx = templates.index(template)
-
- # Get ANP
- bds = [b.get('name') for b in schema_obj.get('templates')[template_idx]['bds']]
-
- if bd is not None and bd in bds:
- bd_idx = bds.index(bd)
- mso.existing = schema_obj.get('templates')[template_idx]['bds'][bd_idx]
-
- if state == 'query':
- if bd is None:
- mso.existing = schema_obj.get('templates')[template_idx]['bds']
- elif not mso.existing:
- mso.fail_json(msg="BD '{bd}' not found".format(bd=bd))
- mso.exit_json()
-
- bds_path = '/templates/{0}/bds'.format(template)
- bd_path = '/templates/{0}/bds/{1}'.format(template, bd)
- ops = []
-
- mso.previous = mso.existing
- if state == 'absent':
- if mso.existing:
- mso.sent = mso.existing = {}
- ops.append(dict(op='remove', path=bd_path))
-
- elif state == 'present':
- vrf_ref = mso.make_reference(vrf, 'vrf', schema_id, template)
- subnets = mso.make_subnets(subnets)
-
- if display_name is None and not mso.existing:
- display_name = bd
- if subnets is None and not mso.existing:
- subnets = []
-
- payload = dict(
- name=bd,
- displayName=display_name,
- intersiteBumTrafficAllow=intersite_bum_traffic,
- optimizeWanBandwidth=optimize_wan_bandwidth,
- l2UnknownUnicast=layer2_unknown_unicast,
- l2Stretch=layer2_stretch,
- l3MCast=layer3_multicast,
- subnets=subnets,
- vrfRef=vrf_ref,
- )
-
- mso.sanitize(payload, collate=True)
-
- if mso.existing:
- ops.append(dict(op='replace', path=bd_path, value=mso.sent))
- else:
- ops.append(dict(op='add', path=bds_path + '/-', value=mso.sent))
-
- mso.existing = mso.proposed
-
- if not module.check_mode:
- mso.request(schema_path, method='PATCH', data=ops)
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_schema_template_bd_subnet.py b/lib/ansible/modules/network/aci/mso_schema_template_bd_subnet.py
deleted file mode 100644
index f8ec751e52..0000000000
--- a/lib/ansible/modules/network/aci/mso_schema_template_bd_subnet.py
+++ /dev/null
@@ -1,241 +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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_schema_template_bd_subnet
-short_description: Manage BD subnets in schema templates
-description:
-- Manage BD subnets in schema templates on Cisco ACI Multi-Site.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- schema:
- description:
- - The name of the schema.
- type: str
- required: yes
- template:
- description:
- - The name of the template to change.
- type: str
- required: yes
- bd:
- description:
- - The name of the BD to manage.
- type: str
- required: yes
- subnet:
- description:
- - The IP range in CIDR notation.
- type: str
- required: true
- aliases: [ ip ]
- description:
- description:
- - The description of this subnet.
- type: str
- scope:
- description:
- - The scope of the subnet.
- type: str
- choices: [ private, public ]
- shared:
- description:
- - Whether this subnet is shared between VRFs.
- type: bool
- no_default_gateway:
- description:
- - Whether this subnet has a default gateway.
- 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
-notes:
-- Due to restrictions of the MSO REST API concurrent modifications to BD subnets can be dangerous and corrupt data.
-extends_documentation_fragment: mso
-'''
-
-EXAMPLES = r'''
-- name: Add a new subnet to a BD
- mso_schema_template_bd_subnet:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- bd: BD 1
- subnet: 10.0.0.0/24
- state: present
- delegate_to: localhost
-
-- name: Remove a subset from a BD
- mso_schema_template_bd_subnet:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- bd: BD 1
- subnet: 10.0.0.0/24
- state: absent
- delegate_to: localhost
-
-- name: Query a specific BD subnet
- mso_schema_template_bd_subnet:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- bd: BD 1
- subnet: 10.0.0.0/24
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all BD subnets
- mso_schema_template_bd_subnet:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- bd: BD 1
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec, mso_reference_spec, mso_subnet_spec
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- schema=dict(type='str', required=True),
- template=dict(type='str', required=True),
- bd=dict(type='str', required=True),
- state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
- )
- argument_spec.update(mso_subnet_spec())
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_if=[
- ['state', 'absent', ['subnet']],
- ['state', 'present', ['subnet']],
- ],
- )
-
- schema = module.params.get('schema')
- template = module.params.get('template')
- bd = module.params.get('bd')
- subnet = module.params.get('subnet')
- description = module.params.get('description')
- scope = module.params.get('scope')
- shared = module.params.get('shared')
- no_default_gateway = module.params.get('no_default_gateway')
- state = module.params.get('state')
-
- mso = MSOModule(module)
-
- # Get schema
- schema_obj = mso.get_obj('schemas', displayName=schema)
- if not schema_obj:
- mso.fail_json(msg="Provided schema '{0}' does not exist".format(schema))
-
- schema_path = 'schemas/{id}'.format(**schema_obj)
-
- # Get template
- templates = [t.get('name') for t in schema_obj.get('templates')]
- if template not in templates:
- mso.fail_json(msg="Provided template '{0}' does not exist. Existing templates: {1}".format(template, ', '.join(templates)))
- template_idx = templates.index(template)
-
- # Get BD
- bds = [b.get('name') for b in schema_obj.get('templates')[template_idx]['bds']]
- if bd not in bds:
- mso.fail_json(msg="Provided BD '{0}' does not exist. Existing BDs: {1}".format(bd, ', '.join(bds)))
- bd_idx = bds.index(bd)
-
- # Get Subnet
- subnets = [s.get('ip') for s in schema_obj.get('templates')[template_idx]['bds'][bd_idx]['subnets']]
- if subnet in subnets:
- subnet_idx = subnets.index(subnet)
- # FIXME: Changes based on index are DANGEROUS
- subnet_path = '/templates/{0}/bds/{1}/subnets/{2}'.format(template, bd, subnet_idx)
- mso.existing = schema_obj.get('templates')[template_idx]['bds'][bd_idx]['subnets'][subnet_idx]
-
- if state == 'query':
- if subnet is None:
- mso.existing = schema_obj.get('templates')[template_idx]['bds'][bd_idx]['subnets']
- elif not mso.existing:
- mso.fail_json(msg="Subnet IP '{subnet}' not found".format(subnet=subnet))
- mso.exit_json()
-
- subnets_path = '/templates/{0}/bds/{1}/subnets'.format(template, bd)
- ops = []
-
- mso.previous = mso.existing
- if state == 'absent':
- if mso.existing:
- mso.sent = mso.existing = {}
- ops.append(dict(op='remove', path=subnet_path))
-
- elif state == 'present':
- if not mso.existing:
- if description is None:
- description = subnet
- if scope is None:
- scope = 'private'
- if shared is None:
- shared = False
- if no_default_gateway is None:
- no_default_gateway = False
-
- payload = dict(
- ip=subnet,
- description=description,
- scope=scope,
- shared=shared,
- noDefaultGateway=no_default_gateway,
- )
-
- mso.sanitize(payload, collate=True)
-
- if mso.existing:
- ops.append(dict(op='replace', path=subnet_path, value=mso.sent))
- else:
- ops.append(dict(op='add', path=subnets_path + '/-', value=mso.sent))
-
- mso.existing = mso.proposed
-
- if not module.check_mode:
- mso.request(schema_path, method='PATCH', data=ops)
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_schema_template_contract_filter.py b/lib/ansible/modules/network/aci/mso_schema_template_contract_filter.py
deleted file mode 100644
index e548fd53a1..0000000000
--- a/lib/ansible/modules/network/aci/mso_schema_template_contract_filter.py
+++ /dev/null
@@ -1,340 +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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_schema_template_contract_filter
-short_description: Manage contract filters in schema templates
-description:
-- Manage contract filters in schema templates on Cisco ACI Multi-Site.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- schema:
- description:
- - The name of the schema.
- type: str
- required: yes
- template:
- description:
- - The name of the template.
- type: str
- required: yes
- contract:
- description:
- - The name of the contract to manage.
- type: str
- required: yes
- contract_display_name:
- description:
- - The name as displayed on the MSO web interface.
- - This defaults to the contract name when unset on creation.
- type: str
- contract_filter_type:
- description:
- - The type of filters defined in this contract.
- - This defaults to C(both-way) when unset on creation.
- type: str
- choices: [ both-way, one-way ]
- contract_scope:
- description:
- - The scope of the contract.
- - This defaults to C(vrf) when unset on creation.
- type: str
- choices: [ application-profile, global, tenant, vrf ]
- filter:
- description:
- - The filter to associate with this contract.
- type: str
- aliases: [ name ]
- filter_template:
- description:
- - The template name in which the filter is located.
- type: str
- filter_schema:
- description:
- - The schema name in which the filter is located.
- type: str
- filter_type:
- description:
- - The type of filter to manage.
- type: str
- choices: [ both-way, consumer-to-provider, provider-to-consumer ]
- default: both-way
- aliases: [ type ]
- filter_directives:
- description:
- - A list of filter directives.
- type: list
- choices: [ log, 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
-seealso:
-- module: mso_schema_template_filter_entry
-notes:
-- Due to restrictions of the MSO REST API this module creates contracts when needed, and removes them when the last filter has been removed.
-- Due to restrictions of the MSO REST API concurrent modifications to contract filters can be dangerous and corrupt data.
-extends_documentation_fragment: mso
-'''
-
-EXAMPLES = r'''
-- name: Add a new contract filter
- mso_schema_template_contract_filter:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- contract: Contract 1
- contract_scope: global
- filter: Filter 1
- state: present
- delegate_to: localhost
-
-- name: Remove a contract filter
- mso_schema_template_contract_filter:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- contract: Contract 1
- filter: Filter 1
- state: absent
- delegate_to: localhost
-
-- name: Query a specific contract filter
- mso_schema_template_contract_filter:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- contract: Contract 1
- filter: Filter 1
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all contract filters
- mso_schema_template_contract_filter:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- contract: Contract 1
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec, mso_reference_spec, issubset
-
-FILTER_KEYS = {
- 'both-way': 'filterRelationships',
- 'consumer-to-provider': 'filterRelationshipsConsumerToProvider',
- 'provider-to-consumer': 'filterRelationshipsProviderToConsumer',
-}
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- schema=dict(type='str', required=True),
- template=dict(type='str', required=True),
- contract=dict(type='str', required=True),
- contract_display_name=dict(type='str'),
- contract_scope=dict(type='str', choices=['application-profile', 'global', 'tenant', 'vrf']),
- contract_filter_type=dict(type='str', choices=['both-way', 'one-way']),
- filter=dict(type='str', aliases=['name']), # This parameter is not required for querying all objects
- filter_directives=dict(type='list', choices=['log', 'none']),
- filter_template=dict(type='str'),
- filter_schema=dict(type='str'),
- filter_type=dict(type='str', default='both-way', choices=FILTER_KEYS.keys(), aliases=['type']),
- state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_if=[
- ['state', 'absent', ['filter']],
- ['state', 'present', ['filter']],
- ],
- )
-
- schema = module.params.get('schema')
- template = module.params.get('template')
- contract = module.params.get('contract')
- contract_display_name = module.params.get('contract_display_name')
- contract_filter_type = module.params.get('contract_filter_type')
- contract_scope = module.params.get('contract_scope')
- filter_name = module.params.get('filter')
- filter_directives = module.params.get('filter_directives')
- filter_template = module.params.get('filter_template')
- filter_schema = module.params.get('filter_schema')
- filter_type = module.params.get('filter_type')
- state = module.params.get('state')
-
- contract_ftype = 'bothWay' if contract_filter_type == 'both-way' else 'oneWay'
-
- if contract_filter_type == 'both-way' and filter_type != 'both-way':
- module.warn("You are adding 'one-way' filters to a 'both-way' contract")
- elif contract_filter_type != 'both-way' and filter_type == 'both-way':
- module.warn("You are adding 'both-way' filters to a 'one-way' contract")
-
- if filter_template is None:
- filter_template = template
-
- if filter_schema is None:
- filter_schema = schema
-
- filter_key = FILTER_KEYS[filter_type]
-
- mso = MSOModule(module)
-
- filter_schema_id = mso.lookup_schema(filter_schema)
-
- # Get schema object
- schema_obj = mso.get_obj('schemas', displayName=schema)
- if schema_obj:
- schema_id = schema_obj.get('id')
- else:
- mso.fail_json(msg="Provided schema '{0}' does not exist".format(schema))
-
- schema_path = 'schemas/{id}'.format(**schema_obj)
-
- # Get template
- templates = [t.get('name') for t in schema_obj.get('templates')]
- if template not in templates:
- mso.fail_json(msg="Provided template '{0}' does not exist. Existing templates: {1}".format(template, ', '.join(templates)))
- template_idx = templates.index(template)
-
- # Get contracts
- mso.existing = {}
- contract_idx = None
- filter_idx = None
- contracts = [c.get('name') for c in schema_obj.get('templates')[template_idx]['contracts']]
-
- if contract in contracts:
- contract_idx = contracts.index(contract)
-
- filters = [f.get('filterRef') for f in schema_obj.get('templates')[template_idx]['contracts'][contract_idx][filter_key]]
- filter_ref = mso.filter_ref(schema_id=filter_schema_id, template=filter_template, filter=filter_name)
- if filter_ref in filters:
- filter_idx = filters.index(filter_ref)
- filter_path = '/templates/{0}/contracts/{1}/{2}/{3}'.format(template, contract, filter_key, filter_name)
- mso.existing = schema_obj.get('templates')[template_idx]['contracts'][contract_idx][filter_key][filter_idx]
-
- if state == 'query':
- if contract_idx is None:
- mso.fail_json(msg="Provided contract '{0}' does not exist. Existing contracts: {1}".format(contract, ', '.join(contracts)))
-
- if filter_name is None:
- mso.existing = schema_obj.get('templates')[template_idx]['contracts'][contract_idx][filter_key]
- elif not mso.existing:
- mso.fail_json(msg="FilterRef '{filter_ref}' not found".format(filter_ref=filter_ref))
- mso.exit_json()
-
- ops = []
- contract_path = '/templates/{0}/contracts/{1}'.format(template, contract)
- filters_path = '/templates/{0}/contracts/{1}/{2}'.format(template, contract, filter_key)
-
- mso.previous = mso.existing
- if state == 'absent':
- mso.proposed = mso.sent = {}
-
- if contract_idx is None:
- # There was no contract to begin with
- pass
- elif filter_idx is None:
- # There was no filter to begin with
- pass
- elif len(filters) == 1:
- # There is only one filter, remove contract
- mso.existing = {}
- ops.append(dict(op='remove', path=contract_path))
- else:
- # Remove filter
- mso.existing = {}
- ops.append(dict(op='remove', path=filter_path))
-
- elif state == 'present':
- if filter_directives is None:
- filter_directives = ['none']
-
- payload = dict(
- filterRef=dict(
- filterName=filter_name,
- templateName=filter_template,
- schemaId=filter_schema_id,
- ),
- directives=filter_directives,
- )
-
- mso.sanitize(payload, collate=True)
- mso.existing = mso.sent
-
- if contract_idx is None:
- # Contract does not exist, so we have to create it
- if contract_display_name is None:
- contract_display_name = contract
- if contract_filter_type is None:
- contract_ftype = 'bothWay'
- if contract_scope is None:
- contract_scope = 'context'
-
- payload = {
- 'name': contract,
- 'displayName': contract_display_name,
- 'filterType': contract_ftype,
- 'scope': contract_scope,
- }
-
- ops.append(dict(op='add', path='/templates/{0}/contracts/-'.format(template), value=payload))
- else:
- # Contract exists, but may require an update
- if contract_display_name is not None:
- ops.append(dict(op='replace', path=contract_path + '/displayName', value=contract_display_name))
- if contract_filter_type is not None:
- ops.append(dict(op='replace', path=contract_path + '/filterType', value=contract_ftype))
- if contract_scope is not None:
- ops.append(dict(op='replace', path=contract_path + '/scope', value=contract_scope))
-
- if filter_idx is None:
- # Filter does not exist, so we have to add it
- ops.append(dict(op='add', path=filters_path + '/-', value=mso.sent))
-
- else:
- # Filter exists, we have to update it
- ops.append(dict(op='replace', path=filter_path, value=mso.sent))
-
- if not module.check_mode:
- mso.request(schema_path, method='PATCH', data=ops)
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_schema_template_deploy.py b/lib/ansible/modules/network/aci/mso_schema_template_deploy.py
deleted file mode 100644
index 17375f2eab..0000000000
--- a/lib/ansible/modules/network/aci/mso_schema_template_deploy.py
+++ /dev/null
@@ -1,142 +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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_schema_template_deploy
-short_description: Deploy schema templates to sites
-description:
-- Deploy schema templates to sites.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- schema:
- description:
- - The name of the schema.
- type: str
- required: yes
- template:
- description:
- - The name of the template.
- type: str
- aliases: [ name ]
- site:
- description:
- - The name of the site B(to undeploy).
- type: str
- state:
- description:
- - Use C(deploy) to deploy schema template.
- - Use C(status) to get deployment status.
- - Use C(undeploy) to deploy schema template from a site.
- type: str
- choices: [ deploy, status, undeploy ]
- default: deploy
-seealso:
-- module: mso_schema_site
-- module: mso_schema_template
-extends_documentation_fragment: mso
-'''
-
-EXAMPLES = r'''
-- name: Deploy a schema template
- mso_schema_template_deploy:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- state: deploy
- delegate_to: localhost
-
-- name: Undeploy a schema template
- mso_schema_template_deploy:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- site: Site 1
- state: undeploy
- delegate_to: localhost
-
-- name: Get deployment status
- mso_schema:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- state: status
- delegate_to: localhost
- register: status_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- schema=dict(type='str', required=True),
- template=dict(type='str', required=True, aliases=['name']),
- site=dict(type='str'),
- state=dict(type='str', default='deploy', choices=['deploy', 'status', 'undeploy']),
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_if=[
- ['state', 'undeploy', ['site']],
- ],
- )
-
- schema = module.params.get('schema')
- template = module.params.get('template')
- site = module.params.get('site')
- state = module.params.get('state')
-
- mso = MSOModule(module)
-
- # Get schema
- schema_id = mso.lookup_schema(schema)
-
- payload = dict(
- schemaId=schema_id,
- templateName=template,
- )
-
- qs = None
- if state == 'deploy':
- path = 'execute/schema/{0}/template/{1}'.format(schema_id, template)
- elif state == 'status':
- path = 'status/schema/{0}/template/{1}'.format(schema_id, template)
- elif state == 'undeploy':
- path = 'execute/schema/{0}/template/{1}'.format(schema_id, template)
- site_id = mso.lookup_site(site)
- qs = dict(undeploy=site_id)
-
- if not module.check_mode:
- status = mso.request(path, method='GET', data=payload, qs=qs)
-
- mso.exit_json(**status)
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_schema_template_externalepg.py b/lib/ansible/modules/network/aci/mso_schema_template_externalepg.py
deleted file mode 100644
index 3aa41da35b..0000000000
--- a/lib/ansible/modules/network/aci/mso_schema_template_externalepg.py
+++ /dev/null
@@ -1,226 +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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_schema_template_externalepg
-short_description: Manage external EPGs in schema templates
-description:
-- Manage external EPGs in schema templates on Cisco ACI Multi-Site.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- schema:
- description:
- - The name of the schema.
- type: str
- required: yes
- template:
- description:
- - The name of the template.
- type: str
- required: yes
- externalepg:
- description:
- - The name of the external EPG to manage.
- type: str
- aliases: [ name ]
- display_name:
- description:
- - The name as displayed on the MSO web interface.
- type: str
- vrf:
- description:
- - The VRF associated to this ANP.
- type: dict
- suboptions:
- name:
- description:
- - The name of the VRF to associate with.
- required: true
- type: str
- schema:
- description:
- - The schema that defines the referenced VRF.
- - If this parameter is unspecified, it defaults to the current schema.
- type: str
- template:
- description:
- - The template that defines the referenced VRF.
- - If this parameter is unspecified, it defaults to the current template.
- 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: mso
-'''
-
-EXAMPLES = r'''
-- name: Add a new external EPG
- mso_schema_template_externalepg:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- externalepg: External EPG 1
- state: present
- delegate_to: localhost
-
-- name: Remove an external EPG
- mso_schema_template_externalepg:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- externalepg: external EPG1
- state: absent
- delegate_to: localhost
-
-- name: Query a specific external EPGs
- mso_schema_template_externalepg:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- externalepg: external EPG1
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all external EPGs
- mso_schema_template_externalepg:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec, mso_reference_spec, issubset
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- schema=dict(type='str', required=True),
- template=dict(type='str', required=True),
- externalepg=dict(type='str', aliases=['name']), # This parameter is not required for querying all objects
- display_name=dict(type='str'),
- vrf=dict(type='dict', options=mso_reference_spec()),
- state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_if=[
- ['state', 'absent', ['externalepg']],
- ['state', 'present', ['externalepg', 'vrf']],
- ],
- )
-
- schema = module.params.get('schema')
- template = module.params.get('template')
- externalepg = module.params.get('externalepg')
- display_name = module.params.get('display_name')
- vrf = module.params.get('vrf')
- state = module.params.get('state')
-
- mso = MSOModule(module)
-
- # Get schema_id
- schema_obj = mso.get_obj('schemas', displayName=schema)
- if schema_obj:
- schema_id = schema_obj.get('id')
- else:
- mso.fail_json(msg="Provided schema '{0}' does not exist".format(schema))
-
- schema_path = 'schemas/{id}'.format(**schema_obj)
-
- # Get template
- templates = [t.get('name') for t in schema_obj.get('templates')]
- if template not in templates:
- mso.fail_json(msg="Provided template '{0}' does not exist. Existing templates: {1}".format(template, ', '.join(templates)))
- template_idx = templates.index(template)
-
- # Get external EPGs
- externalepgs = [e.get('name') for e in schema_obj.get('templates')[template_idx]['externalEpgs']]
-
- if externalepg is not None and externalepg in externalepgs:
- externalepg_idx = externalepgs.index(externalepg)
- mso.existing = schema_obj.get('templates')[template_idx]['externalEpgs'][externalepg_idx]
-
- if state == 'query':
- if externalepg is None:
- mso.existing = schema_obj.get('templates')[template_idx]['externalEpgs']
- elif not mso.existing:
- mso.fail_json(msg="External EPG '{externalepg}' not found".format(externalepg=externalepg))
- mso.exit_json()
-
- eepgs_path = '/templates/{0}/externalEpgs'.format(template)
- eepg_path = '/templates/{0}/externalEpgs/{1}'.format(template, externalepg)
- ops = []
-
- mso.previous = mso.existing
- if state == 'absent':
- if mso.existing:
- mso.sent = mso.existing = {}
- ops.append(dict(op='remove', path=eepg_path))
-
- elif state == 'present':
- vrf_ref = mso.make_reference(vrf, 'vrf', schema_id, template)
-
- if display_name is None and not mso.existing:
- display_name = externalepg
-
- payload = dict(
- name=externalepg,
- displayName=display_name,
- vrfRef=vrf_ref,
- # FIXME
- subnets=[],
- contractRelationships=[],
- )
-
- mso.sanitize(payload, collate=True)
-
- if mso.existing:
- ops.append(dict(op='replace', path=eepg_path, value=mso.sent))
- else:
- ops.append(dict(op='add', path=eepgs_path + '/-', value=mso.sent))
-
- mso.existing = mso.proposed
-
- if not module.check_mode:
- mso.request(schema_path, method='PATCH', data=ops)
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_schema_template_filter_entry.py b/lib/ansible/modules/network/aci/mso_schema_template_filter_entry.py
deleted file mode 100644
index f49e54e7ab..0000000000
--- a/lib/ansible/modules/network/aci/mso_schema_template_filter_entry.py
+++ /dev/null
@@ -1,363 +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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_schema_template_filter_entry
-short_description: Manage filter entries in schema templates
-description:
-- Manage filter entries in schema templates on Cisco ACI Multi-Site.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- schema:
- description:
- - The name of the schema.
- type: str
- required: yes
- template:
- description:
- - The name of the template.
- type: str
- required: yes
- filter:
- description:
- - The name of the filter to manage.
- type: str
- required: yes
- filter_display_name:
- description:
- - The name as displayed on the MSO web interface.
- type: str
- entry:
- description:
- - The filter entry name to manage.
- type: str
- aliases: [ name ]
- display_name:
- description:
- - The name as displayed on the MSO web interface.
- type: str
- aliases: [ entry_display_name ]
- description:
- description:
- - The description of this filer entry.
- type: str
- aliases: [ entry_description ]
- ethertype:
- description:
- - The ethernet type to use for this filter entry.
- type: str
- choices: [ arp, fcoe, ip, ipv4, ipv6, mac-security, mpls-unicast, trill, unspecified ]
- ip_protocol:
- description:
- - The IP protocol to use for this filter entry.
- type: str
- choices: [ eigrp, egp, icmp, icmpv6, igmp, igp, l2tp, ospfigp, pim, tcp, udp, unspecified ]
- tcp_session_rules:
- description:
- - A list of TCP session rules.
- type: list
- choices: [ acknowledgement, established, finish, synchronize, reset, unspecified ]
- source_from:
- description:
- - The source port range from.
- type: str
- source_to:
- description:
- - The source port range to.
- type: str
- destination_from:
- description:
- - The destination port range from.
- type: str
- destination_to:
- description:
- - The destination port range to.
- type: str
- arp_flag:
- description:
- - The ARP flag to use for this filter entry.
- type: str
- choices: [ reply, request, unspecified ]
- stateful:
- description:
- - Whether this filter entry is stateful.
- type: bool
- default: no
- fragments_only:
- description:
- - Whether this filter entry only matches fragments.
- type: bool
- default: no
- 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
-seealso:
-- module: mso_schema_template_contract_filter
-notes:
-- Due to restrictions of the MSO REST API this module creates filters when needed, and removes them when the last entry has been removed.
-extends_documentation_fragment: mso
-'''
-
-EXAMPLES = r'''
-- name: Add a new filter entry
- mso_schema_template_filter_entry:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- filter: Filter 1
- state: present
- delegate_to: localhost
-
-- name: Remove a filter entry
- mso_schema_template_filter_entry:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- filter: Filter 1
- state: absent
- delegate_to: localhost
-
-- name: Query a specific filter entry
- mso_schema_template_filter_entry:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- filter: Filter 1
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all filter entries
- mso_schema_template_filter_entry:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec, mso_reference_spec, issubset
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- schema=dict(type='str', required=True),
- template=dict(type='str', required=True),
- filter=dict(type='str', required=True),
- filter_display_name=dict(type='str'),
- entry=dict(type='str', aliases=['name']), # This parameter is not required for querying all objects
- description=dict(type='str', aliases=['entry_description']),
- display_name=dict(type='str', aliases=['entry_display_name']),
- ethertype=dict(type='str', choices=['arp', 'fcoe', 'ip', 'ipv4', 'ipv6', 'mac-security', 'mpls-unicast', 'trill', 'unspecified']),
- ip_protocol=dict(type='str', choices=['eigrp', 'egp', 'icmp', 'icmpv6', 'igmp', 'igp', 'l2tp', 'ospfigp', 'pim', 'tcp', 'udp', 'unspecified']),
- tcp_session_rules=dict(type='list', choices=['acknowledgement', 'established', 'finish', 'synchronize', 'reset', 'unspecified']),
- source_from=dict(type='str'),
- source_to=dict(type='str'),
- destination_from=dict(type='str'),
- destination_to=dict(type='str'),
- arp_flag=dict(type='str', choices=['reply', 'request', 'unspecified']),
- stateful=dict(type='bool'),
- fragments_only=dict(type='bool'),
- state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_if=[
- ['state', 'absent', ['entry']],
- ['state', 'present', ['entry']],
- ],
- )
-
- schema = module.params.get('schema')
- template = module.params.get('template')
- filter_name = module.params.get('filter')
- filter_display_name = module.params.get('filter_display_name')
- entry = module.params.get('entry')
- display_name = module.params.get('display_name')
- description = module.params.get('description')
- ethertype = module.params.get('ethertype')
- ip_protocol = module.params.get('ip_protocol')
- tcp_session_rules = module.params.get('tcp_session_rules')
- source_from = module.params.get('source_from')
- source_to = module.params.get('source_to')
- destination_from = module.params.get('destination_from')
- destination_to = module.params.get('destination_to')
- arp_flag = module.params.get('arp_flag')
- stateful = module.params.get('stateful')
- fragments_only = module.params.get('fragments_only')
- state = module.params.get('state')
-
- mso = MSOModule(module)
-
- # Get schema
- schema_obj = mso.get_obj('schemas', displayName=schema)
- if not schema_obj:
- mso.fail_json(msg="Provided schema '{0}' does not exist".format(schema))
-
- schema_path = 'schemas/{id}'.format(**schema_obj)
-
- # Get template
- templates = [t.get('name') for t in schema_obj.get('templates')]
- if template not in templates:
- mso.fail_json(msg="Provided template '{template}' does not exist. Existing templates: {templates}".format(template=template,
- templates=', '.join(templates)))
- template_idx = templates.index(template)
-
- # Get filters
- mso.existing = {}
- filter_idx = None
- entry_idx = None
- filters = [f.get('name') for f in schema_obj.get('templates')[template_idx]['filters']]
- if filter_name in filters:
- filter_idx = filters.index(filter_name)
-
- entries = [f.get('name') for f in schema_obj.get('templates')[template_idx]['filters'][filter_idx]['entries']]
- if entry in entries:
- entry_idx = entries.index(entry)
- mso.existing = schema_obj.get('templates')[template_idx]['filters'][filter_idx]['entries'][entry_idx]
-
- if state == 'query':
- if entry is None:
- if filter_idx is None:
- mso.fail_json(msg="Filter '{filter}' not found".format(filter=filter_name))
- mso.existing = schema_obj.get('templates')[template_idx]['filters'][filter_idx]['entries']
- elif not mso.existing:
- mso.fail_json(msg="Entry '{entry}' not found".format(entry=entry))
- mso.exit_json()
-
- filters_path = '/templates/{0}/filters'.format(template)
- filter_path = '/templates/{0}/filters/{1}'.format(template, filter_name)
- entries_path = '/templates/{0}/filters/{1}/entries'.format(template, filter_name)
- entry_path = '/templates/{0}/filters/{1}/entries/{2}'.format(template, filter_name, entry)
- ops = []
-
- mso.previous = mso.existing
- if state == 'absent':
- mso.proposed = mso.sent = {}
-
- if filter_idx is None:
- # There was no filter to begin with
- pass
- elif entry_idx is None:
- # There was no entry to begin with
- pass
- elif len(entries) == 1:
- # There is only one entry, remove filter
- mso.existing = {}
- ops.append(dict(op='remove', path=filter_path))
-
- else:
- mso.existing = {}
- ops.append(dict(op='remove', path=entry_path))
-
- elif state == 'present':
-
- if not mso.existing:
- if display_name is None:
- display_name = entry
- if description is None:
- description = ''
- if ethertype is None:
- ethertype = 'unspecified'
- if ip_protocol is None:
- ip_protocol = 'unspecified'
- if tcp_session_rules is None:
- tcp_session_rules = ['unspecified']
- if source_from is None:
- source_from = 'unspecified'
- if source_to is None:
- source_to = 'unspecified'
- if destination_from is None:
- destination_from = 'unspecified'
- if destination_to is None:
- destination_to = 'unspecified'
- if arp_flag is None:
- arp_flag = 'unspecified'
- if stateful is None:
- stateful = False
- if fragments_only is None:
- fragments_only = False
-
- payload = dict(
- name=entry,
- displayName=display_name,
- description=description,
- etherType=ethertype,
- ipProtocol=ip_protocol,
- tcpSessionRules=tcp_session_rules,
- sourceFrom=source_from,
- sourceTo=source_to,
- destinationFrom=destination_from,
- destinationTo=destination_to,
- arpFlag=arp_flag,
- stateful=stateful,
- matchOnlyFragments=fragments_only,
- )
-
- mso.sanitize(payload, collate=True)
-
- if filter_idx is None:
- # Filter does not exist, so we have to create it
- if filter_display_name is None:
- filter_display_name = filter_name
-
- payload = dict(
- name=filter_name,
- displayName=filter_display_name,
- entries=[mso.sent],
- )
-
- ops.append(dict(op='add', path=filters_path + '/-', value=payload))
-
- elif entry_idx is None:
- # Entry does not exist, so we have to add it
- ops.append(dict(op='add', path=entries_path + '/-', value=mso.sent))
-
- else:
- # Entry exists, we have to update it
- for (key, value) in mso.sent.items():
- ops.append(dict(op='replace', path=entry_path + '/' + key, value=value))
-
- mso.existing = mso.proposed
-
- if not module.check_mode:
- mso.request(schema_path, method='PATCH', data=ops)
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_schema_template_l3out.py b/lib/ansible/modules/network/aci/mso_schema_template_l3out.py
deleted file mode 100644
index 6bdeff982f..0000000000
--- a/lib/ansible/modules/network/aci/mso_schema_template_l3out.py
+++ /dev/null
@@ -1,223 +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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_schema_template_l3out
-short_description: Manage l3outs in schema templates
-description:
-- Manage l3outs in schema templates on Cisco ACI Multi-Site.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- schema:
- description:
- - The name of the schema.
- type: str
- required: yes
- template:
- description:
- - The name of the template.
- type: str
- required: yes
- l3out:
- description:
- - The name of the l3out to manage.
- type: str
- aliases: [ name ]
- display_name:
- description:
- - The name as displayed on the MSO web interface.
- type: str
- vrf:
- description:
- - The VRF associated to this L3out.
- type: dict
- suboptions:
- name:
- description:
- - The name of the VRF to associate with.
- required: true
- type: str
- schema:
- description:
- - The schema that defines the referenced VRF.
- - If this parameter is unspecified, it defaults to the current schema.
- type: str
- template:
- description:
- - The template that defines the referenced VRF.
- - If this parameter is unspecified, it defaults to the current schema.
- 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: mso
-'''
-
-EXAMPLES = r'''
-- name: Add a new L3out
- mso_schema_template_l3out:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- l3out: L3out 1
- state: present
- delegate_to: localhost
-
-- name: Remove an L3out
- mso_schema_template_l3out:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- l3out: L3out 1
- state: absent
- delegate_to: localhost
-
-- name: Query a specific L3outs
- mso_schema_template_l3out:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- l3out: L3out 1
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all L3outs
- mso_schema_template_l3out:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec, mso_reference_spec, issubset
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- schema=dict(type='str', required=True),
- template=dict(type='str', required=True),
- l3out=dict(type='str', aliases=['name']), # This parameter is not required for querying all objects
- display_name=dict(type='str'),
- vrf=dict(type='dict', options=mso_reference_spec()),
- state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_if=[
- ['state', 'absent', ['l3out']],
- ['state', 'present', ['l3out', 'vrf']],
- ],
- )
-
- schema = module.params.get('schema')
- template = module.params.get('template')
- l3out = module.params.get('l3out')
- display_name = module.params.get('display_name')
- vrf = module.params.get('vrf')
- state = module.params.get('state')
-
- mso = MSOModule(module)
-
- # Get schema_id
- schema_obj = mso.get_obj('schemas', displayName=schema)
- if schema_obj:
- schema_id = schema_obj.get('id')
- else:
- mso.fail_json(msg="Provided schema '{0}' does not exist".format(schema))
-
- schema_path = 'schemas/{id}'.format(**schema_obj)
-
- # Get template
- templates = [t.get('name') for t in schema_obj.get('templates')]
- if template not in templates:
- mso.fail_json(msg="Provided template '{0}' does not exist. Existing templates: {1}".format(template, ', '.join(templates)))
- template_idx = templates.index(template)
-
- # Get L3out
- l3outs = [l.get('name') for l in schema_obj.get('templates')[template_idx]['intersiteL3outs']]
-
- if l3out is not None and l3out in l3outs:
- l3out_idx = l3outs.index(l3out)
- mso.existing = schema_obj.get('templates')[template_idx]['intersiteL3outs'][l3out_idx]
-
- if state == 'query':
- if l3out is None:
- mso.existing = schema_obj.get('templates')[template_idx]['intersiteL3outs']
- elif not mso.existing:
- mso.fail_json(msg="L3out '{l3out}' not found".format(l3out=l3out))
- mso.exit_json()
-
- l3outs_path = '/templates/{0}/intersiteL3outs'.format(template)
- l3out_path = '/templates/{0}/intersiteL3outs/{1}'.format(template, l3out)
- ops = []
-
- mso.previous = mso.existing
- if state == 'absent':
- if mso.existing:
- mso.sent = mso.existing = {}
- ops.append(dict(op='remove', path=l3out_path))
-
- elif state == 'present':
- vrf_ref = mso.make_reference(vrf, 'vrf', schema_id, template)
-
- if display_name is None and not mso.existing:
- display_name = l3out
-
- payload = dict(
- name=l3out,
- displayName=display_name,
- vrfRef=vrf_ref,
- )
-
- mso.sanitize(payload, collate=True)
-
- if mso.existing:
- ops.append(dict(op='replace', path=l3out_path, value=mso.sent))
- else:
- ops.append(dict(op='add', path=l3outs_path + '/-', value=mso.sent))
-
- mso.existing = mso.proposed
-
- if not module.check_mode:
- mso.request(schema_path, method='PATCH', data=ops)
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_schema_template_vrf.py b/lib/ansible/modules/network/aci/mso_schema_template_vrf.py
deleted file mode 100644
index 9f8ac4373b..0000000000
--- a/lib/ansible/modules/network/aci/mso_schema_template_vrf.py
+++ /dev/null
@@ -1,205 +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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_schema_template_vrf
-short_description: Manage VRFs in schema templates
-description:
-- Manage VRFs in schema templates on Cisco ACI Multi-Site.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- schema:
- description:
- - The name of the schema.
- type: str
- required: yes
- template:
- description:
- - The name of the template.
- type: str
- required: yes
- vrf:
- description:
- - The name of the VRF to manage.
- type: str
- aliases: [ name ]
- display_name:
- description:
- - The name as displayed on the MSO web interface.
- type: str
- layer3_multicast:
- description:
- - Whether to enable L3 multicast.
- 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
-extends_documentation_fragment: mso
-'''
-
-EXAMPLES = r'''
-- name: Add a new VRF
- mso_schema_template_vrf:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- vrf: VRF 1
- state: present
- delegate_to: localhost
-
-- name: Remove an VRF
- mso_schema_template_vrf:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- vrf: VRF1
- state: absent
- delegate_to: localhost
-
-- name: Query a specific VRFs
- mso_schema_template_vrf:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- vrf: VRF1
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all VRFs
- mso_schema_template_vrf:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- schema: Schema 1
- template: Template 1
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec, mso_reference_spec, issubset
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- schema=dict(type='str', required=True),
- template=dict(type='str', required=True),
- vrf=dict(type='str', aliases=['name']), # This parameter is not required for querying all objects
- display_name=dict(type='str'),
- layer3_multicast=dict(type='bool'),
- state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_if=[
- ['state', 'absent', ['vrf']],
- ['state', 'present', ['vrf']],
- ],
- )
-
- schema = module.params.get('schema')
- template = module.params.get('template')
- vrf = module.params.get('vrf')
- display_name = module.params.get('display_name')
- layer3_multicast = module.params.get('layer3_multicast')
- state = module.params.get('state')
-
- mso = MSOModule(module)
-
- # Get schema_id
- schema_obj = mso.get_obj('schemas', displayName=schema)
- if not schema_obj:
- mso.fail_json(msg="Provided schema '{0}' does not exist".format(schema))
-
- schema_path = 'schemas/{id}'.format(**schema_obj)
-
- # Get template
- templates = [t.get('name') for t in schema_obj.get('templates')]
- if template not in templates:
- mso.fail_json(msg="Provided template '{0}' does not exist. Existing templates: {1}".format(template, ', '.join(templates)))
- template_idx = templates.index(template)
-
- # Get ANP
- vrfs = [v.get('name') for v in schema_obj.get('templates')[template_idx]['vrfs']]
-
- if vrf is not None and vrf in vrfs:
- vrf_idx = vrfs.index(vrf)
- mso.existing = schema_obj.get('templates')[template_idx]['vrfs'][vrf_idx]
-
- if state == 'query':
- if vrf is None:
- mso.existing = schema_obj.get('templates')[template_idx]['vrfs']
- elif not mso.existing:
- mso.fail_json(msg="VRF '{vrf}' not found".format(vrf=vrf))
- mso.exit_json()
-
- vrfs_path = '/templates/{0}/vrfs'.format(template)
- vrf_path = '/templates/{0}/vrfs/{1}'.format(template, vrf)
- ops = []
-
- mso.previous = mso.existing
- if state == 'absent':
- if mso.existing:
- mso.sent = mso.existing = {}
- ops.append(dict(op='remove', path=vrf_path))
-
- elif state == 'present':
- if display_name is None and not mso.existing:
- display_name = vrf
-
- payload = dict(
- name=vrf,
- displayName=display_name,
- l3MCast=layer3_multicast,
- # FIXME
- regions=[],
- )
-
- mso.sanitize(payload, collate=True)
-
- if mso.existing:
- ops.append(dict(op='replace', path=vrf_path, value=mso.sent))
- else:
- ops.append(dict(op='add', path=vrfs_path + '/-', value=mso.sent))
-
- mso.existing = mso.proposed
-
- if not module.check_mode:
- mso.request(schema_path, method='PATCH', data=ops)
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_site.py b/lib/ansible/modules/network/aci/mso_site.py
deleted file mode 100644
index 64dd43fc81..0000000000
--- a/lib/ansible/modules/network/aci/mso_site.py
+++ /dev/null
@@ -1,246 +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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_site
-short_description: Manage sites
-description:
-- Manage sites on Cisco ACI Multi-Site.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- apic_password:
- description:
- - The password for the APICs.
- type: str
- required: yes
- apic_site_id:
- description:
- - The site ID of the APICs.
- type: str
- required: yes
- apic_username:
- description:
- - The username for the APICs.
- type: str
- required: yes
- default: admin
- site:
- description:
- - The name of the site.
- type: str
- required: yes
- aliases: [ name ]
- labels:
- description:
- - The labels for this site.
- - Labels that do not already exist will be automatically created.
- type: list
- location:
- description:
- - Location of the site.
- type: dict
- suboptions:
- latitude:
- description:
- - The latitude of the location of the site.
- type: float
- longitude:
- description:
- - The longitude of the location of the site.
- type: float
- urls:
- description:
- - A list of URLs to reference the APICs.
- type: list
- 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: mso
-'''
-
-EXAMPLES = r'''
-- name: Add a new site
- mso_site:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- site: north_europe
- description: North European Datacenter
- apic_username: mso_admin
- apic_password: AnotherSecretPassword
- apic_site_id: 12
- urls:
- - 10.2.3.4
- - 10.2.4.5
- - 10.3.5.6
- labels:
- - NEDC
- - Europe
- - Diegem
- location:
- latitude: 50.887318
- longitude: 4.447084
- state: present
- delegate_to: localhost
-
-- name: Remove a site
- mso_site:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- site: north_europe
- state: absent
- delegate_to: localhost
-
-- name: Query a site
- mso_site:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- site: north_europe
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all sites
- mso_site:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec, issubset
-
-
-def main():
- location_arg_spec = dict(
- latitude=dict(type='float'),
- longitude=dict(type='float'),
- )
-
- argument_spec = mso_argument_spec()
- argument_spec.update(
- apic_password=dict(type='str', no_log=True),
- apic_site_id=dict(type='str'),
- apic_username=dict(type='str', default='admin'),
- labels=dict(type='list'),
- location=dict(type='dict', options=location_arg_spec),
- site=dict(type='str', aliases=['name']),
- state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
- urls=dict(type='list'),
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_if=[
- ['state', 'absent', ['site']],
- ['state', 'present', ['apic_site_id', 'site']],
- ],
- )
-
- apic_username = module.params.get('apic_username')
- apic_password = module.params.get('apic_password')
- apic_site_id = module.params.get('apic_site_id')
- site = module.params.get('site')
- location = module.params.get('location')
- if location is not None:
- latitude = module.params.get('location')['latitude']
- longitude = module.params.get('location')['longitude']
- state = module.params.get('state')
- urls = module.params.get('urls')
-
- mso = MSOModule(module)
-
- site_id = None
- path = 'sites'
-
- # Convert labels
- labels = mso.lookup_labels(module.params.get('labels'), 'site')
-
- # Query for mso.existing object(s)
- if site:
- mso.existing = mso.get_obj(path, name=site)
- if mso.existing:
- site_id = mso.existing.get('id')
- # If we found an existing object, continue with it
- path = 'sites/{id}'.format(id=site_id)
- else:
- mso.existing = mso.query_objs(path)
-
- if state == 'query':
- pass
-
- elif state == 'absent':
- mso.previous = mso.existing
- if mso.existing:
- if module.check_mode:
- mso.existing = {}
- else:
- mso.existing = mso.request(path, method='DELETE', qs=dict(force='true'))
-
- elif state == 'present':
- mso.previous = mso.existing
-
- payload = dict(
- apicSiteId=apic_site_id,
- id=site_id,
- name=site,
- urls=urls,
- labels=labels,
- username=apic_username,
- password=apic_password,
- )
-
- if location is not None:
- payload['location'] = dict(
- lat=latitude,
- long=longitude,
- )
-
- mso.sanitize(payload, collate=True)
-
- if mso.existing:
- if not issubset(mso.sent, mso.existing):
- if module.check_mode:
- mso.existing = mso.proposed
- else:
- mso.existing = mso.request(path, method='PUT', data=mso.sent)
- else:
- if module.check_mode:
- mso.existing = mso.proposed
- else:
- mso.existing = mso.request(path, method='POST', data=mso.sent)
-
- if 'password' in mso.existing:
- mso.existing['password'] = '******'
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_tenant.py b/lib/ansible/modules/network/aci/mso_tenant.py
deleted file mode 100644
index 92db65ce85..0000000000
--- a/lib/ansible/modules/network/aci/mso_tenant.py
+++ /dev/null
@@ -1,200 +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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_tenant
-short_description: Manage tenants
-description:
-- Manage tenants on Cisco ACI Multi-Site.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- tenant:
- description:
- - The name of the tenant.
- type: str
- required: yes
- aliases: [ name ]
- display_name:
- description:
- - The name of the tenant to be displayed in the web UI.
- type: str
- required: yes
- description:
- description:
- - The description for this tenant.
- type: str
- users:
- description:
- - A list of associated users for this tenant.
- - Using this property will replace any existing associated users.
- type: list
- sites:
- description:
- - A list of associated sites for this tenant.
- - Using this property will replace any existing associated sites.
- type: list
- 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: mso
-'''
-
-EXAMPLES = r'''
-- name: Add a new tenant
- mso_tenant:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- tenant: north_europe
- display_name: North European Datacenter
- description: This tenant manages the NEDC environment.
- state: present
- delegate_to: localhost
-
-- name: Remove a tenant
- mso_tenant:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- tenant: north_europe
- state: absent
- delegate_to: localhost
-
-- name: Query a tenant
- mso_tenant:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- tenant: north_europe
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all tenants
- mso_tenant:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r'''
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec, issubset
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- description=dict(type='str'),
- display_name=dict(type='str'),
- tenant=dict(type='str', aliases=['name']),
- users=dict(type='list'),
- sites=dict(type='list'),
- state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_if=[
- ['state', 'absent', ['tenant']],
- ['state', 'present', ['tenant']],
- ],
- )
-
- description = module.params.get('description')
- display_name = module.params.get('display_name')
- tenant = module.params.get('tenant')
- state = module.params.get('state')
-
- mso = MSOModule(module)
-
- # Convert sites and users
- sites = mso.lookup_sites(module.params.get('sites'))
- users = mso.lookup_users(module.params.get('users'))
-
- tenant_id = None
- path = 'tenants'
-
- # Query for existing object(s)
- if tenant:
- mso.existing = mso.get_obj(path, name=tenant)
- if mso.existing:
- tenant_id = mso.existing.get('id')
- # If we found an existing object, continue with it
- path = 'tenants/{id}'.format(id=tenant_id)
- else:
- mso.existing = mso.query_objs(path)
-
- if state == 'query':
- pass
-
- elif state == 'absent':
- mso.previous = mso.existing
- if mso.existing:
- if module.check_mode:
- mso.existing = {}
- else:
- mso.existing = mso.request(path, method='DELETE')
-
- elif state == 'present':
- mso.previous = mso.existing
-
- payload = dict(
- description=description,
- id=tenant_id,
- name=tenant,
- displayName=display_name,
- siteAssociations=sites,
- userAssociations=users,
- )
-
- mso.sanitize(payload, collate=True)
-
- # Ensure displayName is not undefined
- if mso.sent.get('displayName') is None:
- mso.sent['displayName'] = tenant
-
- # Ensure tenant has at least admin user
- if mso.sent.get('userAssociations') is None:
- mso.sent['userAssociations'] = [dict(userId="0000ffff0000000000000020")]
-
- if mso.existing:
- if not issubset(mso.sent, mso.existing):
- if module.check_mode:
- mso.existing = mso.proposed
- else:
- mso.existing = mso.request(path, method='PUT', data=mso.sent)
- else:
- if module.check_mode:
- mso.existing = mso.proposed
- else:
- mso.existing = mso.request(path, method='POST', data=mso.sent)
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/modules/network/aci/mso_user.py b/lib/ansible/modules/network/aci/mso_user.py
deleted file mode 100644
index 5a4621d7ed..0000000000
--- a/lib/ansible/modules/network/aci/mso_user.py
+++ /dev/null
@@ -1,248 +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': 'community'}
-
-DOCUMENTATION = r'''
----
-module: mso_user
-short_description: Manage users
-description:
-- Manage users on Cisco ACI Multi-Site.
-author:
-- Dag Wieers (@dagwieers)
-version_added: '2.8'
-options:
- user:
- description:
- - The name of the user.
- type: str
- required: yes
- aliases: [ name ]
- user_password:
- description:
- - The password of the user.
- type: str
- first_name:
- description:
- - The first name of the user.
- - This parameter is required when creating new users.
- type: str
- last_name:
- description:
- - The last name of the user.
- - This parameter is required when creating new users.
- type: str
- email:
- description:
- - The email address of the user.
- - This parameter is required when creating new users.
- type: str
- phone:
- description:
- - The phone number of the user.
- - This parameter is required when creating new users.
- type: str
- account_status:
- description:
- - The status of the user account.
- type: str
- choices: [ active ]
- domain:
- description:
- - The domain this user belongs to.
- - When creating new users, this defaults to C(Local).
- type: str
- roles:
- description:
- - The roles for this user.
- type: list
- 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
-notes:
-- A default installation of ACI Multi-Site ships with admin password 'we1come!' which requires a password change on first login.
- See the examples of how to change the 'admin' password using Ansible.
-extends_documentation_fragment: mso
-'''
-
-EXAMPLES = r'''
-- name: Update initial admin password
- mso_user:
- host: mso_host
- username: admin
- password: we1come!
- user_name: admin
- user_password: SomeSecretPassword
- state: present
- delegate_to: localhost
-
-- name: Add a new user
- mso_user:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- user_name: dag
- description: Test user
- first_name: Dag
- last_name: Wieers
- email: dag@wieers.com
- phone: +32 478 436 299
- state: present
- delegate_to: localhost
-
-- name: Remove a user
- mso_user:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- user_name: dag
- state: absent
- delegate_to: localhost
-
-- name: Query a user
- mso_user:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- user_name: dag
- state: query
- delegate_to: localhost
- register: query_result
-
-- name: Query all users
- mso_user:
- host: mso_host
- username: admin
- password: SomeSecretPassword
- state: query
- delegate_to: localhost
- register: query_result
-'''
-
-RETURN = r''' # '''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec, issubset
-
-
-def main():
- argument_spec = mso_argument_spec()
- argument_spec.update(
- user=dict(type='str', aliases=['name']),
- user_password=dict(type='str', no_log=True),
- first_name=dict(type='str'),
- last_name=dict(type='str'),
- email=dict(type='str'),
- phone=dict(type='str'),
- # TODO: What possible options do we have ?
- account_status=dict(type='str', choices=['active']),
- domain=dict(type='str'),
- roles=dict(type='list'),
- state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
- )
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- required_if=[
- ['state', 'absent', ['user']],
- ['state', 'present', ['user']],
- ],
- )
-
- user_name = module.params.get('user')
- user_password = module.params.get('user_password')
- first_name = module.params.get('first_name')
- last_name = module.params.get('last_name')
- email = module.params.get('email')
- phone = module.params.get('phone')
- account_status = module.params.get('account_status')
- state = module.params.get('state')
-
- mso = MSOModule(module)
-
- roles = mso.lookup_roles(module.params.get('roles'))
- domain = mso.lookup_domain(module.params.get('domain'))
-
- user_id = None
- path = 'users'
-
- # Query for existing object(s)
- if user_name:
- mso.existing = mso.get_obj(path, username=user_name)
- if mso.existing:
- user_id = mso.existing.get('id')
- # If we found an existing object, continue with it
- path = 'users/{id}'.format(id=user_id)
- else:
- mso.existing = mso.query_objs(path)
-
- if state == 'query':
- pass
-
- elif state == 'absent':
- mso.previous = mso.existing
- if mso.existing:
- if module.check_mode:
- mso.existing = {}
- else:
- mso.existing = mso.request(path, method='DELETE')
-
- elif state == 'present':
- mso.previous = mso.existing
-
- payload = dict(
- id=user_id,
- username=user_name,
- password=user_password,
- firstName=first_name,
- lastName=last_name,
- emailAddress=email,
- phoneNumber=phone,
- accountStatus=account_status,
- domainId=domain,
- roles=roles,
- # active=True,
- # remote=True,
- )
-
- mso.sanitize(payload, collate=True)
-
- if mso.sent.get('accountStatus') is None:
- mso.sent['accountStatus'] = 'active'
-
- if mso.existing:
- if not issubset(mso.sent, mso.existing):
- # NOTE: Since MSO always returns '******' as password, we need to assume a change
- if 'password' in mso.proposed:
- mso.module.warn("A password change is assumed, as the MSO REST API does not return passwords we do not know.")
- mso.result['changed'] = True
-
- if module.check_mode:
- mso.existing = mso.proposed
- else:
- mso.existing = mso.request(path, method='PUT', data=mso.sent)
- else:
- if module.check_mode:
- mso.existing = mso.proposed
- else:
- mso.existing = mso.request(path, method='POST', data=mso.sent)
-
- mso.exit_json()
-
-
-if __name__ == "__main__":
- main()
diff --git a/lib/ansible/plugins/doc_fragments/mso.py b/lib/ansible/plugins/doc_fragments/mso.py
deleted file mode 100644
index 6548859a02..0000000000
--- a/lib/ansible/plugins/doc_fragments/mso.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# -*- 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
-
-
-class ModuleDocFragment(object):
- # Standard files documentation fragment
- DOCUMENTATION = r'''
-options:
- host:
- description:
- - IP Address or hostname of the ACI Multi Site Orchestrator host.
- type: str
- required: yes
- aliases: [ hostname ]
- port:
- description:
- - Port number to be used for the REST connection.
- - The default value depends on parameter `use_ssl`.
- type: int
- username:
- description:
- - The username to use for authentication.
- type: str
- default: admin
- 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
- 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
-requirements:
-- Multi Site Orchestrator v2.1 or newer
-notes:
-- Please read the :ref:`aci_guide` for more detailed information on how to manage your ACI infrastructure using Ansible.
-- This module was written to support ACI Multi Site Orchestrator v2.1 or newer. Some or all functionality may not work on earlier versions.
-'''
diff --git a/test/integration/targets/mso_label/aliases b/test/integration/targets/mso_label/aliases
deleted file mode 100644
index cd28d3c362..0000000000
--- a/test/integration/targets/mso_label/aliases
+++ /dev/null
@@ -1,2 +0,0 @@
-# No ACI MultiSite infrastructure, so not enabled
-unsupported
diff --git a/test/integration/targets/mso_label/tasks/main.yml b/test/integration/targets/mso_label/tasks/main.yml
deleted file mode 100644
index 9246ce1fba..0000000000
--- a/test/integration/targets/mso_label/tasks/main.yml
+++ /dev/null
@@ -1,283 +0,0 @@
-# Test code for the MSO 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 MultiSite host, username and password
- fail:
- msg: 'Please define the following variables: mso_hostname, mso_username and mso_password.'
- when: mso_hostname is not defined or mso_username is not defined or mso_password is not defined
-
-
-# CLEAN ENVIRONMENT
-- name: Remove label ansible_test2
- mso_label: &label_absent
- host: '{{ mso_hostname }}'
- username: '{{ mso_username }}'
- password: '{{ mso_password }}'
- validate_certs: '{{ mso_validate_certs | default(false) }}'
- use_ssl: '{{ mso_use_ssl | default(true) }}'
- use_proxy: '{{ mso_use_proxy | default(true) }}'
- output_level: '{{ mso_output_level | default("info") }}'
- label: ansible_test2
- state: absent
-
-- name: Remove label ansible_test
- mso_label:
- <<: *label_absent
- label: ansible_test
- register: cm_remove_label
-
-
-# ADD LABEL
-- name: Add label (check_mode)
- mso_label: &label_present
- host: '{{ mso_hostname }}'
- username: '{{ mso_username }}'
- password: '{{ mso_password }}'
- validate_certs: '{{ mso_validate_certs | default(false) }}'
- use_ssl: '{{ mso_use_ssl | default(true) }}'
- use_proxy: '{{ mso_use_proxy | default(true) }}'
- output_level: '{{ mso_output_level | default("info") }}'
- label: ansible_test
- state: present
- check_mode: yes
- register: cm_add_label
-
-- name: Verify cm_add_label
- assert:
- that:
- - cm_add_label is changed
- - cm_add_label.previous == {}
- - cm_add_label.current.displayName == 'ansible_test'
- - cm_add_label.current.id is not defined
- - cm_add_label.current.type == 'site'
-
-- name: Add label (normal mode)
- mso_label: *label_present
- register: nm_add_label
-
-- name: nm_Verify add_label
- assert:
- that:
- - nm_add_label is changed
- - nm_add_label.previous == {}
- - nm_add_label.current.displayName == 'ansible_test'
- - nm_add_label.current.id is defined
- - nm_add_label.current.type == 'site'
-
-- name: Add label again (check_mode)
- mso_label: *label_present
- check_mode: yes
- register: cm_add_label_again
-
-- name: Verify cm_add_label_again
- assert:
- that:
- - cm_add_label_again is not changed
- - cm_add_label_again.previous.displayName == 'ansible_test'
- - cm_add_label_again.previous.type == 'site'
- - cm_add_label_again.current.displayName == 'ansible_test'
- - cm_add_label_again.current.id == nm_add_label.current.id
- - cm_add_label_again.current.type == 'site'
-
-- name: Add label again (normal mode)
- mso_label: *label_present
- register: nm_add_label_again
-
-- name: Verify nm_add_label_again
- assert:
- that:
- - nm_add_label_again is not changed
- - nm_add_label_again.previous.displayName == 'ansible_test'
- - nm_add_label_again.previous.type == 'site'
- - nm_add_label_again.current.displayName == 'ansible_test'
- - nm_add_label_again.current.id == nm_add_label.current.id
- - nm_add_label_again.current.type == 'site'
-
-
-# CHANGE LABEL
-- name: Change label (check_mode)
- mso_label:
- <<: *label_present
- label_id: '{{ nm_add_label.current.id }}'
- label: ansible_test2
- check_mode: yes
- register: cm_change_label
-
-- name: Verify cm_change_label
- assert:
- that:
- - cm_change_label is changed
- - cm_change_label.current.displayName == 'ansible_test2'
- - cm_change_label.current.id == nm_add_label.current.id
- - cm_change_label.current.type == 'site'
-
-- name: Change label (normal mode)
- mso_label:
- <<: *label_present
- label_id: '{{ nm_add_label.current.id }}'
- label: ansible_test2
- output_level: debug
- register: nm_change_label
-
-- name: Verify nm_change_label
- assert:
- that:
- - nm_change_label is changed
- - cm_change_label.current.displayName == 'ansible_test2'
- - nm_change_label.current.id == nm_add_label.current.id
- - nm_change_label.current.type == 'site'
-
-- name: Change label again (check_mode)
- mso_label:
- <<: *label_present
- label_id: '{{ nm_add_label.current.id }}'
- label: ansible_test2
- check_mode: yes
- register: cm_change_label_again
-
-- name: Verify cm_change_label_again
- assert:
- that:
- - cm_change_label_again is not changed
- - cm_change_label_again.current.displayName == 'ansible_test2'
- - cm_change_label_again.current.id == nm_add_label.current.id
- - cm_change_label_again.current.type == 'site'
-
-- name: Change label again (normal mode)
- mso_label:
- <<: *label_present
- label_id: '{{ nm_add_label.current.id }}'
- label: ansible_test2
- register: nm_change_label_again
-
-- name: Verify nm_change_label_again
- assert:
- that:
- - nm_change_label_again is not changed
- - nm_change_label_again.current.displayName == 'ansible_test2'
- - nm_change_label_again.current.id == nm_add_label.current.id
- - nm_change_label_again.current.type == 'site'
-
-
-# QUERY ALL LABELS
-- name: Query all labels (check_mode)
- mso_label: &label_query
- host: '{{ mso_hostname }}'
- username: '{{ mso_username }}'
- password: '{{ mso_password }}'
- validate_certs: '{{ mso_validate_certs | default(false) }}'
- use_ssl: '{{ mso_use_ssl | default(true) }}'
- use_proxy: '{{ mso_use_proxy | default(true) }}'
- output_level: '{{ mso_output_level | default("info") }}'
- state: query
- check_mode: yes
- register: cm_query_all_labels
-
-- name: Query all labels (normal mode)
- mso_label: *label_query
- register: nm_query_all_labels
-
-- name: Verify query_all_labels
- assert:
- that:
- - cm_query_all_labels is not changed
- - nm_query_all_labels is not changed
- # NOTE: Order of labels is not stable between calls
- #- cm_query_all_labels == nm_query_all_labels
-
-
-# QUERY A LABEL
-- name: Query our label
- mso_label:
- <<: *label_query
- label: ansible_test2
- check_mode: yes
- register: cm_query_label
-
-- name: Query our label
- mso_label:
- <<: *label_query
- label: ansible_test2
- register: nm_query_label
-
-- name: Verify query_label
- assert:
- that:
- - cm_query_label is not changed
- - cm_query_label.current.displayName == 'ansible_test2'
- - cm_query_label.current.id == nm_add_label.current.id
- - cm_query_label.current.type == 'site'
- - nm_query_label is not changed
- - nm_query_label.current.displayName == 'ansible_test2'
- - nm_query_label.current.id == nm_add_label.current.id
- - nm_query_label.current.type == 'site'
- - cm_query_label == nm_query_label
-
-
-# REMOVE LABEL
-- name: Remove label (check_mode)
- mso_label: *label_absent
- check_mode: yes
- register: cm_remove_label
-
-- name: Verify cm_remove_label
- assert:
- that:
- - cm_remove_label is changed
- - cm_remove_label.current == {}
-
-- name: Remove label (normal mode)
- mso_label: *label_absent
- register: nm_remove_label
-
-- name: Verify nm_remove_label
- assert:
- that:
- - nm_remove_label is changed
- - nm_remove_label.current == {}
-
-- name: Remove label again (check_mode)
- mso_label: *label_absent
- check_mode: yes
- register: cm_remove_label_again
-
-- name: Verify cm_remove_label_again
- assert:
- that:
- - cm_remove_label_again is not changed
- - cm_remove_label_again.current == {}
-
-- name: Remove label again (normal mode)
- mso_label: *label_absent
- register: nm_remove_label_again
-
-- name: Verify nm_remove_label_again
- assert:
- that:
- - nm_remove_label_again is not changed
- - nm_remove_label_again.current == {}
-
-
-# QUERY NON-EXISTING LABEL
-- name: Query non-existing label (check_mode)
- mso_label:
- <<: *label_query
- label: ansible_test
- check_mode: yes
- register: cm_query_non_label
-
-- name: Query non-existing label (normal mode)
- mso_label:
- <<: *label_query
- label: ansible_test
- register: nm_query_non_label
-
-# TODO: Implement more tests
-- name: Verify query_non_label
- assert:
- that:
- - cm_query_non_label is not changed
- - nm_query_non_label is not changed
- - cm_query_non_label == nm_query_non_label
diff --git a/test/integration/targets/mso_role/aliases b/test/integration/targets/mso_role/aliases
deleted file mode 100644
index cd28d3c362..0000000000
--- a/test/integration/targets/mso_role/aliases
+++ /dev/null
@@ -1,2 +0,0 @@
-# No ACI MultiSite infrastructure, so not enabled
-unsupported
diff --git a/test/integration/targets/mso_role/tasks/main.yml b/test/integration/targets/mso_role/tasks/main.yml
deleted file mode 100644
index 6f4ed2b0bd..0000000000
--- a/test/integration/targets/mso_role/tasks/main.yml
+++ /dev/null
@@ -1,289 +0,0 @@
-# Test code for the MSO 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 MultiSite host, username and password
- fail:
- msg: 'Please define the following variables: mso_hostname, mso_username and mso_password.'
- when: mso_hostname is not defined or mso_username is not defined or mso_password is not defined
-
-
-# CLEAN ENVIRONMENT
-- name: Remove role ansible_test2
- mso_role: &role_absent
- host: '{{ mso_hostname }}'
- username: '{{ mso_username }}'
- password: '{{ mso_password }}'
- validate_certs: '{{ mso_validate_certs | default(false) }}'
- use_ssl: '{{ mso_use_ssl | default(true) }}'
- use_proxy: '{{ mso_use_proxy | default(true) }}'
- output_level: '{{ mso_output_level | default("info") }}'
- role: ansible_test2
- state: absent
-
-- name: Remove role ansible_test
- mso_role:
- <<: *role_absent
- role: ansible_test
- register: cm_remove_role
-
-
-# ADD ROLE
-- name: Add role (check_mode)
- mso_role: &role_present
- host: '{{ mso_hostname }}'
- username: '{{ mso_username }}'
- password: '{{ mso_password }}'
- validate_certs: '{{ mso_validate_certs | default(false) }}'
- use_ssl: '{{ mso_use_ssl | default(true) }}'
- use_proxy: '{{ mso_use_proxy | default(true) }}'
- output_level: '{{ mso_output_level | default("info") }}'
- role: ansible_test
- description: Ansible test role
- permissions: view-sites
- state: present
- check_mode: yes
- register: cm_add_role
-
-- name: Verify cm_add_role
- assert:
- that:
- - cm_add_role is changed
- - cm_add_role.previous == {}
- - cm_add_role.current.description == 'Ansible test role'
- - cm_add_role.current.displayName == 'ansible_test'
- - cm_add_role.current.id is not defined
-
-- name: Add role (normal mode)
- mso_role: *role_present
- register: nm_add_role
-
-- name: nm_Verify add_role
- assert:
- that:
- - nm_add_role is changed
- - nm_add_role.previous == {}
- - nm_add_role.current.description == 'Ansible test role'
- - nm_add_role.current.displayName == 'ansible_test'
- - nm_add_role.current.id is defined
-
-- name: Add role again (check_mode)
- mso_role: *role_present
- check_mode: yes
- register: cm_add_role_again
-
-- name: Verify cm_add_role_again
- assert:
- that:
- - cm_add_role_again is not changed
- - cm_add_role_again.previous.description == 'Ansible test role'
- - cm_add_role_again.previous.displayName == 'ansible_test'
- - cm_add_role_again.current.description == 'Ansible test role'
- - cm_add_role_again.current.displayName == 'ansible_test'
- - cm_add_role_again.current.id == nm_add_role.current.id
-
-- name: Add role again (normal mode)
- mso_role: *role_present
- register: nm_add_role_again
-
-- name: Verify nm_add_role_again
- assert:
- that:
- - nm_add_role_again is not changed
- - nm_add_role_again.previous.description == 'Ansible test role'
- - nm_add_role_again.previous.displayName == 'ansible_test'
- - nm_add_role_again.current.description == 'Ansible test role'
- - nm_add_role_again.current.displayName == 'ansible_test'
- - nm_add_role_again.current.id == nm_add_role.current.id
-
-
-# CHANGE ROLE
-- name: Change role (check_mode)
- mso_role:
- <<: *role_present
- role_id: '{{ nm_add_role.current.id }}'
- role: ansible_test2
- description: Ansible test role 2
- check_mode: yes
- register: cm_change_role
-
-- name: Verify cm_change_role
- assert:
- that:
- - cm_change_role is changed
- - cm_change_role.current.description == 'Ansible test role 2'
- - cm_change_role.current.displayName == 'ansible_test2'
- - cm_change_role.current.id == nm_add_role.current.id
-
-- name: Change role (normal mode)
- mso_role:
- <<: *role_present
- role_id: '{{ nm_add_role.current.id }}'
- role: ansible_test2
- description: Ansible test role 2
- output_level: debug
- register: nm_change_role
-
-- name: Verify nm_change_role
- assert:
- that:
- - nm_change_role is changed
- - nm_change_role.current.description == 'Ansible test role 2'
- - nm_change_role.current.displayName == 'ansible_test2'
- - nm_change_role.current.id == nm_add_role.current.id
-
-- name: Change role again (check_mode)
- mso_role:
- <<: *role_present
- role_id: '{{ nm_add_role.current.id }}'
- role: ansible_test2
- description: Ansible test role 2
- check_mode: yes
- register: cm_change_role_again
-
-- name: Verify cm_change_role_again
- assert:
- that:
- - cm_change_role_again is not changed
- - cm_change_role_again.current.description == 'Ansible test role 2'
- - cm_change_role_again.current.displayName == 'ansible_test2'
- - cm_change_role_again.current.id == nm_add_role.current.id
-
-- name: Change role again (normal mode)
- mso_role:
- <<: *role_present
- role_id: '{{ nm_add_role.current.id }}'
- role: ansible_test2
- description: Ansible test role 2
- register: nm_change_role_again
-
-- name: Verify nm_change_role_again
- assert:
- that:
- - nm_change_role_again is not changed
- - nm_change_role_again.current.description == 'Ansible test role 2'
- - nm_change_role_again.current.displayName == 'ansible_test2'
- - nm_change_role_again.current.id == nm_add_role.current.id
-
-
-# QUERY ALL ROLES
-- name: Query all roles (check_mode)
- mso_role: &role_query
- host: '{{ mso_hostname }}'
- username: '{{ mso_username }}'
- password: '{{ mso_password }}'
- validate_certs: '{{ mso_validate_certs | default(false) }}'
- use_ssl: '{{ mso_use_ssl | default(true) }}'
- use_proxy: '{{ mso_use_proxy | default(true) }}'
- output_level: '{{ mso_output_level | default("info") }}'
- state: query
- check_mode: yes
- register: cm_query_all_roles
-
-- name: Query all roles (normal mode)
- mso_role: *role_query
- register: nm_query_all_roles
-
-- name: Verify query_all_roles
- assert:
- that:
- - cm_query_all_roles is not changed
- - nm_query_all_roles is not changed
- # NOTE: Order of roles is not stable between calls
- #- cm_query_all_roles == nm_query_all_roles
-
-
-# QUERY A ROLE
-- name: Query our role
- mso_role:
- <<: *role_query
- role: ansible_test2
- check_mode: yes
- register: cm_query_role
-
-- name: Query our role
- mso_role:
- <<: *role_query
- role: ansible_test2
- register: nm_query_role
-
-- name: Verify query_role
- assert:
- that:
- - cm_query_role is not changed
- - cm_query_role.current.description == 'Ansible test role 2'
- - cm_query_role.current.displayName == 'ansible_test2'
- - cm_query_role.current.id == nm_add_role.current.id
- - nm_query_role is not changed
- - nm_query_role.current.description == 'Ansible test role 2'
- - nm_query_role.current.displayName == 'ansible_test2'
- - nm_query_role.current.id == nm_add_role.current.id
- - cm_query_role == nm_query_role
-
-
-# REMOVE ROLE
-- name: Remove role (check_mode)
- mso_role: *role_absent
- check_mode: yes
- register: cm_remove_role
-
-- name: Verify cm_remove_role
- assert:
- that:
- - cm_remove_role is changed
- - cm_remove_role.current == {}
-
-- name: Remove role (normal mode)
- mso_role: *role_absent
- register: nm_remove_role
-
-- name: Verify nm_remove_role
- assert:
- that:
- - nm_remove_role is changed
- - nm_remove_role.current == {}
-
-- name: Remove role again (check_mode)
- mso_role: *role_absent
- check_mode: yes
- register: cm_remove_role_again
-
-- name: Verify cm_remove_role_again
- assert:
- that:
- - cm_remove_role_again is not changed
- - cm_remove_role_again.current == {}
-
-- name: Remove role again (normal mode)
- mso_role: *role_absent
- register: nm_remove_role_again
-
-- name: Verify nm_remove_role_again
- assert:
- that:
- - nm_remove_role_again is not changed
- - nm_remove_role_again.current == {}
-
-
-# QUERY NON-EXISTING ROLE
-- name: Query non-existing role (check_mode)
- mso_role:
- <<: *role_query
- role: ansible_test
- check_mode: yes
- register: cm_query_non_role
-
-- name: Query non-existing role (normal mode)
- mso_role:
- <<: *role_query
- role: ansible_test
- register: nm_query_non_role
-
-# TODO: Implement more tests
-- name: Verify query_non_role
- assert:
- that:
- - cm_query_non_role is not changed
- - nm_query_non_role is not changed
- - cm_query_non_role == nm_query_non_role
diff --git a/test/integration/targets/mso_site/aliases b/test/integration/targets/mso_site/aliases
deleted file mode 100644
index cd28d3c362..0000000000
--- a/test/integration/targets/mso_site/aliases
+++ /dev/null
@@ -1,2 +0,0 @@
-# No ACI MultiSite infrastructure, so not enabled
-unsupported
diff --git a/test/integration/targets/mso_site/tasks/main.yml b/test/integration/targets/mso_site/tasks/main.yml
deleted file mode 100644
index 2c0092edfe..0000000000
--- a/test/integration/targets/mso_site/tasks/main.yml
+++ /dev/null
@@ -1,283 +0,0 @@
-# Test code for the MSO 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 MultiSite host, username and password
- fail:
- msg: 'Please define the following variables: mso_hostname, mso_username and mso_password.'
- when: mso_hostname is not defined or mso_username is not defined or mso_password is not defined
-
-
-# CLEAN ENVIRONMENT
-- name: Remove site 2
- mso_site: &site_absent
- host: '{{ mso_hostname }}'
- username: '{{ mso_username }}'
- password: '{{ mso_password }}'
- validate_certs: '{{ mso_validate_certs | default(false) }}'
- use_ssl: '{{ mso_use_ssl | default(true) }}'
- use_proxy: '{{ mso_use_proxy | default(true) }}'
- output_level: '{{ mso_output_level | default("info") }}'
- site: '{{ mso_site | default("ansible_test") }}_2'
- state: absent
-
-- name: Remove site
- mso_site:
- <<: *site_absent
- site: '{{ mso_site | default("ansible_test") }}'
- register: cm_remove_site
-
-
-# ADD SITE
-- name: Add site (check_mode)
- mso_site: &site_present
- host: '{{ mso_hostname }}'
- username: '{{ mso_username }}'
- password: '{{ mso_password }}'
- validate_certs: '{{ mso_validate_certs | default(false) }}'
- use_ssl: '{{ mso_use_ssl | default(true) }}'
- use_proxy: '{{ mso_use_proxy | default(true) }}'
- output_level: '{{ mso_output_level | default("info") }}'
- site: '{{ mso_site | default("ansible_test") }}'
- apic_username: admin
- apic_password: '{{ apic_password }}'
- apic_site_id: 101
- urls:
- - https://{{ apic_hostname }}
- location:
- latitude: 50.887318
- longitude: 4.447084
- labels:
- - Diegem
- - EMEA
- - POD51
- state: present
- check_mode: yes
- register: cm_add_site
-
-- name: Verify cm_add_site
- assert:
- that:
- - cm_add_site is changed
- - cm_add_site.previous == {}
- - cm_add_site.current.id is not defined
- - cm_add_site.current.name == mso_site|default("ansible_test")
-
-- name: Add site (normal mode)
- mso_site: *site_present
- register: nm_add_site
-
-- name: nm_Verify add_site
- assert:
- that:
- - nm_add_site is changed
- - nm_add_site.previous == {}
- - nm_add_site.current.id is defined
- - nm_add_site.current.name == mso_site|default("ansible_test")
-
-- name: Add site again (check_mode)
- mso_site: *site_present
- check_mode: yes
- register: cm_add_site_again
-
-- name: Verify cm_add_site_again
- assert:
- that:
- - cm_add_site_again is not changed
- - cm_add_site_again.previous.name == mso_site|default("ansible_test")
- - cm_add_site_again.current.id == nm_add_site.current.id
- - cm_add_site_again.current.name == mso_site|default("ansible_test")
-
-- name: Add site again (normal mode)
- mso_site: *site_present
- register: nm_add_site_again
-
-- name: Verify nm_add_site_again
- assert:
- that:
- - nm_add_site_again is not changed
- - nm_add_site_again.previous.name == mso_site|default("ansible_test")
- - nm_add_site_again.current.id == nm_add_site.current.id
- - nm_add_site_again.current.name == mso_site|default("ansible_test")
-
-
-# CHANGE SITE
-- name: Change site (check_mode)
- mso_site:
- <<: *site_present
- site_id: '{{ nm_add_site.current.id }}'
- site: '{{ mso_site | default("ansible_test") }}_2'
- check_mode: yes
- register: cm_change_site
-
-- name: Verify cm_change_site
- assert:
- that:
- - cm_change_site is changed
- - cm_change_site.current.id == nm_add_site.current.id
- - cm_change_site.current.name == '{{ mso_site | default("ansible_test") }}_2'
-
-- name: Change site (normal mode)
- mso_site:
- <<: *site_present
- site_id: '{{ nm_add_site.current.id }}'
- site: '{{ mso_site | default("ansible_test") }}_2'
- output_level: debug
- register: nm_change_site
-
-- name: Verify nm_change_site
- assert:
- that:
- - nm_change_site is changed
- - nm_change_site.current.id == nm_add_site.current.id
- - nm_change_site.current.name == '{{ mso_site | default("ansible_test") }}_2'
-
-- name: Change site again (check_mode)
- mso_site:
- <<: *site_present
- site_id: '{{ nm_add_site.current.id }}'
- site: '{{ mso_site | default("ansible_test") }}_2'
- check_mode: yes
- register: cm_change_site_again
-
-- name: Verify cm_change_site_again
- assert:
- that:
- - cm_change_site_again is not changed
- - cm_change_site_again.current.id == nm_add_site.current.id
- - cm_change_site_again.current.name == '{{ mso_site | default("ansible_test") }}_2'
-
-- name: Change site again (normal mode)
- mso_site:
- <<: *site_present
- site_id: '{{ nm_add_site.current.id }}'
- site: '{{ mso_site | default("ansible_test") }}_2'
- register: nm_change_site_again
-
-- name: Verify nm_change_site_again
- assert:
- that:
- - nm_change_site_again is not changed
- - nm_change_site_again.current.id == nm_add_site.current.id
- - nm_change_site_again.current.name == '{{ mso_site | default("ansible_test") }}_2'
-
-
-# QUERY ALL SITES
-- name: Query all sites (check_mode)
- mso_site: &site_query
- host: '{{ mso_hostname }}'
- username: '{{ mso_username }}'
- password: '{{ mso_password }}'
- validate_certs: '{{ mso_validate_certs | default(false) }}'
- use_ssl: '{{ mso_use_ssl | default(true) }}'
- use_proxy: '{{ mso_use_proxy | default(true) }}'
- output_level: '{{ mso_output_level | default("info") }}'
- state: query
- check_mode: yes
- register: cm_query_all_sites
-
-- name: Query all sites (normal mode)
- mso_site: *site_query
- register: nm_query_all_sites
-
-- name: Verify query_all_sites
- assert:
- that:
- - cm_query_all_sites is not changed
- - nm_query_all_sites is not changed
- # NOTE: Order of sites is not stable between calls
- #- cm_query_all_sites == nm_query_all_sites
-
-
-# QUERY A SITE
-- name: Query our site
- mso_site:
- <<: *site_query
- site: '{{ mso_site | default("ansible_test") }}_2'
- check_mode: yes
- register: cm_query_site
-
-- name: Query our site
- mso_site:
- <<: *site_query
- site: '{{ mso_site | default("ansible_test") }}_2'
- register: nm_query_site
-
-- name: Verify query_site
- assert:
- that:
- - cm_query_site is not changed
- - cm_query_site.current.id == nm_add_site.current.id
- - cm_query_site.current.name == '{{ mso_site | default("ansible_test") }}_2'
- - nm_query_site is not changed
- - nm_query_site.current.id == nm_add_site.current.id
- - nm_query_site.current.name == '{{ mso_site | default("ansible_test") }}_2'
- - cm_query_site == nm_query_site
-
-
-# REMOVE SITE
-- name: Remove site (check_mode)
- mso_site: *site_absent
- check_mode: yes
- register: cm_remove_site
-
-- name: Verify cm_remove_site
- assert:
- that:
- - cm_remove_site is changed
- - cm_remove_site.current == {}
-
-- name: Remove site (normal mode)
- mso_site: *site_absent
- register: nm_remove_site
-
-- name: Verify nm_remove_site
- assert:
- that:
- - nm_remove_site is changed
- - nm_remove_site.current == {}
-
-- name: Remove site again (check_mode)
- mso_site: *site_absent
- check_mode: yes
- register: cm_remove_site_again
-
-- name: Verify cm_remove_site_again
- assert:
- that:
- - cm_remove_site_again is not changed
- - cm_remove_site_again.current == {}
-
-- name: Remove site again (normal mode)
- mso_site: *site_absent
- register: nm_remove_site_again
-
-- name: Verify nm_remove_site_again
- assert:
- that:
- - nm_remove_site_again is not changed
- - nm_remove_site_again.current == {}
-
-
-# QUERY NON-EXISTING SITE
-- name: Query non-existing site (check_mode)
- mso_site:
- <<: *site_query
- site: '{{ mso_site | default("ansible_test") }}'
- check_mode: yes
- register: cm_query_non_site
-
-- name: Query non-existing site (normal mode)
- mso_site:
- <<: *site_query
- site: '{{ mso_site | default("ansible_test") }}'
- register: nm_query_non_site
-
-# TODO: Implement more tests
-- name: Verify query_non_site
- assert:
- that:
- - cm_query_non_site is not changed
- - nm_query_non_site is not changed
- - cm_query_non_site == nm_query_non_site
diff --git a/test/integration/targets/mso_tenant/aliases b/test/integration/targets/mso_tenant/aliases
deleted file mode 100644
index cd28d3c362..0000000000
--- a/test/integration/targets/mso_tenant/aliases
+++ /dev/null
@@ -1,2 +0,0 @@
-# No ACI MultiSite infrastructure, so not enabled
-unsupported
diff --git a/test/integration/targets/mso_tenant/tasks/main.yml b/test/integration/targets/mso_tenant/tasks/main.yml
deleted file mode 100644
index fb6be21a15..0000000000
--- a/test/integration/targets/mso_tenant/tasks/main.yml
+++ /dev/null
@@ -1,289 +0,0 @@
-# Test code for the MSO 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 MultiSite host, username and password
- fail:
- msg: 'Please define the following variables: mso_hostname, mso_username and mso_password.'
- when: mso_hostname is not defined or mso_username is not defined or mso_password is not defined
-
-
-# CLEAN ENVIRONMENT
-- name: Remove tenant ansible_test2
- mso_tenant: &tenant_absent
- host: '{{ mso_hostname }}'
- username: '{{ mso_username }}'
- password: '{{ mso_password }}'
- validate_certs: '{{ mso_validate_certs | default(false) }}'
- use_ssl: '{{ mso_use_ssl | default(true) }}'
- use_proxy: '{{ mso_use_proxy | default(true) }}'
- output_level: '{{ mso_output_level | default("info") }}'
- tenant: ansible_test2
- state: absent
-
-- name: Remove tenant ansible_test
- mso_tenant:
- <<: *tenant_absent
- tenant: ansible_test
- register: cm_remove_tenant
-
-
-# ADD TENANT
-- name: Add tenant (check_mode)
- mso_tenant: &tenant_present
- host: '{{ mso_hostname }}'
- username: '{{ mso_username }}'
- password: '{{ mso_password }}'
- validate_certs: '{{ mso_validate_certs | default(false) }}'
- use_ssl: '{{ mso_use_ssl | default(true) }}'
- use_proxy: '{{ mso_use_proxy | default(true) }}'
- output_level: '{{ mso_output_level | default("info") }}'
- tenant: ansible_test
- display_name: Ansible test title
- description: Ansible test tenant
- state: present
- check_mode: yes
- register: cm_add_tenant
-
-- name: Verify cm_add_tenant
- assert:
- that:
- - cm_add_tenant is changed
- - cm_add_tenant.previous == {}
- - cm_add_tenant.current.id is not defined
- - cm_add_tenant.current.name == 'ansible_test'
- - cm_add_tenant.current.description == 'Ansible test tenant'
-
-- name: Add tenant (normal mode)
- mso_tenant: *tenant_present
- register: nm_add_tenant
-
-- name: nm_Verify add_tenant
- assert:
- that:
- - nm_add_tenant is changed
- - nm_add_tenant.previous == {}
- - nm_add_tenant.current.id is defined
- - nm_add_tenant.current.name == 'ansible_test'
- - nm_add_tenant.current.description == 'Ansible test tenant'
-
-- name: Add tenant again (check_mode)
- mso_tenant: *tenant_present
- check_mode: yes
- register: cm_add_tenant_again
-
-- name: Verify cm_add_tenant_again
- assert:
- that:
- - cm_add_tenant_again is not changed
- - cm_add_tenant_again.previous.name == 'ansible_test'
- - cm_add_tenant_again.previous.description == 'Ansible test tenant'
- - cm_add_tenant_again.current.id == nm_add_tenant.current.id
- - cm_add_tenant_again.current.name == 'ansible_test'
- - cm_add_tenant_again.current.description == 'Ansible test tenant'
-
-- name: Add tenant again (normal mode)
- mso_tenant: *tenant_present
- register: nm_add_tenant_again
-
-- name: Verify nm_add_tenant_again
- assert:
- that:
- - nm_add_tenant_again is not changed
- - nm_add_tenant_again.previous.name == 'ansible_test'
- - nm_add_tenant_again.previous.description == 'Ansible test tenant'
- - nm_add_tenant_again.current.id == nm_add_tenant.current.id
- - nm_add_tenant_again.current.name == 'ansible_test'
- - nm_add_tenant_again.current.description == 'Ansible test tenant'
-
-
-# CHANGE TENANT
-- name: Change tenant (check_mode)
- mso_tenant:
- <<: *tenant_present
- tenant_id: '{{ nm_add_tenant.current.id }}'
- tenant: ansible_test2
- description: Ansible test tenant 2
- check_mode: yes
- register: cm_change_tenant
-
-- name: Verify cm_change_tenant
- assert:
- that:
- - cm_change_tenant is changed
- - cm_change_tenant.current.id == nm_add_tenant.current.id
- - cm_change_tenant.current.name == 'ansible_test2'
- - cm_change_tenant.current.description == 'Ansible test tenant 2'
-
-- name: Change tenant (normal mode)
- mso_tenant:
- <<: *tenant_present
- tenant_id: '{{ nm_add_tenant.current.id }}'
- tenant: ansible_test2
- description: Ansible test tenant 2
- output_level: debug
- register: nm_change_tenant
-
-- name: Verify nm_change_tenant
- assert:
- that:
- - nm_change_tenant is changed
- - nm_change_tenant.current.id == nm_add_tenant.current.id
- - nm_change_tenant.current.name == 'ansible_test2'
- - nm_change_tenant.current.description == 'Ansible test tenant 2'
-
-- name: Change tenant again (check_mode)
- mso_tenant:
- <<: *tenant_present
- tenant_id: '{{ nm_add_tenant.current.id }}'
- tenant: ansible_test2
- description: Ansible test tenant 2
- check_mode: yes
- register: cm_change_tenant_again
-
-- name: Verify cm_change_tenant_again
- assert:
- that:
- - cm_change_tenant_again is not changed
- - cm_change_tenant_again.current.id == nm_add_tenant.current.id
- - cm_change_tenant_again.current.name == 'ansible_test2'
- - cm_change_tenant_again.current.description == 'Ansible test tenant 2'
-
-- name: Change tenant again (normal mode)
- mso_tenant:
- <<: *tenant_present
- tenant_id: '{{ nm_add_tenant.current.id }}'
- tenant: ansible_test2
- description: Ansible test tenant 2
- register: nm_change_tenant_again
-
-- name: Verify nm_change_tenant_again
- assert:
- that:
- - nm_change_tenant_again is not changed
- - nm_change_tenant_again.current.id == nm_add_tenant.current.id
- - nm_change_tenant_again.current.name == 'ansible_test2'
- - nm_change_tenant_again.current.description == 'Ansible test tenant 2'
-
-
-# QUERY ALL TENANTS
-- name: Query all tenants (check_mode)
- mso_tenant: &tenant_query
- host: '{{ mso_hostname }}'
- username: '{{ mso_username }}'
- password: '{{ mso_password }}'
- validate_certs: '{{ mso_validate_certs | default(false) }}'
- use_ssl: '{{ mso_use_ssl | default(true) }}'
- use_proxy: '{{ mso_use_proxy | default(true) }}'
- output_level: '{{ mso_output_level | default("info") }}'
- state: query
- check_mode: yes
- register: cm_query_all_tenants
-
-- name: Query all tenants (normal mode)
- mso_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
- mso_tenant:
- <<: *tenant_query
- tenant: ansible_test2
- check_mode: yes
- register: cm_query_tenant
-
-- name: Query our tenant
- mso_tenant:
- <<: *tenant_query
- tenant: ansible_test2
- register: nm_query_tenant
-
-- name: Verify query_tenant
- assert:
- that:
- - cm_query_tenant is not changed
- - cm_query_tenant.current.id == nm_add_tenant.current.id
- - cm_query_tenant.current.name == 'ansible_test2'
- - cm_query_tenant.current.description == 'Ansible test tenant 2'
- - nm_query_tenant is not changed
- - nm_query_tenant.current.id == nm_add_tenant.current.id
- - nm_query_tenant.current.name == 'ansible_test2'
- - nm_query_tenant.current.description == 'Ansible test tenant 2'
- - cm_query_tenant == nm_query_tenant
-
-
-# REMOVE TENANT
-- name: Remove tenant (check_mode)
- mso_tenant: *tenant_absent
- check_mode: yes
- register: cm_remove_tenant
-
-- name: Verify cm_remove_tenant
- assert:
- that:
- - cm_remove_tenant is changed
- - cm_remove_tenant.current == {}
-
-- name: Remove tenant (normal mode)
- mso_tenant: *tenant_absent
- register: nm_remove_tenant
-
-- name: Verify nm_remove_tenant
- assert:
- that:
- - nm_remove_tenant is changed
- - nm_remove_tenant.current == {}
-
-- name: Remove tenant again (check_mode)
- mso_tenant: *tenant_absent
- check_mode: yes
- register: cm_remove_tenant_again
-
-- name: Verify cm_remove_tenant_again
- assert:
- that:
- - cm_remove_tenant_again is not changed
- - cm_remove_tenant_again.current == {}
-
-- name: Remove tenant again (normal mode)
- mso_tenant: *tenant_absent
- register: nm_remove_tenant_again
-
-- name: Verify nm_remove_tenant_again
- assert:
- that:
- - nm_remove_tenant_again is not changed
- - nm_remove_tenant_again.current == {}
-
-
-# QUERY NON-EXISTING TENANT
-- name: Query non-existing tenant (check_mode)
- mso_tenant:
- <<: *tenant_query
- tenant: ansible_test
- check_mode: yes
- register: cm_query_non_tenant
-
-- name: Query non-existing tenant (normal mode)
- mso_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/mso_user/aliases b/test/integration/targets/mso_user/aliases
deleted file mode 100644
index cd28d3c362..0000000000
--- a/test/integration/targets/mso_user/aliases
+++ /dev/null
@@ -1,2 +0,0 @@
-# No ACI MultiSite infrastructure, so not enabled
-unsupported
diff --git a/test/integration/targets/mso_user/tasks/main.yml b/test/integration/targets/mso_user/tasks/main.yml
deleted file mode 100644
index 2bddd7ac34..0000000000
--- a/test/integration/targets/mso_user/tasks/main.yml
+++ /dev/null
@@ -1,292 +0,0 @@
-# Test code for the MSO 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 MultiSite host, username and password
- fail:
- msg: 'Please define the following variables: mso_hostname, mso_username and mso_password.'
- when: mso_hostname is not defined or mso_username is not defined or mso_password is not defined
-
-
-# CLEAN ENVIRONMENT
-- name: Remove user ansible_test2
- mso_user: &user_absent
- host: '{{ mso_hostname }}'
- username: '{{ mso_username }}'
- password: '{{ mso_password }}'
- validate_certs: '{{ mso_validate_certs | default(false) }}'
- use_ssl: '{{ mso_use_ssl | default(true) }}'
- use_proxy: '{{ mso_use_proxy | default(true) }}'
- output_level: '{{ mso_output_level | default("info") }}'
- user_name: ansible_test2
- state: absent
-
-- name: Remove user ansible_test
- mso_user:
- <<: *user_absent
- user_name: ansible_test
- register: cm_remove_user
-
-
-# ADD USER
-- name: Add user (check_mode)
- mso_user: &user_present
- host: '{{ mso_hostname }}'
- username: '{{ mso_username }}'
- password: '{{ mso_password }}'
- validate_certs: '{{ mso_validate_certs | default(false) }}'
- use_ssl: '{{ mso_use_ssl | default(true) }}'
- use_proxy: '{{ mso_use_proxy | default(true) }}'
- output_level: '{{ mso_output_level | default("info") }}'
- user_name: ansible_test
- user_password: 'S0m3!1n1t14l!p455w0rd'
- # NOTE: First name, last name, phone and email are mandatory on creation
- first_name: Ansible
- last_name: Test
- email: msc@cisco.com
- phone: +32 478 436 299
- account_status: active
- roles:
- - powerUser
- domain: Local
-
- state: present
- check_mode: yes
- register: cm_add_user
-
-- name: Verify cm_add_user
- assert:
- that:
- - cm_add_user is changed
- - cm_add_user.previous == {}
- - cm_add_user.current.id is not defined
- - cm_add_user.current.username == 'ansible_test'
-
-- name: Add user (normal mode)
- mso_user: *user_present
- register: nm_add_user
-
-- name: nm_Verify add_user
- assert:
- that:
- - nm_add_user is changed
- - nm_add_user.previous == {}
- - nm_add_user.current.id is defined
- - nm_add_user.current.username == 'ansible_test'
-
-- name: Add user again (check_mode)
- mso_user:
- <<: *user_present
- # NOTE: We need to modify the password for a new user
- user_password: 'S0m3!n3w!p455w0rd'
- check_mode: yes
- register: cm_add_user_again
-
-- name: Verify cm_add_user_again
- assert:
- that:
- - cm_add_user_again is changed
- - cm_add_user_again.previous.username == 'ansible_test'
- - cm_add_user_again.current.id == nm_add_user.current.id
- - cm_add_user_again.current.username == 'ansible_test'
-
-- name: Add user again (normal mode)
- mso_user:
- <<: *user_present
- # NOTE: We need to modify the password for a new user
- user_password: 'S0m3!n3w!p455w0rd'
- register: nm_add_user_again
-
-- name: Verify nm_add_user_again
- assert:
- that:
- - nm_add_user_again is changed
- - nm_add_user_again.previous.username == 'ansible_test'
- - nm_add_user_again.current.id == nm_add_user.current.id
- - nm_add_user_again.current.username == 'ansible_test'
-
-
-# CHANGE USER
-- name: Change user (check_mode)
- mso_user:
- <<: *user_present
- user_id: '{{ nm_add_user.current.id }}'
- user_name: ansible_test2
- user_password: null
- check_mode: yes
- register: cm_change_user
-
-- name: Verify cm_change_user
- assert:
- that:
- - cm_change_user is changed
- - cm_change_user.current.id == nm_add_user.current.id
- - cm_change_user.current.username == 'ansible_test2'
-
-- name: Change user (normal mode)
- mso_user:
- <<: *user_present
- user_id: '{{ nm_add_user.current.id }}'
- user_name: ansible_test2
- user_password: null
- output_level: debug
- register: nm_change_user
-
-- name: Verify nm_change_user
- assert:
- that:
- - nm_change_user is changed
- - nm_change_user.current.id == nm_add_user.current.id
- - nm_change_user.current.username == 'ansible_test2'
-
-- name: Change user again (check_mode)
- mso_user:
- <<: *user_present
- user_id: '{{ nm_add_user.current.id }}'
- user_name: ansible_test2
- user_password: null
- check_mode: yes
- register: cm_change_user_again
-
-- name: Verify cm_change_user_again
- assert:
- that:
- - cm_change_user_again is not changed
- - cm_change_user_again.current.id == nm_add_user.current.id
- - cm_change_user_again.current.username == 'ansible_test2'
-
-- name: Change user again (normal mode)
- mso_user:
- <<: *user_present
- user_id: '{{ nm_add_user.current.id }}'
- user_name: ansible_test2
- user_password: null
- register: nm_change_user_again
-
-- name: Verify nm_change_user_again
- assert:
- that:
- - nm_change_user_again is not changed
- - nm_change_user_again.current.id == nm_add_user.current.id
- - nm_change_user_again.current.username == 'ansible_test2'
-
-
-# QUERY ALL USERS
-- name: Query all users (check_mode)
- mso_user: &user_query
- host: '{{ mso_hostname }}'
- username: '{{ mso_username }}'
- password: '{{ mso_password }}'
- validate_certs: '{{ mso_validate_certs | default(false) }}'
- use_ssl: '{{ mso_use_ssl | default(true) }}'
- use_proxy: '{{ mso_use_proxy | default(true) }}'
- output_level: '{{ mso_output_level | default("info") }}'
- state: query
- check_mode: yes
- register: cm_query_all_users
-
-- name: Query all users (normal mode)
- mso_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 A USER
-- name: Query our user
- mso_user:
- <<: *user_query
- user_name: ansible_test2
- check_mode: yes
- register: cm_query_user
-
-- name: Query our user
- mso_user:
- <<: *user_query
- user_name: ansible_test2
- register: nm_query_user
-
-- name: Verify query_user
- assert:
- that:
- - cm_query_user is not changed
- - cm_query_user.current.id == nm_add_user.current.id
- - cm_query_user.current.username == 'ansible_test2'
- - nm_query_user is not changed
- - nm_query_user.current.id == nm_add_user.current.id
- - nm_query_user.current.username == 'ansible_test2'
- - cm_query_user == nm_query_user
-
-
-# REMOVE USER
-- name: Remove user (check_mode)
- mso_user: *user_absent
- check_mode: yes
- register: cm_remove_user
-
-- name: Verify cm_remove_user
- assert:
- that:
- - cm_remove_user is changed
- - cm_remove_user.current == {}
-
-- name: Remove user (normal mode)
- mso_user: *user_absent
- register: nm_remove_user
-
-- name: Verify nm_remove_user
- assert:
- that:
- - nm_remove_user is changed
- - nm_remove_user.current == {}
-
-- name: Remove user again (check_mode)
- mso_user: *user_absent
- check_mode: yes
- register: cm_remove_user_again
-
-- name: Verify cm_remove_user_again
- assert:
- that:
- - cm_remove_user_again is not changed
- - cm_remove_user_again.current == {}
-
-- name: Remove user again (normal mode)
- mso_user: *user_absent
- register: nm_remove_user_again
-
-- name: Verify nm_remove_user_again
- assert:
- that:
- - nm_remove_user_again is not changed
- - nm_remove_user_again.current == {}
-
-
-# QUERY NON-EXISTING USER
-- name: Query non-existing user (check_mode)
- mso_user:
- <<: *user_query
- user_name: ansible_test
- check_mode: yes
- register: cm_query_non_user
-
-- name: Query non-existing user (normal mode)
- mso_user:
- <<: *user_query
- user_name: ansible_test
- register: nm_query_non_user
-
-# TODO: Implement more tests
-- name: Verify query_non_user
- assert:
- that:
- - cm_query_non_user is not changed
- - nm_query_non_user is not changed
- - cm_query_non_user == nm_query_non_user
diff --git a/test/sanity/ignore.txt b/test/sanity/ignore.txt
index bec92ee02d..4e163869ff 100644
--- a/test/sanity/ignore.txt
+++ b/test/sanity/ignore.txt
@@ -1456,34 +1456,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/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
-lib/ansible/modules/network/aci/mso_schema.py validate-modules:doc-required-mismatch
-lib/ansible/modules/network/aci/mso_schema.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/network/aci/mso_schema_site.py validate-modules:doc-required-mismatch
-lib/ansible/modules/network/aci/mso_schema_site_anp_epg.py validate-modules:doc-required-mismatch
-lib/ansible/modules/network/aci/mso_schema_site_anp_epg_domain.py pylint:ansible-bad-function
-lib/ansible/modules/network/aci/mso_schema_site_anp_epg_domain.py validate-modules:doc-required-mismatch
-lib/ansible/modules/network/aci/mso_schema_site_anp_epg_staticleaf.py validate-modules:doc-required-mismatch
-lib/ansible/modules/network/aci/mso_schema_site_anp_epg_staticport.py validate-modules:doc-required-mismatch
-lib/ansible/modules/network/aci/mso_schema_site_anp_epg_subnet.py validate-modules:doc-required-mismatch
-lib/ansible/modules/network/aci/mso_schema_site_bd_l3out.py validate-modules:doc-required-mismatch
-lib/ansible/modules/network/aci/mso_schema_site_vrf_region.py validate-modules:doc-required-mismatch
-lib/ansible/modules/network/aci/mso_schema_site_vrf_region_cidr.py validate-modules:doc-required-mismatch
-lib/ansible/modules/network/aci/mso_schema_site_vrf_region_cidr_subnet.py validate-modules:doc-required-mismatch
-lib/ansible/modules/network/aci/mso_schema_template_anp_epg.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/network/aci/mso_schema_template_bd.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/network/aci/mso_schema_template_contract_filter.py validate-modules:invalid-ansiblemodule-schema
-lib/ansible/modules/network/aci/mso_schema_template_contract_filter.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/network/aci/mso_schema_template_deploy.py validate-modules:doc-required-mismatch
-lib/ansible/modules/network/aci/mso_schema_template_filter_entry.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/network/aci/mso_site.py validate-modules:doc-required-mismatch
-lib/ansible/modules/network/aci/mso_site.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/network/aci/mso_tenant.py validate-modules:doc-required-mismatch
-lib/ansible/modules/network/aci/mso_tenant.py validate-modules:parameter-list-no-elements
-lib/ansible/modules/network/aci/mso_user.py validate-modules:doc-required-mismatch
-lib/ansible/modules/network/aci/mso_user.py validate-modules:parameter-list-no-elements
lib/ansible/modules/network/dellos10/dellos10_command.py validate-modules:doc-default-does-not-match-spec
lib/ansible/modules/network/dellos10/dellos10_command.py validate-modules:doc-missing-type
lib/ansible/modules/network/dellos10/dellos10_command.py validate-modules:doc-required-mismatch