mso_schema_site: Add sites to a schema template (#51332)

A new module to associate sites to schema templates
This commit is contained in:
Dag Wieers 2019-01-25 15:27:55 +01:00 committed by GitHub
parent b9f5a343c4
commit b7ec254816
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 225 additions and 11 deletions

View file

@ -281,7 +281,7 @@ class MSOModule(object):
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 '%s': %s" % (schema, s))
self.module.fail_json(msg="Schema lookup failed for schema '%s': %s" % (schema, s))
return s['id']
def lookup_domain(self, domain):
@ -293,7 +293,7 @@ class MSOModule(object):
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 '%s': %s" % (domain, d))
self.module.fail_json(msg="Domain lookup failed for domain '%s': %s" % (domain, d))
return d['id']
def lookup_roles(self, roles):
@ -305,12 +305,24 @@ class MSOModule(object):
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." % role)
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 '%s': %s" % (role, r))
self.module.fail_json(msg="Role lookup failed for role '%s': %s" % (role, r))
ids.append(dict(roleId=r['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['id']
def lookup_sites(self, sites):
''' Look up sites and return their ids '''
if sites is None:
@ -320,9 +332,9 @@ class MSOModule(object):
for site in sites:
s = self.get_obj('sites', name=site)
if not s:
self.module.fail_json(msg="Site '%s' is not valid." % site)
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 '%s': %s" % (site, s))
self.module.fail_json(msg="Site lookup failed for site '%s': %s" % (site, s))
ids.append(dict(siteId=s['id'], securityDomains=[]))
return ids
@ -333,9 +345,9 @@ class MSOModule(object):
t = self.get_obj('tenants', key='tenants', name=tenant)
if not t:
self.module.fail_json(msg="Tenant '%s' is not valid." % tenant)
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 '%s': %s" % (tenant, t))
self.module.fail_json(msg="Tenant lookup failed for tenant '%s': %s" % (tenant, t))
return t['id']
def lookup_users(self, users):
@ -347,9 +359,9 @@ class MSOModule(object):
for user in users:
u = self.get_obj('users', username=user)
if not u:
self.module.fail_json(msg="User '%s' is not valid." % user)
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 '%s': %s" % (user, u))
self.module.fail_json(msg="User lookup failed for user '%s': %s" % (user, u))
ids.append(dict(userId=u['id']))
return ids
@ -368,7 +380,7 @@ class MSOModule(object):
if not l:
l = self.create_label(label, label_type)
if 'id' not in l:
self.module.fail_json(msg="Label lookup failed for '%s': %s" % (label, l))
self.module.fail_json(msg="Label lookup failed for label '%s': %s" % (label, l))
ids.append(l['id'])
return ids

View file

@ -1,6 +1,7 @@
#!/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

View file

@ -0,0 +1,200 @@
#!/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:
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:
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:
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', required=False, aliases=['name']),
template=dict(type='str', required=False),
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['schema']
site = module.params['site']
template = module.params['template']
state = module.params['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_id = schema_obj['id']
schema_path = 'schemas/{id}'.format(**schema_obj)
# Get site
site_id = mso.lookup_site(site)
mso.existing = {}
if 'sites' in schema_obj:
sites = [(s['siteId'], s['templateName']) for s in schema_obj['sites']]
if template:
if (site_id, template) in sites:
site_idx = sites.index((site_id, template))
mso.existing = schema_obj['sites'][site_idx]
else:
mso.existing = schema_obj['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()
ops = []
mso.previous = mso.existing
if state == 'absent':
mso.proposed = mso.sent = {}
if mso.existing:
# Remove existing site
mso.existing = {}
ops.append(dict(op='remove', path='/sites/{0}'.format(site_idx)))
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)
mso.existing = mso.proposed = mso.sent
ops.append(dict(op='add', path='/sites/-', value=mso.sent))
if not module.check_mode:
mso.request(schema_path, method='PATCH', data=ops)
mso.exit_json()
if __name__ == "__main__":
main()

View file

@ -1,6 +1,7 @@
#!/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