7from __future__
import absolute_import, division, print_function
10ANSIBLE_METADATA = {
'metadata_version':
'1.1',
11 'status': [
'preview'],
12 'supported_by':
'community'}
16module: mso_schema_template_contract_filter
17short_description: Manage contract filters in schema templates
19- Manage contract filters in schema templates on Cisco ACI Multi-Site.
21- Dag Wieers (@dagwieers)
26 - The name of the schema.
31 - The name of the template.
36 - The name of the contract to manage.
39 contract_display_name:
41 - The name as displayed on the MSO web interface.
42 - This defaults to the contract name when unset on creation.
46 - The type of filters defined
in this contract.
47 - This defaults to C(both-way) when unset on creation.
49 choices: [ both-way, one-way ]
52 - The scope of the contract.
53 - This defaults to C(vrf) when unset on creation.
55 choices: [ application-profile,
global, tenant, vrf ]
58 - The filter to associate
with this contract.
63 - The template name
in which the filter
is located.
67 - The schema name
in which the filter
is located.
71 - The type of filter to manage.
73 choices: [ both-way, consumer-to-provider, provider-to-consumer ]
78 - A list of filter directives.
80 choices: [ log, none ]
83 - Use C(present)
or C(absent)
for adding
or removing.
84 - Use C(query)
for listing an object
or multiple objects.
86 choices: [ absent, present, query ]
89- module: mso_schema_template_filter_entry
91- Due to restrictions of the MSO REST API this module creates contracts when needed,
and removes them when the last filter has been removed.
92- Due to restrictions of the MSO REST API concurrent modifications to contract filters can be dangerous
and corrupt data.
93extends_documentation_fragment: mso
97- name: Add a new contract filter
98 mso_schema_template_contract_filter:
101 password: SomeSecretPassword
105 contract_scope: global
108 delegate_to: localhost
110- name: Remove a contract filter
111 mso_schema_template_contract_filter:
114 password: SomeSecretPassword
120 delegate_to: localhost
122- name: Query a specific contract filter
123 mso_schema_template_contract_filter:
126 password: SomeSecretPassword
132 delegate_to: localhost
133 register: query_result
135- name: Query all contract filters
136 mso_schema_template_contract_filter:
139 password: SomeSecretPassword
144 delegate_to: localhost
145 register: query_result
151from ansible.module_utils.basic import AnsibleModule
152from ansible.module_utils.network.aci.mso import MSOModule, mso_argument_spec, mso_reference_spec, issubset
155 'both-way':
'filterRelationships',
156 'consumer-to-provider':
'filterRelationshipsConsumerToProvider',
157 'provider-to-consumer':
'filterRelationshipsProviderToConsumer',
163 argument_spec.update(
164 schema=dict(type=
'str', required=
True),
165 template=dict(type=
'str', required=
True),
166 contract=dict(type=
'str', required=
True),
167 contract_display_name=dict(type=
'str'),
168 contract_scope=dict(type=
'str', choices=[
'application-profile',
'global',
'tenant',
'vrf']),
169 contract_filter_type=dict(type=
'str', choices=[
'both-way',
'one-way']),
170 filter=dict(type=
'str', aliases=[
'name']),
171 filter_directives=dict(type=
'list', choices=[
'log',
'none']),
172 filter_template=dict(type=
'str'),
173 filter_schema=dict(type=
'str'),
174 filter_type=dict(type=
'str', default=
'both-way', choices=FILTER_KEYS.keys(), aliases=[
'type']),
175 state=dict(type=
'str', default=
'present', choices=[
'absent',
'present',
'query']),
179 argument_spec=argument_spec,
180 supports_check_mode=
True,
182 [
'state',
'absent', [
'filter']],
183 [
'state',
'present', [
'filter']],
187 schema = module.params[
'schema']
188 template = module.params[
'template']
189 contract = module.params[
'contract']
190 contract_display_name = module.params[
'contract_display_name']
191 contract_filter_type = module.params[
'contract_filter_type']
192 contract_scope = module.params[
'contract_scope']
193 filter_name = module.params[
'filter']
194 filter_directives = module.params[
'filter_directives']
195 filter_template = module.params[
'filter_template']
196 filter_schema = module.params[
'filter_schema']
197 filter_type = module.params[
'filter_type']
198 state = module.params[
'state']
200 contract_ftype =
'bothWay' if contract_filter_type ==
'both-way' else 'oneWay'
202 if contract_filter_type ==
'both-way' and filter_type !=
'both-way':
203 module.warn(
"You are adding 'one-way' filters to a 'both-way' contract")
204 elif contract_filter_type !=
'both-way' and filter_type ==
'both-way':
205 module.warn(
"You are adding 'both-way' filters to a 'one-way' contract")
207 if filter_template
is None:
208 filter_template = template
210 if filter_schema
is None:
211 filter_schema = schema
213 filter_key = FILTER_KEYS[filter_type]
217 filter_schema_id = mso.lookup_schema(filter_schema)
220 schema_obj = mso.get_obj(
'schemas', displayName=schema)
222 schema_id = schema_obj[
'id']
224 mso.fail_json(msg=
"Provided schema '{0}' does not exist".
format(schema))
226 schema_path =
'schemas/{id}'.
format(**schema_obj)
229 templates = [t[
'name']
for t
in schema_obj[
'templates']]
230 if template
not in templates:
231 mso.fail_json(msg=
"Provided template '{0}' does not exist. Existing templates: {1}".
format(template,
', '.join(templates)))
232 template_idx = templates.index(template)
238 contracts = [c[
'name']
for c
in schema_obj[
'templates'][template_idx][
'contracts']]
240 if contract
in contracts:
241 contract_idx = contracts.index(contract)
243 filters = [f[
'filterRef']
for f
in schema_obj[
'templates'][template_idx][
'contracts'][contract_idx][filter_key]]
244 filter_ref = mso.filter_ref(schema_id=filter_schema_id, template=filter_template, filter=filter_name)
245 if filter_ref
in filters:
246 filter_idx = filters.index(filter_ref)
247 filter_path =
'/templates/{0}/contracts/{1}/{2}/{3}'.
format(template, contract, filter_key, filter_name)
248 mso.existing = schema_obj[
'templates'][template_idx][
'contracts'][contract_idx][filter_key][filter_idx]
251 if contract_idx
is None:
252 mso.fail_json(msg=
"Provided contract '{0}' does not exist. Existing contracts: {1}".
format(contract,
', '.join(contracts)))
254 if filter_name
is None:
255 mso.existing = schema_obj[
'templates'][template_idx][
'contracts'][contract_idx][filter_key]
256 elif not mso.existing:
257 mso.fail_json(msg=
"FilterRef '{filter_ref}' not found".
format(filter_ref=filter_ref))
261 contract_path =
'/templates/{0}/contracts/{1}'.
format(template, contract)
262 filters_path =
'/templates/{0}/contracts/{1}/{2}'.
format(template, contract, filter_key)
264 mso.previous = mso.existing
265 if state ==
'absent':
266 mso.proposed = mso.sent = {}
268 if contract_idx
is None:
271 elif filter_idx
is None:
274 elif len(filters) == 1:
277 ops.append(dict(op=
'remove', path=contract_path))
281 ops.append(dict(op=
'remove', path=filter_path))
283 elif state ==
'present':
284 if filter_directives
is None:
285 filter_directives = [
'none']
289 filterName=filter_name,
290 templateName=filter_template,
291 schemaId=filter_schema_id,
293 directives=filter_directives,
296 mso.sanitize(payload, collate=
True)
297 mso.existing = mso.sent
299 if contract_idx
is None:
301 if contract_display_name
is None:
302 contract_display_name = contract
303 if contract_filter_type
is None:
304 contract_ftype =
'bothWay'
305 if contract_scope
is None:
306 contract_scope =
'context'
310 'displayName': contract_display_name,
311 'filterType': contract_ftype,
312 'scope': contract_scope,
315 ops.append(dict(op=
'add', path=
'/templates/{0}/contracts/-'.
format(template), value=payload))
318 if contract_display_name
is not None:
319 ops.append(dict(op=
'replace', path=contract_path +
'/displayName', value=contract_display_name))
320 if contract_filter_type
is not None:
321 ops.append(dict(op=
'replace', path=contract_path +
'/filterType', value=contract_ftype))
322 if contract_scope
is not None:
323 ops.append(dict(op=
'replace', path=contract_path +
'/scope', value=contract_scope))
325 if filter_idx
is None:
327 ops.append(dict(op=
'add', path=filters_path +
'/-', value=mso.sent))
331 ops.append(dict(op=
'replace', path=filter_path, value=mso.sent))
333 if not module.check_mode:
334 mso.request(schema_path, method=
'PATCH', data=ops)
339if __name__ ==
"__main__":