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_template_filter_entry.py
Go to the documentation of this file.
1#!/usr/bin/python
2# -*- coding: utf-8 -*-
3
4# Copyright: (c) 2018, 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_template_filter_entry
17short_description: Manage filter entries in schema templates
18description:
19- Manage filter entries in schema templates 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 template:
30 description:
31 - The name of the template.
32 type: str
33 required: yes
34 filter:
35 description:
36 - The name of the filter to manage.
37 type: str
38 required: yes
39 filter_display_name:
40 description:
41 - The name as displayed on the MSO web interface.
42 type: str
43 entry:
44 description:
45 - The filter entry name to manage.
46 type: str
47 aliases: [ name ]
48 display_name:
49 description:
50 - The name as displayed on the MSO web interface.
51 type: str
52 aliases: [ entry_display_name ]
53 description:
54 description:
55 - The description of this filer entry.
56 type: str
57 aliases: [ entry_description ]
58 ethertype:
59 description:
60 - The ethernet type to use for this filter entry.
61 type: str
62 choices: [ arp, fcoe, ip, ipv4, ipv6, mac-security, mpls-unicast, trill, unspecified ]
63 ip_protocol:
64 description:
65 - The IP protocol to use for this filter entry.
66 type: str
67 choices: [ eigrp, egp, icmp, icmpv6, igmp, igp, l2tp, ospfigp, pim, tcp, udp, unspecified ]
68 tcp_session_rules:
69 description:
70 - A list of TCP session rules.
71 type: list
72 choices: [ acknowledgement, established, finish, synchronize, reset, unspecified ]
73 source_from:
74 description:
75 - The source port range from.
76 type: str
77 source_to:
78 description:
79 - The source port range to.
80 type: str
81 destination_from:
82 description:
83 - The destination port range from.
84 type: str
85 destination_to:
86 description:
87 - The destination port range to.
88 type: str
89 arp_flag:
90 description:
91 - The ARP flag to use for this filter entry.
92 type: str
93 choices: [ reply, request, unspecified ]
94 stateful:
95 description:
96 - Whether this filter entry is stateful.
97 type: bool
98 default: no
99 fragments_only:
100 description:
101 - Whether this filter entry only matches fragments.
102 type: bool
103 default: no
104 state:
105 description:
106 - Use C(present) or C(absent) for adding or removing.
107 - Use C(query) for listing an object or multiple objects.
108 type: str
109 choices: [ absent, present, query ]
110 default: present
111seealso:
112- module: mso_schema_template_contract_filter
113notes:
114- Due to restrictions of the MSO REST API this module creates filters when needed, and removes them when the last entry has been removed.
115extends_documentation_fragment: mso
116'''
117
118EXAMPLES = r'''
119- name: Add a new filter entry
120 mso_schema_template_filter_entry:
121 host: mso_host
122 username: admin
123 password: SomeSecretPassword
124 schema: Schema 1
125 template: Template 1
126 filter: Filter 1
127 state: present
128 delegate_to: localhost
129
130- name: Remove a filter entry
131 mso_schema_template_filter_entry:
132 host: mso_host
133 username: admin
134 password: SomeSecretPassword
135 schema: Schema 1
136 template: Template 1
137 filter: Filter 1
138 state: absent
139 delegate_to: localhost
140
141- name: Query a specific filter entry
142 mso_schema_template_filter_entry:
143 host: mso_host
144 username: admin
145 password: SomeSecretPassword
146 schema: Schema 1
147 template: Template 1
148 filter: Filter 1
149 state: query
150 delegate_to: localhost
151 register: query_result
152
153- name: Query all filter entries
154 mso_schema_template_filter_entry:
155 host: mso_host
156 username: admin
157 password: SomeSecretPassword
158 schema: Schema 1
159 template: Template 1
160 state: query
161 delegate_to: localhost
162 register: query_result
163'''
164
165RETURN = r'''
166'''
167
168from ansible.module_utils.basic import AnsibleModule
169from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec, mso_reference_spec, issubset
170
171
172def main():
173 argument_spec = mso_argument_spec()
174 argument_spec.update(
175 schema=dict(type='str', required=True),
176 template=dict(type='str', required=True),
177 filter=dict(type='str', required=True),
178 filter_display_name=dict(type='str'),
179 entry=dict(type='str', aliases=['name']), # This parameter is not required for querying all objects
180 description=dict(type='str', aliases=['entry_description']),
181 display_name=dict(type='str', aliases=['entry_display_name']),
182 ethertype=dict(type='str', choices=['arp', 'fcoe', 'ip', 'ipv4', 'ipv6', 'mac-security', 'mpls-unicast', 'trill', 'unspecified']),
183 ip_protocol=dict(type='str', choices=['eigrp', 'egp', 'icmp', 'icmpv6', 'igmp', 'igp', 'l2tp', 'ospfigp', 'pim', 'tcp', 'udp', 'unspecified']),
184 tcp_session_rules=dict(type='list', choices=['acknowledgement', 'established', 'finish', 'synchronize', 'reset', 'unspecified']),
185 source_from=dict(type='str'),
186 source_to=dict(type='str'),
187 destination_from=dict(type='str'),
188 destination_to=dict(type='str'),
189 arp_flag=dict(type='str', choices=['reply', 'request', 'unspecified']),
190 stateful=dict(type='bool'),
191 fragments_only=dict(type='bool'),
192 state=dict(type='str', default='present', choices=['absent', 'present', 'query']),
193 )
194
195 module = AnsibleModule(
196 argument_spec=argument_spec,
197 supports_check_mode=True,
198 required_if=[
199 ['state', 'absent', ['entry']],
200 ['state', 'present', ['entry']],
201 ],
202 )
203
204 schema = module.params['schema']
205 template = module.params['template']
206 filter_name = module.params['filter']
207 filter_display_name = module.params['filter_display_name']
208 entry = module.params['entry']
209 display_name = module.params['display_name']
210 description = module.params['description']
211 ethertype = module.params['ethertype']
212 ip_protocol = module.params['ip_protocol']
213 tcp_session_rules = module.params['tcp_session_rules']
214 source_from = module.params['source_from']
215 source_to = module.params['source_to']
216 destination_from = module.params['destination_from']
217 destination_to = module.params['destination_to']
218 arp_flag = module.params['arp_flag']
219 stateful = module.params['stateful']
220 fragments_only = module.params['fragments_only']
221 state = module.params['state']
222
223 mso = MSOModule(module)
224
225 # Get schema
226 schema_obj = mso.get_obj('schemas', displayName=schema)
227 if not schema_obj:
228 mso.fail_json(msg="Provided schema '{0}' does not exist".format(schema))
229
230 schema_path = 'schemas/{id}'.format(**schema_obj)
231
232 # Get template
233 templates = [t['name'] for t in schema_obj['templates']]
234 if template not in templates:
235 mso.fail_json(msg="Provided template '{template}' does not exist. Existing templates: {templates}".format(template=template,
236 templates=', '.join(templates)))
237 template_idx = templates.index(template)
238
239 # Get filters
240 mso.existing = {}
241 filter_idx = None
242 entry_idx = None
243 filters = [f['name'] for f in schema_obj['templates'][template_idx]['filters']]
244 if filter_name in filters:
245 filter_idx = filters.index(filter_name)
246
247 entries = [f['name'] for f in schema_obj['templates'][template_idx]['filters'][filter_idx]['entries']]
248 if entry in entries:
249 entry_idx = entries.index(entry)
250 mso.existing = schema_obj['templates'][template_idx]['filters'][filter_idx]['entries'][entry_idx]
251
252 if state == 'query':
253 if entry is None:
254 if filter_idx is None:
255 mso.fail_json(msg="Filter '{filter}' not found".format(filter=filter_name))
256 mso.existing = schema_obj['templates'][template_idx]['filters'][filter_idx]['entries']
257 elif not mso.existing:
258 mso.fail_json(msg="Entry '{entry}' not found".format(entry=entry))
259 mso.exit_json()
260
261 filters_path = '/templates/{0}/filters'.format(template)
262 filter_path = '/templates/{0}/filters/{1}'.format(template, filter_name)
263 entries_path = '/templates/{0}/filters/{1}/entries'.format(template, filter_name)
264 entry_path = '/templates/{0}/filters/{1}/entries/{2}'.format(template, filter_name, entry)
265 ops = []
266
267 mso.previous = mso.existing
268 if state == 'absent':
269 mso.proposed = mso.sent = {}
270
271 if filter_idx is None:
272 # There was no filter to begin with
273 pass
274 elif entry_idx is None:
275 # There was no entry to begin with
276 pass
277 elif len(entries) == 1:
278 # There is only one entry, remove filter
279 mso.existing = {}
280 ops.append(dict(op='remove', path=filter_path))
281
282 else:
283 mso.existing = {}
284 ops.append(dict(op='remove', path=entry_path))
285
286 elif state == 'present':
287
288 if not mso.existing:
289 if display_name is None:
290 display_name = entry
291 if description is None:
292 description = ''
293 if ethertype is None:
294 ethertype = 'unspecified'
295 if ip_protocol is None:
296 ip_protocol = 'unspecified'
297 if tcp_session_rules is None:
298 tcp_session_rules = ['unspecified']
299 if source_from is None:
300 source_from = 'unspecified'
301 if source_to is None:
302 source_to = 'unspecified'
303 if destination_from is None:
304 destination_from = 'unspecified'
305 if destination_to is None:
306 destination_to = 'unspecified'
307 if arp_flag is None:
308 arp_flag = 'unspecified'
309 if stateful is None:
310 stateful = False
311 if fragments_only is None:
312 fragments_only = False
313
314 payload = dict(
315 name=entry,
316 displayName=display_name,
317 description=description,
318 etherType=ethertype,
319 ipProtocol=ip_protocol,
320 tcpSessionRules=tcp_session_rules,
321 sourceFrom=source_from,
322 sourceTo=source_to,
323 destinationFrom=destination_from,
324 destinationTo=destination_to,
325 arpFlag=arp_flag,
326 stateful=stateful,
327 matchOnlyFragments=fragments_only,
328 )
329
330 mso.sanitize(payload, collate=True)
331
332 if filter_idx is None:
333 # Filter does not exist, so we have to create it
334 if filter_display_name is None:
335 filter_display_name = filter_name
336
337 payload = dict(
338 name=filter_name,
339 displayName=filter_display_name,
340 entries=[mso.sent],
341 )
342
343 ops.append(dict(op='add', path=filters_path + '/-', value=payload))
344
345 elif entry_idx is None:
346 # Entry does not exist, so we have to add it
347 ops.append(dict(op='add', path=entries_path + '/-', value=mso.sent))
348
349 else:
350 # Entry exists, we have to update it
351 for (key, value) in mso.sent.items():
352 ops.append(dict(op='replace', path=entry_path + '/' + key, value=value))
353
354 mso.existing = mso.proposed
355
356 if not module.check_mode:
357 mso.request(schema_path, method='PATCH', data=ops)
358
359 mso.exit_json()
360
361
362if __name__ == "__main__":
363 main()
def main()