ansible  2.9.27
About: Ansible is an IT Configuration Management, Deployment \
About: Ansible (2.x) is an IT Configuration Management, Deployment & Orchestration tool.
ansible download page.
  Fossies Dox: ansible-2.9.27.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

mso_schema_site_vrf_region_cidr.py
Go to the documentation of this file.
1#!/usr/bin/python
2# -*- coding: utf-8 -*-
3
4# Copyright: (c) 2019, Dag Wieers (@dagwieers) <dag@wieers.com>
5# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
6
7from __future__ import absolute_import, division, print_function
8__metaclass__ = type
9
10ANSIBLE_METADATA = {'metadata_version': '1.1',
11 'status': ['preview'],
12 'supported_by': 'community'}
13
14DOCUMENTATION = r'''
15---
16module: mso_schema_site_vrf_region_cidr
17short_description: Manage site-local VRF region CIDRs in schema template
18description:
19- Manage site-local VRF region CIDRs in schema template on Cisco ACI Multi-Site.
20author:
21- Dag Wieers (@dagwieers)
22version_added: '2.8'
23options:
24 schema:
25 description:
26 - The name of the schema.
27 type: str
28 required: yes
29 site:
30 description:
31 - The name of the site.
32 type: str
33 required: yes
34 template:
35 description:
36 - The name of the template.
37 type: str
38 required: yes
39 vrf:
40 description:
41 - The name of the VRF.
42 type: str
43 region:
44 description:
45 - The name of the region.
46 type: str
47 cidr:
48 description:
49 - The name of the region CIDR to manage.
50 type: str
51 aliases: [ ip ]
52 primary:
53 description:
54 - Whether this is the primary CIDR.
55 type: bool
56 state:
57 description:
58 - Use C(present) or C(absent) for adding or removing.
59 - Use C(query) for listing an object or multiple objects.
60 type: str
61 choices: [ absent, present, query ]
62 default: present
63notes:
64- The ACI MultiSite PATCH API has a deficiency requiring some objects to be referenced by index.
65 This can cause silent corruption on concurrent access when changing/removing on object as
66 the wrong object may be referenced. This module is affected by this deficiency.
67seealso:
68- module: mso_schema_site_vrf_region
69- module: mso_schema_site_vrf_region_cidr_subnet
70- module: mso_schema_template_vrf
71extends_documentation_fragment: mso
72'''
73
74EXAMPLES = r'''
75- name: Add a new site VRF region CIDR
76 mso_schema_template_vrf_region_cidr:
77 host: mso_host
78 username: admin
79 password: SomeSecretPassword
80 schema: Schema1
81 site: Site1
82 template: Template1
83 vrf: VRF1
84 region: us-west-1
85 cidr: 14.14.14.1/24
86 state: present
87 delegate_to: localhost
88
89- name: Remove a site VRF region CIDR
90 mso_schema_template_vrf_region_cidr:
91 host: mso_host
92 username: admin
93 password: SomeSecretPassword
94 schema: Schema1
95 site: Site1
96 template: Template1
97 vrf: VRF1
98 region: us-west-1
99 cidr: 14.14.14.1/24
100 state: absent
101 delegate_to: localhost
102
103- name: Query a specific site VRF region CIDR
104 mso_schema_template_vrf_region_cidr:
105 host: mso_host
106 username: admin
107 password: SomeSecretPassword
108 schema: Schema1
109 site: Site1
110 template: Template1
111 vrf: VRF1
112 region: us-west-1
113 cidr: 14.14.14.1/24
114 state: query
115 delegate_to: localhost
116 register: query_result
117
118- name: Query all site VRF region CIDR
119 mso_schema_template_vrf_region_cidr:
120 host: mso_host
121 username: admin
122 password: SomeSecretPassword
123 schema: Schema1
124 site: Site1
125 template: Template1
126 vrf: VRF1
127 region: us-west-1
128 state: query
129 delegate_to: localhost
130 register: query_result
131'''
132
133RETURN = r'''
134'''
135
136from ansible.module_utils.basic import AnsibleModule
137from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec
138
139
140def main():
141 argument_spec = mso_argument_spec()
142 argument_spec.update(
143 schema=dict(type='str', required=True),
144 site=dict(type='str', required=True),
145 template=dict(type='str', required=True),
146 vrf=dict(type='str', required=True),
147 region=dict(type='str', required=True),
148 cidr=dict(type='str', aliases=['ip']), # This parameter is not required for querying all objects
149 primary=dict(type='bool'),
150 state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
151 )
152
153 module = AnsibleModule(
154 argument_spec=argument_spec,
155 supports_check_mode=True,
156 required_if=[
157 ['state', 'absent', ['cidr']],
158 ['state', 'present', ['cidr']],
159 ],
160 )
161
162 schema = module.params['schema']
163 site = module.params['site']
164 template = module.params['template']
165 vrf = module.params['vrf']
166 region = module.params['region']
167 cidr = module.params['cidr']
168 primary = module.params['primary']
169 state = module.params['state']
170
171 mso = MSOModule(module)
172
173 # Get schema_id
174 schema_obj = mso.get_obj('schemas', displayName=schema)
175 if not schema_obj:
176 mso.fail_json(msg="Provided schema '{0}' does not exist".format(schema))
177
178 schema_path = 'schemas/{id}'.format(**schema_obj)
179 schema_id = schema_obj['id']
180
181 # Get site
182 site_id = mso.lookup_site(site)
183
184 # Get site_idx
185 sites = [(s['siteId'], s['templateName']) for s in schema_obj['sites']]
186 if (site_id, template) not in sites:
187 mso.fail_json(msg="Provided site/template '{0}-{1}' does not exist. Existing sites/templates: {2}".format(site, template, ', '.join(sites)))
188
189 # Schema-access uses indexes
190 site_idx = sites.index((site_id, template))
191 # Path-based access uses site_id-template
192 site_template = '{0}-{1}'.format(site_id, template)
193
194 # Get VRF
195 vrf_ref = mso.vrf_ref(schema_id=schema_id, template=template, vrf=vrf)
196 vrfs = [v['vrfRef'] for v in schema_obj['sites'][site_idx]['vrfs']]
197 if vrf_ref not in vrfs:
198 mso.fail_json(msg="Provided vrf '{0}' does not exist. Existing vrfs: {1}".format(vrf, ', '.join(vrfs)))
199 vrf_idx = vrfs.index(vrf_ref)
200
201 # Get Region
202 regions = [r['name'] for r in schema_obj['sites'][site_idx]['vrfs'][vrf_idx]['regions']]
203 if region not in regions:
204 mso.fail_json(msg="Provided region '{0}' does not exist. Existing regions: {1}".format(region, ', '.join(regions)))
205 region_idx = regions.index(region)
206
207 # Get CIDR
208 cidrs = [c['ip'] for c in schema_obj['sites'][site_idx]['vrfs'][vrf_idx]['regions'][region_idx]['cidrs']]
209 if cidr is not None and cidr in cidrs:
210 cidr_idx = cidrs.index(cidr)
211 # FIXME: Changes based on index are DANGEROUS
212 cidr_path = '/sites/{0}/vrfs/{1}/regions/{2}/cidrs/{3}'.format(site_template, vrf, region, cidr_idx)
213 mso.existing = schema_obj['sites'][site_idx]['vrfs'][vrf_idx]['regions'][region_idx]['cidrs'][cidr_idx]
214
215 if state == 'query':
216 if cidr is None:
217 mso.existing = schema_obj['sites'][site_idx]['vrfs'][vrf_idx]['regions'][region_idx]['cidrs']
218 elif not mso.existing:
219 mso.fail_json(msg="CIDR IP '{cidr}' not found".format(cidr=cidr))
220 mso.exit_json()
221
222 cidrs_path = '/sites/{0}/vrfs/{1}/regions/{2}/cidrs'.format(site_template, vrf, region)
223 ops = []
224
225 mso.previous = mso.existing
226 if state == 'absent':
227 if mso.existing:
228 mso.sent = mso.existing = {}
229 ops.append(dict(op='remove', path=cidr_path))
230
231 elif state == 'present':
232 if not mso.existing:
233 if primary is None:
234 primary = False
235
236 payload = dict(
237 ip=cidr,
238 primary=primary,
239 )
240
241 mso.sanitize(payload, collate=True)
242
243 if mso.existing:
244 ops.append(dict(op='replace', path=cidr_path, value=mso.sent))
245 else:
246 ops.append(dict(op='add', path=cidrs_path + '/-', value=mso.sent))
247
248 mso.existing = mso.proposed
249
250 if not module.check_mode:
251 mso.request(schema_path, method='PATCH', data=ops)
252
253 mso.exit_json()
254
255
256if __name__ == "__main__":
257 main()