mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-05-07 22:02:50 +00:00
ACI: Make querying links and nodes possible (#43441)
This functionality was not considered when the module was written, but there's no reason why it shouldn't be supported. We had to rework the query string construction and object filtering. This new functionality allows to filter on arbitrary keys and supports None values. This PR fixes various issues with the existing framework, including querying specific objects using construct_url_4 (i.e. aci_epg_to_contract and aci_static_binding_to_epg)
This commit is contained in:
@@ -78,46 +78,6 @@ def aci_argument_spec():
|
||||
)
|
||||
|
||||
|
||||
'''
|
||||
URL_MAPPING = dict(
|
||||
action_rule=dict(aci_class='rtctrlAttrP', mo='attr-', key='name'),
|
||||
aep=dict(aci_class='infraAttEntityP', mo='infra/attentp-', key='name'),
|
||||
ap=dict(aci_class='fvAp', mo='ap-', key='name'),
|
||||
bd=dict(aci_class='fvBD', mo='BD-', key='name'),
|
||||
bd_l3out=dict(aci_class='fvRsBDToOut', mo='rsBDToOut-', key='tnL3extOutName'),
|
||||
contract=dict(aci_class='vzBrCP', mo='brc-', key='name'),
|
||||
entry=dict(aci_class='vzEntry', mo='e-', key='name'),
|
||||
epg=dict(aci_class='fvAEPg', mo='epg-', key='name'),
|
||||
epg_consumer=dict(aci_class='fvRsCons', mo='rscons-', key='tnVzBrCPName'),
|
||||
epg_domain=dict(aci_class='fvRsDomAtt', mo='rsdomAtt-', key='tDn'),
|
||||
epg_provider=dict(aci_class='fvRsProv', mo='rsprov-', key='tnVzBrCPName'),
|
||||
epr_policy=dict(aci_class='fvEpRetPol', mo='epRPol-', key='name'),
|
||||
export_policy=dict(aci_class='configExportP', mo='fabric/configexp-', key='name'),
|
||||
fc_policy=dict(aci_class='fcIfPol', mo='infra/fcIfPol-', key='name'),
|
||||
filter=dict(aci_class='vzFilter', mo='flt-', key='name'),
|
||||
gateway_addr=dict(aci_class='fvSubnet', mo='subnet-', key='ip'),
|
||||
import_policy=dict(aci_class='configImportP', mo='fabric/configimp-', key='name'),
|
||||
l2_policy=dict(aci_class='l2IfPol', mo='infra/l2IfP-', key='name'),
|
||||
lldp_policy=dict(aci_class='lldpIfPol', mo='infra/lldpIfP-', key='name'),
|
||||
mcp=dict(aci_class='mcpIfPol', mo='infra/mcpIfP-', key='name'),
|
||||
monitoring_policy=dict(aci_class='monEPGPol', mo='monepg-', key='name'),
|
||||
port_channel=dict(aci_class='lacpLagPol', mo='infra/lacplagp-', key='name'),
|
||||
port_security=dict(aci_class='l2PortSecurityPol', mo='infra/portsecurityP-', key='name'),
|
||||
rtp=dict(aci_class='l3extRouteTagPol', mo='rttag-', key='name'),
|
||||
snapshot=dict(aci_class='configSnapshot', mo='snapshot-', key='name'),
|
||||
snapshot_container=dict(aci_class='configSnapshotCont', mo='backupst/snapshots-', key='name'),
|
||||
subject=dict(aci_class='vzSubj', mo='subj-', key='name'),
|
||||
subject_filter=dict(aci_class='vzRsSubjFiltAtt', mo='rssubjFiltAtt-', key='tnVzFilterName'),
|
||||
taboo_contract=dict(aci_class='vzTaboo', mo='taboo-', key='name'),
|
||||
tenant=dict(aci_class='fvTenant', mo='tn-', key='name'),
|
||||
tenant_span_dst_grp=dict(aci_class='spanDestGrp', mo='destgrp-', key='name'),
|
||||
tenant_span_src_grp=dict(aci_class='spanSrcGrp', mo='srcgrp-', key='name'),
|
||||
tenant_span_src_grp_dst_grp=dict(aci_class='spanSpanLbl', mo='spanlbl-', key='name'),
|
||||
vrf=dict(aci_class='fvCtx', mo='ctx-', key='name'),
|
||||
)
|
||||
'''
|
||||
|
||||
|
||||
class ACIModule(object):
|
||||
|
||||
def __init__(self, module):
|
||||
@@ -125,6 +85,7 @@ class ACIModule(object):
|
||||
self.params = module.params
|
||||
self.result = dict(changed=False)
|
||||
self.headers = dict()
|
||||
self.child_classes = set()
|
||||
|
||||
# error output
|
||||
self.error = dict(code=None, text=None)
|
||||
@@ -423,14 +384,34 @@ class ACIModule(object):
|
||||
if self.result['diff']['before'] != self.result['diff']['after']:
|
||||
self.result['changed'] = True
|
||||
|
||||
# TODO: This could be designed to update existing keys
|
||||
def update_qs(self, params):
|
||||
''' Append key-value pairs to self.filter_string '''
|
||||
accepted_params = dict((k, v) for (k, v) in params.items() if v)
|
||||
if accepted_params:
|
||||
if self.filter_string:
|
||||
self.filter_string += '&'
|
||||
else:
|
||||
self.filter_string = '?'
|
||||
self.filter_string += '&'.join(['%s=%s' % (k, v) for (k, v) in accepted_params.items()])
|
||||
|
||||
# TODO: This could be designed to accept multiple obj_classes and keys
|
||||
def build_filter(self, obj_class, params):
|
||||
''' Build an APIC filter based on obj_class and key-value pairs '''
|
||||
accepted_params = dict((k, v) for (k, v) in params.items() if v is not None)
|
||||
if len(accepted_params) == 1:
|
||||
return ','.join('eq({0}.{1}, "{2}")'.format(obj_class, k, v) for (k, v) in accepted_params.items())
|
||||
elif len(accepted_params) > 1:
|
||||
return 'and(' + ','.join(['eq({0}.{1}, "{2}")'.format(obj_class, k, v) for (k, v) in accepted_params.items()]) + ')'
|
||||
|
||||
def construct_url(self, root_class, subclass_1=None, subclass_2=None, subclass_3=None, child_classes=None):
|
||||
"""
|
||||
This method is used to retrieve the appropriate URL path and filter_string to make the request to the APIC.
|
||||
|
||||
:param root_class: The top-level class dictionary containing aci_class, aci_rn, filter_target, and module_object keys.
|
||||
:param sublass_1: The second-level class dictionary containing aci_class, aci_rn, filter_target, and module_object keys.
|
||||
:param sublass_2: The third-level class dictionary containing aci_class, aci_rn, filter_target, and module_object keys.
|
||||
:param sublass_3: The fourth-level class dictionary containing aci_class, aci_rn, filter_target, and module_object keys.
|
||||
:param root_class: The top-level class dictionary containing aci_class, aci_rn, target_filter, and module_object keys.
|
||||
:param sublass_1: The second-level class dictionary containing aci_class, aci_rn, target_filter, and module_object keys.
|
||||
:param sublass_2: The third-level class dictionary containing aci_class, aci_rn, target_filter, and module_object keys.
|
||||
:param sublass_3: The fourth-level class dictionary containing aci_class, aci_rn, target_filter, and module_object keys.
|
||||
:param child_classes: The list of child classes that the module supports along with the object.
|
||||
:type root_class: dict
|
||||
:type subclass_1: dict
|
||||
@@ -439,207 +420,203 @@ class ACIModule(object):
|
||||
:type child_classes: list
|
||||
:return: The path and filter_string needed to build the full URL.
|
||||
"""
|
||||
self.filter_string = ''
|
||||
|
||||
if child_classes is None:
|
||||
child_includes = ''
|
||||
self.child_classes = set()
|
||||
else:
|
||||
child_includes = ','.join(child_classes)
|
||||
child_includes = '&rsp-subtree=full&rsp-subtree-class=' + child_includes
|
||||
self.child_classes = set(child_classes)
|
||||
|
||||
if subclass_3 is not None:
|
||||
path, filter_string = self._construct_url_4(root_class, subclass_1, subclass_2, subclass_3, child_includes)
|
||||
self._construct_url_4(root_class, subclass_1, subclass_2, subclass_3)
|
||||
elif subclass_2 is not None:
|
||||
path, filter_string = self._construct_url_3(root_class, subclass_1, subclass_2, child_includes)
|
||||
self._construct_url_3(root_class, subclass_1, subclass_2)
|
||||
elif subclass_1 is not None:
|
||||
path, filter_string = self._construct_url_2(root_class, subclass_1, child_includes)
|
||||
self._construct_url_2(root_class, subclass_1)
|
||||
else:
|
||||
path, filter_string = self._construct_url_1(root_class, child_includes)
|
||||
self._construct_url_1(root_class)
|
||||
|
||||
self.path = path
|
||||
if 'port' in self.params and self.params['port'] is not None:
|
||||
self.url = '{protocol}://{host}:{port}/{path}'.format(path=path, **self.module.params)
|
||||
self.url = '{protocol}://{host}:{port}/{path}'.format(path=self.path, **self.module.params)
|
||||
else:
|
||||
self.url = '{protocol}://{host}/{path}'.format(path=path, **self.module.params)
|
||||
self.filter_string = filter_string
|
||||
self.url = '{protocol}://{host}/{path}'.format(path=self.path, **self.module.params)
|
||||
|
||||
def _construct_url_1(self, obj, child_includes):
|
||||
if self.child_classes:
|
||||
# Append child_classes to filter_string if filter string is empty
|
||||
self.update_qs({'rsp-subtree': 'full', 'rsp-subtree-class': ','.join(self.child_classes)})
|
||||
|
||||
def _construct_url_1(self, obj):
|
||||
"""
|
||||
This method is used by get_url when the object is the top-level class.
|
||||
This method is used by construct_url when the object is the top-level class.
|
||||
"""
|
||||
obj_class = obj['aci_class']
|
||||
obj_rn = obj['aci_rn']
|
||||
obj_filter = obj['target_filter']
|
||||
mo = obj['module_object']
|
||||
|
||||
# State is present or absent
|
||||
if self.module.params['state'] != 'query':
|
||||
path = 'api/mo/uni/{0}.json'.format(obj_rn)
|
||||
filter_string = '?rsp-prop-include=config-only' + child_includes
|
||||
# Query for all objects of the module's class
|
||||
if self.module.params['state'] in ('absent', 'present'):
|
||||
# State is absent or present
|
||||
self.path = 'api/mo/uni/{0}.json'.format(obj_rn)
|
||||
self.update_qs({'rsp-prop-include': 'config-only'})
|
||||
elif mo is None:
|
||||
path = 'api/class/{0}.json'.format(obj_class)
|
||||
filter_string = ''
|
||||
# Query for a specific object in the module's class
|
||||
# Query for all objects of the module's class (filter by properties)
|
||||
self.path = 'api/class/{0}.json'.format(obj_class)
|
||||
else:
|
||||
path = 'api/mo/uni/{0}.json'.format(obj_rn)
|
||||
filter_string = ''
|
||||
# Query for a specific object in the module's class
|
||||
self.path = 'api/mo/uni/{0}.json'.format(obj_rn)
|
||||
|
||||
# Append child_includes to filter_string if filter string is empty
|
||||
if child_includes is not None and filter_string == '':
|
||||
filter_string = child_includes.replace('&', '?', 1)
|
||||
|
||||
return path, filter_string
|
||||
|
||||
def _construct_url_2(self, parent, obj, child_includes):
|
||||
def _construct_url_2(self, parent, obj):
|
||||
"""
|
||||
This method is used by get_url when the object is the second-level class.
|
||||
This method is used by construct_url when the object is the second-level class.
|
||||
"""
|
||||
parent_class = parent['aci_class']
|
||||
parent_rn = parent['aci_rn']
|
||||
parent_filter = parent['target_filter']
|
||||
parent_obj = parent['module_object']
|
||||
obj_class = obj['aci_class']
|
||||
obj_rn = obj['aci_rn']
|
||||
obj_filter = obj['filter_target']
|
||||
obj_filter = obj['target_filter']
|
||||
mo = obj['module_object']
|
||||
|
||||
if not child_includes:
|
||||
self_child_includes = '?rsp-subtree=full&rsp-subtree-class=' + obj_class
|
||||
else:
|
||||
self_child_includes = child_includes.replace('&', '?', 1) + ',' + obj_class
|
||||
|
||||
# State is present or absent
|
||||
if self.module.params['state'] != 'query':
|
||||
path = 'api/mo/uni/{0}/{1}.json'.format(parent_rn, obj_rn)
|
||||
filter_string = '?rsp-prop-include=config-only' + child_includes
|
||||
# Query for all objects of the module's class
|
||||
elif mo is None and parent_obj is None:
|
||||
path = 'api/class/{0}.json'.format(obj_class)
|
||||
filter_string = ''
|
||||
# Queries when parent object is provided
|
||||
elif parent_obj is not None:
|
||||
# Query for specific object in the module's class
|
||||
if mo is not None:
|
||||
path = 'api/mo/uni/{0}/{1}.json'.format(parent_rn, obj_rn)
|
||||
filter_string = ''
|
||||
if self.module.params['state'] in ('absent', 'present'):
|
||||
# State is absent or present
|
||||
self.path = 'api/mo/uni/{0}/{1}.json'.format(parent_rn, obj_rn)
|
||||
self.update_qs({'rsp-prop-include': 'config-only'})
|
||||
elif parent_obj is None and mo is None:
|
||||
# Query for all objects of the module's class
|
||||
self.path = 'api/class/{0}.json'.format(obj_class)
|
||||
elif parent_obj is None: # mo is known
|
||||
# Query for all objects of the module's class that match the provided ID value
|
||||
self.path = 'api/class/{0}.json'.format(obj_class)
|
||||
self.update_qs({'query-target-filter': self.build_filter(obj_class, obj_filter)})
|
||||
elif mo is None: # parent_obj is known
|
||||
# Query for all object's of the module's class that belong to a specific parent object
|
||||
else:
|
||||
path = 'api/mo/uni/{0}.json'.format(parent_rn)
|
||||
filter_string = self_child_includes
|
||||
# Query for all objects of the module's class that match the provided ID value
|
||||
self.child_classes.add(obj_class)
|
||||
self.path = 'api/mo/uni/{0}.json'.format(parent_rn)
|
||||
else:
|
||||
path = 'api/class/{0}.json'.format(obj_class)
|
||||
filter_string = '?query-target-filter={0}'.format(obj_filter) + child_includes
|
||||
# Query for specific object in the module's class
|
||||
self.path = 'api/mo/uni/{0}/{1}.json'.format(parent_rn, obj_rn)
|
||||
|
||||
# Append child_includes to filter_string if filter string is empty
|
||||
if child_includes is not None and filter_string == '':
|
||||
filter_string = child_includes.replace('&', '?', 1)
|
||||
|
||||
return path, filter_string
|
||||
|
||||
def _construct_url_3(self, root, parent, obj, child_includes):
|
||||
def _construct_url_3(self, root, parent, obj):
|
||||
"""
|
||||
This method is used by get_url when the object is the third-level class.
|
||||
This method is used by construct_url when the object is the third-level class.
|
||||
"""
|
||||
root_class = root['aci_class']
|
||||
root_rn = root['aci_rn']
|
||||
root_filter = root['target_filter']
|
||||
root_obj = root['module_object']
|
||||
parent_class = parent['aci_class']
|
||||
parent_rn = parent['aci_rn']
|
||||
parent_filter = parent['filter_target']
|
||||
parent_filter = parent['target_filter']
|
||||
parent_obj = parent['module_object']
|
||||
obj_class = obj['aci_class']
|
||||
obj_rn = obj['aci_rn']
|
||||
obj_filter = obj['filter_target']
|
||||
obj_filter = obj['target_filter']
|
||||
mo = obj['module_object']
|
||||
|
||||
if not child_includes:
|
||||
self_child_includes = '&rsp-subtree=full&rsp-subtree-class=' + obj_class
|
||||
else:
|
||||
self_child_includes = '{0},{1}'.format(child_includes, obj_class)
|
||||
|
||||
if not child_includes:
|
||||
parent_self_child_includes = '&rsp-subtree=full&rsp-subtree-class={0},{1}'.format(parent_class, obj_class)
|
||||
else:
|
||||
parent_self_child_includes = '{0},{1},{2}'.format(child_includes, parent_class, obj_class)
|
||||
|
||||
# State is ablsent or present
|
||||
if self.module.params['state'] != 'query':
|
||||
path = 'api/mo/uni/{0}/{1}/{2}.json'.format(root_rn, parent_rn, obj_rn)
|
||||
filter_string = '?rsp-prop-include=config-only' + child_includes
|
||||
# Query for all objects of the module's class
|
||||
elif mo is None and parent_obj is None and root_obj is None:
|
||||
path = 'api/class/{0}.json'.format(obj_class)
|
||||
filter_string = ''
|
||||
# Queries when root object is provided
|
||||
elif root_obj is not None:
|
||||
# Queries when parent object is provided
|
||||
if parent_obj is not None:
|
||||
# Query for a specific object of the module's class
|
||||
if mo is not None:
|
||||
path = 'api/mo/uni/{0}/{1}/{2}.json'.format(root_rn, parent_rn, obj_rn)
|
||||
filter_string = ''
|
||||
# Query for all objects of the module's class that belong to a specific parent object
|
||||
else:
|
||||
path = 'api/mo/uni/{0}/{1}.json'.format(root_rn, parent_rn)
|
||||
filter_string = self_child_includes.replace('&', '?', 1)
|
||||
# Query for all objects of the module's class that match the provided ID value and belong to a specefic root object
|
||||
elif mo is not None:
|
||||
path = 'api/mo/uni/{0}.json'.format(root_rn)
|
||||
filter_string = '?rsp-subtree-filter={0}{1}'.format(obj_filter, self_child_includes)
|
||||
# Query for all objects of the module's class that belong to a specific root object
|
||||
else:
|
||||
path = 'api/mo/uni/{0}.json'.format(root_rn)
|
||||
filter_string = '?' + parent_self_child_includes
|
||||
# Queries when parent object is provided but root object is not provided
|
||||
elif parent_obj is not None:
|
||||
# Query for all objects of the module's class that belong to any parent class
|
||||
# matching the provided ID values for both object and parent object
|
||||
if mo is not None:
|
||||
path = 'api/class/{0}.json'.format(parent_class)
|
||||
filter_string = '?query-target-filter={0}{1}&rsp-subtree-filter={2}'.format(
|
||||
parent_filter, self_child_includes, obj_filter)
|
||||
if self.module.params['state'] in ('absent', 'present'):
|
||||
# State is absent or present
|
||||
self.path = 'api/mo/uni/{0}/{1}/{2}.json'.format(root_rn, parent_rn, obj_rn)
|
||||
self.update_qs({'rsp-prop-include': 'config-only'})
|
||||
elif root_obj is None and parent_obj is None and mo is None:
|
||||
# Query for all objects of the module's class
|
||||
self.path = 'api/class/{0}.json'.format(obj_class)
|
||||
elif root_obj is None and parent_obj is None: # mo is known
|
||||
# Query for all objects of the module's class matching the provided ID value of the object
|
||||
self.path = 'api/class/{0}.json'.format(obj_class)
|
||||
self.update_qs({'query-target-filter': self.build_filter(obj_class, obj_filter)})
|
||||
elif root_obj is None and mo is None: # parent_obj is known
|
||||
# Query for all objects of the module's class that belong to any parent class
|
||||
# matching the provided ID value for the parent object
|
||||
else:
|
||||
path = 'api/class/{0}.json'.format(parent_class)
|
||||
filter_string = '?query-target-filter={0}{1}'.format(parent_filter, self_child_includes)
|
||||
# Query for all objects of the module's class matching the provided ID value of the object
|
||||
self.child_classes.add(obj_class)
|
||||
self.path = 'api/class/{0}.json'.format(parent_class)
|
||||
self.update_qs({'query-target-filter': self.build_filter(parent_class, parent_filter)})
|
||||
elif parent_obj is None and mo is None: # root_obj is known
|
||||
# Query for all objects of the module's class that belong to a specific root object
|
||||
self.child_classes.update([parent_class, obj_class])
|
||||
self.path = 'api/mo/uni/{0}.json'.format(root_rn)
|
||||
# NOTE: No need to select by root_filter
|
||||
# self.update_qs({'query-target-filter': self.build_filter(root_class, root_filter)})
|
||||
elif root_obj is None: # mo and parent_obj are known
|
||||
# Query for all objects of the module's class that belong to any parent class
|
||||
# matching the provided ID values for both object and parent object
|
||||
self.child_classes.add(obj_class)
|
||||
self.path = 'api/class/{0}.json'.format(parent_class)
|
||||
self.update_qs({'query-target-filter': self.build_filter(parent_class, parent_filter)})
|
||||
self.update_qs({'rsp-subtree-filter': self.build_filter(obj_class, obj_filter)})
|
||||
elif parent_obj is None: # mo and root_obj are known
|
||||
# Query for all objects of the module's class that match the provided ID value and belong to a specific root object
|
||||
self.child_classes.add(obj_class)
|
||||
self.path = 'api/mo/uni/{0}.json'.format(root_rn)
|
||||
# NOTE: No need to select by root_filter
|
||||
# self.update_qs({'query-target-filter': self.build_filter(root_class, root_filter)})
|
||||
# TODO: Filter by parent_filter and obj_filter
|
||||
self.update_qs({'rsp-subtree-filter': self.build_filter(obj_class, obj_filter)})
|
||||
elif mo is None: # root_obj and parent_obj are known
|
||||
# Query for all objects of the module's class that belong to a specific parent object
|
||||
self.child_classes.add(obj_class)
|
||||
self.path = 'api/mo/uni/{0}/{1}.json'.format(root_rn, parent_rn)
|
||||
# NOTE: No need to select by parent_filter
|
||||
# self.update_qs({'query-target-filter': self.build_filter(parent_class, parent_filter)})
|
||||
else:
|
||||
path = 'api/class/{0}.json'.format(obj_class)
|
||||
filter_string = '?query-target-filter={0}'.format(obj_filter) + child_includes
|
||||
# Query for a specific object of the module's class
|
||||
self.path = 'api/mo/uni/{0}/{1}/{2}.json'.format(root_rn, parent_rn, obj_rn)
|
||||
|
||||
# append child_includes to filter_string if filter string is empty
|
||||
if child_includes is not None and filter_string == '':
|
||||
filter_string = child_includes.replace('&', '?', 1)
|
||||
|
||||
return path, filter_string
|
||||
|
||||
def _construct_url_4(self, root, sec, parent, obj, child_includes):
|
||||
def _construct_url_4(self, root, sec, parent, obj):
|
||||
"""
|
||||
This method is used by get_url when the object is the third-level class.
|
||||
This method is used by construct_url when the object is the fourth-level class.
|
||||
"""
|
||||
# root_class = root['aci_class']
|
||||
root_class = root['aci_class']
|
||||
root_rn = root['aci_rn']
|
||||
# root_filter = root['filter_target']
|
||||
# root_obj = root['module_object']
|
||||
# sec_class = sec['aci_class']
|
||||
root_filter = root['target_filter']
|
||||
root_obj = root['module_object']
|
||||
sec_class = sec['aci_class']
|
||||
sec_rn = sec['aci_rn']
|
||||
# sec_filter = sec['filter_target']
|
||||
# sec_obj = sec['module_object']
|
||||
# parent_class = parent['aci_class']
|
||||
sec_filter = sec['target_filter']
|
||||
sec_obj = sec['module_object']
|
||||
parent_class = parent['aci_class']
|
||||
parent_rn = parent['aci_rn']
|
||||
# parent_filter = parent['filter_target']
|
||||
# parent_obj = parent['module_object']
|
||||
parent_filter = parent['target_filter']
|
||||
parent_obj = parent['module_object']
|
||||
obj_class = obj['aci_class']
|
||||
obj_rn = obj['aci_rn']
|
||||
# obj_filter = obj['filter_target']
|
||||
# mo = obj['module_object']
|
||||
obj_filter = obj['target_filter']
|
||||
mo = obj['module_object']
|
||||
|
||||
# State is ablsent or present
|
||||
if self.module.params['state'] != 'query':
|
||||
path = 'api/mo/uni/{0}/{1}/{2}/{3}.json'.format(root_rn, sec_rn, parent_rn, obj_rn)
|
||||
filter_string = '?rsp-prop-include=config-only' + child_includes
|
||||
if self.child_classes is None:
|
||||
self.child_classes = [obj_class]
|
||||
|
||||
if self.module.params['state'] in ('absent', 'present'):
|
||||
# State is absent or present
|
||||
self.path = 'api/mo/uni/{0}/{1}/{2}/{3}.json'.format(root_rn, sec_rn, parent_rn, obj_rn)
|
||||
self.update_qs({'rsp-prop-include': 'config-only'})
|
||||
# TODO: Add all missing cases
|
||||
elif root_obj is None:
|
||||
self.child_classes.add(obj_class)
|
||||
self.path = 'api/class/{0}.json'.format(obj_class)
|
||||
self.update_qs({'query-target-filter': self.build_filter(obj_class, obj_filter)})
|
||||
elif sec_obj is None:
|
||||
self.child_classes.add(obj_class)
|
||||
self.path = 'api/mo/uni/{0}.json'.format(root_rn)
|
||||
# NOTE: No need to select by root_filter
|
||||
# self.update_qs({'query-target-filter': self.build_filter(root_class, root_filter)})
|
||||
# TODO: Filter by sec_filter, parent and obj_filter
|
||||
self.update_qs({'rsp-subtree-filter': self.build_filter(obj_class, obj_filter)})
|
||||
elif parent_obj is None:
|
||||
self.child_classes.add(obj_class)
|
||||
self.path = 'api/mo/uni/{0}/{1}.json'.format(root_rn, sec_rn)
|
||||
# NOTE: No need to select by sec_filter
|
||||
# self.update_qs({'query-target-filter': self.build_filter(sec_class, sec_filter)})
|
||||
# TODO: Filter by parent_filter and obj_filter
|
||||
self.update_qs({'rsp-subtree-filter': self.build_filter(obj_class, obj_filter)})
|
||||
elif mo is None:
|
||||
self.child_classes.add(obj_class)
|
||||
self.path = 'api/mo/uni/{0}/{1}/{2}.json'.format(root_rn, sec_rn, parent_rn)
|
||||
# NOTE: No need to select by parent_filter
|
||||
# self.update_qs({'query-target-filter': self.build_filter(parent_class, parent_filter)})
|
||||
else:
|
||||
path = 'api/class/{0}.json'.format(obj_class)
|
||||
filter_string = child_includes
|
||||
|
||||
return path, filter_string
|
||||
# Query for a specific object of the module's class
|
||||
self.path = 'api/mo/uni/{0}/{1}/{2}/{3}.json'.format(root_rn, sec_rn, parent_rn, obj_rn)
|
||||
|
||||
def delete_config(self):
|
||||
"""
|
||||
|
||||
@@ -301,8 +301,8 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='aaaUser',
|
||||
aci_rn='userext/user-{0}'.format(aaa_user),
|
||||
filter_target='eq(aaaUser.name, "{0}")'.format(aaa_user),
|
||||
module_object=aaa_user,
|
||||
target_filter={'name': aaa_user},
|
||||
),
|
||||
)
|
||||
aci.get_existing()
|
||||
|
||||
@@ -240,14 +240,14 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class=ACI_MAPPING[aaa_user_type]['aci_class'],
|
||||
aci_rn=ACI_MAPPING[aaa_user_type]['aci_mo'] + aaa_user,
|
||||
filter_target='eq({0}.name, "{1}")'.format(ACI_MAPPING[aaa_user_type]['aci_class'], aaa_user),
|
||||
module_object=aaa_user,
|
||||
target_filter={'name': aaa_user},
|
||||
),
|
||||
subclass_1=dict(
|
||||
aci_class='aaaUserCert',
|
||||
aci_rn='usercert-{0}'.format(certificate_name),
|
||||
filter_target='eq(aaaUserCert.name, "{0}")'.format(certificate_name),
|
||||
module_object=certificate_name,
|
||||
target_filter={'name': certificate_name},
|
||||
),
|
||||
)
|
||||
aci.get_existing()
|
||||
|
||||
@@ -282,15 +282,15 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='infraAccPortP',
|
||||
aci_rn='infra/accportprof-{0}'.format(leaf_interface_profile),
|
||||
filter_target='eq(infraAccPortP.name, "{0}")'.format(leaf_interface_profile),
|
||||
module_object=leaf_interface_profile,
|
||||
target_filter={'name': leaf_interface_profile},
|
||||
),
|
||||
subclass_1=dict(
|
||||
aci_class='infraHPortS',
|
||||
# NOTE: normal rn: hports-{name}-typ-{type}, hence here hardcoded to range for purposes of module
|
||||
aci_rn='hports-{0}-typ-range'.format(access_port_selector),
|
||||
filter_target='eq(infraHPortS.name, "{0}")'.format(access_port_selector),
|
||||
module_object=access_port_selector,
|
||||
target_filter={'name': access_port_selector},
|
||||
),
|
||||
child_classes=['infraPortBlk', 'infraRsAccBaseGrp'],
|
||||
)
|
||||
|
||||
@@ -229,8 +229,8 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='infraAttEntityP',
|
||||
aci_rn='infra/attentp-{0}'.format(aep),
|
||||
filter_target='eq(infraAttEntityP.name, "{0}")'.format(aep),
|
||||
module_object=aep,
|
||||
target_filter={'name': aep},
|
||||
),
|
||||
)
|
||||
aci.get_existing()
|
||||
|
||||
@@ -264,14 +264,14 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='infraAttEntityP',
|
||||
aci_rn='infra/attentp-{0}'.format(aep),
|
||||
filter_target='eq(infraAttEntityP.name, "{0}")'.format(aep),
|
||||
module_object=aep,
|
||||
target_filter={'name': aep},
|
||||
),
|
||||
subclass_1=dict(
|
||||
aci_class='infraRsDomP',
|
||||
aci_rn='rsdomP-[{0}]'.format(domain_mo),
|
||||
filter_target='eq(infraRsDomP.tDn, "{0}")'.format(domain_mo),
|
||||
module_object=domain_mo,
|
||||
target_filter={'tDn': domain_mo},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -223,14 +223,14 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='fvTenant',
|
||||
aci_rn='tn-{0}'.format(tenant),
|
||||
filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
|
||||
module_object=tenant,
|
||||
target_filter={'name': tenant},
|
||||
),
|
||||
subclass_1=dict(
|
||||
aci_class='fvAp',
|
||||
aci_rn='ap-{0}'.format(ap),
|
||||
filter_target='eq(fvAp.name, "{0}")'.format(ap),
|
||||
module_object=ap,
|
||||
target_filter={'name': ap},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -381,14 +381,14 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='fvTenant',
|
||||
aci_rn='tn-{0}'.format(tenant),
|
||||
filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
|
||||
module_object=tenant,
|
||||
target_filter={'name': tenant},
|
||||
),
|
||||
subclass_1=dict(
|
||||
aci_class='fvBD',
|
||||
aci_rn='BD-{0}'.format(bd),
|
||||
filter_target='eq(fvBD.name, "{0}")'.format(bd),
|
||||
module_object=bd,
|
||||
target_filter={'name': bd},
|
||||
),
|
||||
child_classes=['fvRsCtx', 'fvRsIgmpsn', 'fvRsBDToNdP', 'fvRsBdToEpRet'],
|
||||
)
|
||||
|
||||
@@ -372,20 +372,20 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='fvTenant',
|
||||
aci_rn='tn-{0}'.format(tenant),
|
||||
filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
|
||||
module_object=tenant,
|
||||
target_filter={'name': tenant},
|
||||
),
|
||||
subclass_1=dict(
|
||||
aci_class='fvBD',
|
||||
aci_rn='BD-{0}'.format(bd),
|
||||
filter_target='eq(fvBD.name, "{0}")'.format(bd),
|
||||
module_object=bd,
|
||||
target_filter={'name': bd},
|
||||
),
|
||||
subclass_2=dict(
|
||||
aci_class='fvSubnet',
|
||||
aci_rn='subnet-[{0}]'.format(gateway),
|
||||
filter_target='eq(fvSubnet.ip, "{0}")'.format(gateway),
|
||||
module_object=gateway,
|
||||
target_filter={'ip': gateway},
|
||||
),
|
||||
child_classes=['fvRsBDSubnetToProfile', 'fvRsNdPfxPol'],
|
||||
)
|
||||
|
||||
@@ -188,20 +188,20 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='fvTenant',
|
||||
aci_rn='tn-{0}'.format(tenant),
|
||||
filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
|
||||
module_object=tenant,
|
||||
target_filter={'name': tenant},
|
||||
),
|
||||
subclass_1=dict(
|
||||
aci_class='fvBD',
|
||||
aci_rn='BD-{0}'.format(bd),
|
||||
filter_target='eq(fvBD.name, "{0}")'.format(bd),
|
||||
module_object=bd,
|
||||
target_filter={'name': bd},
|
||||
),
|
||||
subclass_2=dict(
|
||||
aci_class='fvRsBDToOut',
|
||||
aci_rn='rsBDToOut-{0}'.format(l3out),
|
||||
filter_target='eq(fvRsBDToOut.tnL3extOutName, "{0}")'.format(l3out),
|
||||
module_object=l3out,
|
||||
target_filter={'tnL3extOutName': l3out},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -232,8 +232,8 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='configImportP',
|
||||
aci_rn='fabric/configimp-{0}'.format(import_policy),
|
||||
filter_target='eq(configImportP.name, "{0}")'.format(import_policy),
|
||||
module_object=import_policy,
|
||||
target_filter={'name': import_policy},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -252,8 +252,8 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='configExportP',
|
||||
aci_rn='fabric/configexp-{0}'.format(export_policy),
|
||||
filter_target='eq(configExportP.name, "{0}")'.format(export_policy),
|
||||
module_object=export_policy,
|
||||
target_filter={'name': export_policy},
|
||||
),
|
||||
)
|
||||
|
||||
@@ -286,14 +286,14 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='configSnapshotCont',
|
||||
aci_rn='backupst/snapshots-[{0}]'.format(export_policy),
|
||||
filter_target='(configSnapshotCont.name, "{0}")'.format(export_policy),
|
||||
module_object=export_policy,
|
||||
target_filter={'name': export_policy},
|
||||
),
|
||||
subclass_1=dict(
|
||||
aci_class='configSnapshot',
|
||||
aci_rn='snapshot-{0}'.format(snapshot),
|
||||
filter_target='eq(configSnapshot.name, "{0}")'.format(snapshot),
|
||||
module_object=snapshot,
|
||||
target_filter={'name': snapshot},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -250,14 +250,14 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='fvTenant',
|
||||
aci_rn='tn-{0}'.format(tenant),
|
||||
filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
|
||||
module_object=tenant,
|
||||
target_filter={'name': tenant},
|
||||
),
|
||||
subclass_1=dict(
|
||||
aci_class='vzBrCP',
|
||||
aci_rn='brc-{0}'.format(contract),
|
||||
filter_target='eq(vzBrCP.name, "{0}")'.format(contract),
|
||||
module_object=contract,
|
||||
target_filter={'name': contract},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -286,20 +286,20 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='fvTenant',
|
||||
aci_rn='tn-{0}'.format(tenant),
|
||||
filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
|
||||
module_object=tenant,
|
||||
target_filter={'name': tenant},
|
||||
),
|
||||
subclass_1=dict(
|
||||
aci_class='vzBrCP',
|
||||
aci_rn='brc-{0}'.format(contract),
|
||||
filter_target='eq(vzBrCP.name, "{0}")'.format(contract),
|
||||
module_object=contract,
|
||||
target_filter={'name': contract},
|
||||
),
|
||||
subclass_2=dict(
|
||||
aci_class='vzSubj',
|
||||
aci_rn='subj-{0}'.format(subject),
|
||||
filter_target='eq(vzSubj.name, "{0}")'.format(subject),
|
||||
module_object=subject,
|
||||
target_filter={'name': subject},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -252,26 +252,26 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='fvTenant',
|
||||
aci_rn='tn-{0}'.format(tenant),
|
||||
filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
|
||||
module_object=tenant,
|
||||
target_filter={'name': tenant},
|
||||
),
|
||||
subclass_1=dict(
|
||||
aci_class='vzBrCP',
|
||||
aci_rn='brc-{0}'.format(contract),
|
||||
filter_target='eq(vzBrCP.name, "{0}")'.format(contract),
|
||||
module_object=contract,
|
||||
target_filter={'name': contract},
|
||||
),
|
||||
subclass_2=dict(
|
||||
aci_class='vzSubj',
|
||||
aci_rn='subj-{0}'.format(subject),
|
||||
filter_target='eq(vzSubj.name, "{0}")'.format(subject),
|
||||
module_object=subject,
|
||||
target_filter={'name': subject},
|
||||
),
|
||||
subclass_3=dict(
|
||||
aci_class='vzRsSubjFiltAtt',
|
||||
aci_rn='rssubjFiltAtt-{0}'.format(filter_name),
|
||||
filter_target='eq(vzRsSubjFiltAtt.tnVzFilterName, "{0}")'.format(filter_name),
|
||||
module_object=filter_name,
|
||||
target_filter={'tnVzFilterName': filter_name},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -334,8 +334,8 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class=domain_class,
|
||||
aci_rn=domain_rn,
|
||||
filter_target='eq({0}.name, "{1}")'.format(domain_class, domain),
|
||||
module_object=domain_mo,
|
||||
target_filter={'name': domain},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -325,8 +325,8 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class=domain_class,
|
||||
aci_rn=domain_rn,
|
||||
filter_target='eq({0}.name, "{1}")'.format(domain_class, domain),
|
||||
module_object=domain_mo,
|
||||
target_filter={'name': domain},
|
||||
),
|
||||
child_classes=[child_class],
|
||||
)
|
||||
|
||||
@@ -315,8 +315,8 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class=domain_class,
|
||||
aci_rn=domain_rn,
|
||||
filter_target='eq({0}.name, "{1}")'.format(domain_class, domain),
|
||||
module_object=domain_mo,
|
||||
target_filter={'name': domain},
|
||||
),
|
||||
child_classes=['infraRsVlanNs'],
|
||||
)
|
||||
|
||||
@@ -259,8 +259,8 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class=aci_class,
|
||||
aci_rn='{0}{1}'.format(aci_mo, pool_name),
|
||||
filter_target='eq({0}.name, "{1}")'.format(aci_class, pool),
|
||||
module_object=pool,
|
||||
target_filter={'name': pool},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -327,33 +327,15 @@ def main():
|
||||
if not 1 <= encap_id <= 4093:
|
||||
module.fail_json(msg='vsan pools must have "range_start" and "range_end" values between 1 and 4093')
|
||||
|
||||
# Build proper proper filter_target based on range_start, range_end, and range_name
|
||||
if range_end is not None and range_start is not None:
|
||||
# Validate range_start is less than range_end
|
||||
if range_start > range_end:
|
||||
module.fail_json(msg='The "range_start" must be less than or equal to the "range_end"')
|
||||
|
||||
if range_name is None:
|
||||
range_filter_target = 'and(eq({0}.from, "{1}"),eq({0}.to, "{2}"))'.format(aci_range_class, encap_start, encap_end)
|
||||
else:
|
||||
range_filter_target = 'and(eq({0}.from, "{1}"),eq({0}.to, "{2}"),eq({0}.name, "{3}"))'.format(aci_range_class, encap_start, encap_end, range_name)
|
||||
elif range_end is None and range_start is None:
|
||||
if range_name is None:
|
||||
# Reset range managed object to None for aci util to properly handle query
|
||||
aci_range_mo = None
|
||||
range_filter_target = ''
|
||||
else:
|
||||
range_filter_target = 'eq({0}.name, "{1}")'.format(aci_range_class, range_name)
|
||||
elif range_start is not None:
|
||||
if range_name is None:
|
||||
range_filter_target = 'eq({0}.from, "{1}")'.format(aci_range_class, encap_start)
|
||||
else:
|
||||
range_filter_target = 'and(eq({0}.from, "{1}"),eq({0}.name, "{2}"))'.format(aci_range_class, encap_start, range_name)
|
||||
else:
|
||||
if range_name is None:
|
||||
range_filter_target = 'eq({0}.to, "{1}")'.format(aci_range_class, encap_end)
|
||||
else:
|
||||
range_filter_target = 'and(eq({0}.to, "{1}"),eq({0}.name, "{2}"))'.format(aci_range_class, encap_end, range_name)
|
||||
|
||||
# Vxlan does not support setting the allocation mode
|
||||
if pool_type == 'vxlan' and allocation_mode is not None:
|
||||
@@ -371,14 +353,14 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class=aci_pool_class,
|
||||
aci_rn='{0}{1}'.format(aci_pool_mo, pool_name),
|
||||
filter_target='eq({0}.name, "{1}")'.format(aci_pool_class, pool),
|
||||
module_object=pool,
|
||||
target_filter={'name': pool},
|
||||
),
|
||||
subclass_1=dict(
|
||||
aci_class=aci_range_class,
|
||||
aci_rn='{0}'.format(aci_range_mo),
|
||||
filter_target=range_filter_target,
|
||||
module_object=aci_range_mo,
|
||||
target_filter={'from': encap_start, 'to': encap_end, 'name': range_name},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -307,20 +307,20 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='fvTenant',
|
||||
aci_rn='tn-{0}'.format(tenant),
|
||||
filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
|
||||
module_object=tenant,
|
||||
target_filter={'name': tenant},
|
||||
),
|
||||
subclass_1=dict(
|
||||
aci_class='fvAp',
|
||||
aci_rn='ap-{0}'.format(ap),
|
||||
filter_target='eq(fvAp.name, "{0}")'.format(ap),
|
||||
module_object=ap,
|
||||
target_filter={'name': ap},
|
||||
),
|
||||
subclass_2=dict(
|
||||
aci_class='fvAEPg',
|
||||
aci_rn='epg-{0}'.format(epg),
|
||||
filter_target='eq(fvAEPg.name, "{0}")'.format(epg),
|
||||
module_object=epg,
|
||||
target_filter={'name': epg},
|
||||
),
|
||||
child_classes=['fvRsBd'],
|
||||
)
|
||||
|
||||
@@ -196,14 +196,14 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='fvTenant',
|
||||
aci_rn='tn-{0}'.format(tenant),
|
||||
filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
|
||||
module_object=tenant,
|
||||
target_filter={'name': tenant},
|
||||
),
|
||||
subclass_1=dict(
|
||||
aci_class='monEPGPol',
|
||||
aci_rn='monepg-{0}'.format(monitoring_policy),
|
||||
filter_target='eq(monEPGPol.name, "{0}")'.format(monitoring_policy),
|
||||
module_object=monitoring_policy,
|
||||
target_filter={'name': monitoring_policy},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -267,26 +267,26 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='fvTenant',
|
||||
aci_rn='tn-{0}'.format(tenant),
|
||||
filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
|
||||
module_object=tenant,
|
||||
target_filter={'name': tenant},
|
||||
),
|
||||
subclass_1=dict(
|
||||
aci_class='fvAp',
|
||||
aci_rn='ap-{0}'.format(ap),
|
||||
filter_target='eq(fvAp.name, "{0}")'.format(ap),
|
||||
module_object=ap,
|
||||
target_filter={'name': ap},
|
||||
),
|
||||
subclass_2=dict(
|
||||
aci_class='fvAEPg',
|
||||
aci_rn='epg-{0}'.format(epg),
|
||||
filter_target='eq(fvAEPg.name, "{0}")'.format(epg),
|
||||
module_object=epg,
|
||||
target_filter={'name': epg},
|
||||
),
|
||||
subclass_3=dict(
|
||||
aci_class=aci_class,
|
||||
aci_rn='{0}{1}'.format(aci_rn, contract),
|
||||
filter_target='eq({0}.tnVzBrCPName, "{1}'.format(aci_class, contract),
|
||||
module_object=contract,
|
||||
target_filter={'tnVzBrCPName': contract},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -335,26 +335,26 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='fvTenant',
|
||||
aci_rn='tn-{0}'.format(tenant),
|
||||
filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
|
||||
module_object=tenant,
|
||||
target_filter={'name': tenant},
|
||||
),
|
||||
subclass_1=dict(
|
||||
aci_class='fvAp',
|
||||
aci_rn='ap-{0}'.format(ap),
|
||||
filter_target='eq(fvAp.name, "{0}")'.format(ap),
|
||||
module_object=ap,
|
||||
target_filter={'name': ap},
|
||||
),
|
||||
subclass_2=dict(
|
||||
aci_class='fvAEPg',
|
||||
aci_rn='epg-{0}'.format(epg),
|
||||
filter_target='eq(fvTenant.name, "{0}")'.format(epg),
|
||||
module_object=epg,
|
||||
target_filter={'name': epg},
|
||||
),
|
||||
subclass_3=dict(
|
||||
aci_class='fvRsDomAtt',
|
||||
aci_rn='rsdomAtt-[{0}]'.format(epg_domain),
|
||||
filter_target='eq(fvRsDomAtt.tDn, "{0}")'.format(epg_domain),
|
||||
module_object=epg_domain,
|
||||
target_filter={'tDn': epg_domain},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -232,8 +232,8 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='fabricNodeIdentP',
|
||||
aci_rn='controller/nodeidentpol/nodep-{0}'.format(serial),
|
||||
filter_target='eq(fabricNodeIdentP.serial, "{0}")'.format(serial),
|
||||
module_object=serial,
|
||||
target_filter={'serial': serial},
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -224,14 +224,14 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='fvTenant',
|
||||
aci_rn='tn-{0}'.format(tenant),
|
||||
filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
|
||||
module_object=tenant,
|
||||
target_filter={'name': tenant},
|
||||
),
|
||||
subclass_1=dict(
|
||||
aci_class='vzFilter',
|
||||
aci_rn='flt-{0}'.format(filter_name),
|
||||
filter_target='eq(vzFilter.name, "{0}")'.format(filter_name),
|
||||
module_object=filter_name,
|
||||
target_filter={'name': filter_name},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -299,20 +299,20 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='fvTenant',
|
||||
aci_rn='tn-{0}'.format(tenant),
|
||||
filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
|
||||
module_object=tenant,
|
||||
target_filter={'name': tenant},
|
||||
),
|
||||
subclass_1=dict(
|
||||
aci_class='vzFilter',
|
||||
aci_rn='flt-{0}'.format(filter_name),
|
||||
filter_target='eq(vzFilter.name, "{0}")'.format(filter_name),
|
||||
module_object=filter_name,
|
||||
target_filter={'name': filter_name},
|
||||
),
|
||||
subclass_2=dict(
|
||||
aci_class='vzEntry',
|
||||
aci_rn='e-{0}'.format(entry),
|
||||
filter_target='eq(vzEntry.name, "{0}")'.format(entry),
|
||||
module_object=entry
|
||||
module_object=entry,
|
||||
target_filter={'name': entry},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -236,8 +236,8 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='firmwareOSource',
|
||||
aci_rn='fabric/fwrepop',
|
||||
filter_target='eq(firmwareOSource.name, "{0}")'.format(source),
|
||||
module_object=source,
|
||||
target_filter={'name': source},
|
||||
),
|
||||
)
|
||||
aci.get_existing()
|
||||
|
||||
@@ -194,8 +194,8 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='fcIfPol',
|
||||
aci_rn='infra/fcIfPol-{0}'.format(fc_policy),
|
||||
filter_target='eq(fcIfPol.name, "{0}")'.format(fc_policy),
|
||||
module_object=fc_policy,
|
||||
target_filter={'name': fc_policy},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -213,8 +213,8 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='l2IfPol',
|
||||
aci_rn='infra/l2IfP-{0}'.format(l2_policy),
|
||||
filter_target='eq(l2IfPol.name, "{0}")'.format(l2_policy),
|
||||
module_object=l2_policy,
|
||||
target_filter={'name': l2_policy},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -352,6 +352,8 @@ def main():
|
||||
name=policy_group,
|
||||
descr=description,
|
||||
)
|
||||
# Reset for target_filter
|
||||
lag_type = None
|
||||
elif lag_type in ('link', 'node'):
|
||||
aci_class_name = 'infraAccBndlGrp'
|
||||
dn_name = 'accbundle'
|
||||
@@ -366,8 +368,8 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class=aci_class_name,
|
||||
aci_rn='infra/funcprof/{0}-{1}'.format(dn_name, policy_group),
|
||||
filter_target='eq({0}.name, "{1}")'.format(aci_class_name, policy_group),
|
||||
module_object=policy_group,
|
||||
target_filter={'name': policy_group, 'lagT': lag_type},
|
||||
),
|
||||
child_classes=[
|
||||
'infraRsAttEntP',
|
||||
|
||||
@@ -211,8 +211,8 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='infraAccPortP',
|
||||
aci_rn='infra/accportprof-{0}'.format(leaf_interface_profile),
|
||||
filter_target='eq(infraAccPortP.name, "{0}")'.format(leaf_interface_profile),
|
||||
module_object=leaf_interface_profile
|
||||
module_object=leaf_interface_profile,
|
||||
target_filter={'name': leaf_interface_profile},
|
||||
),
|
||||
)
|
||||
aci.get_existing()
|
||||
|
||||
@@ -203,8 +203,8 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='lldpIfPol',
|
||||
aci_rn='infra/lldpIfP-{0}'.format(lldp_policy),
|
||||
filter_target='eq(lldpIfPol.name, "{0}")'.format(lldp_policy),
|
||||
module_object=lldp_policy,
|
||||
target_filter={'name': lldp_policy},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -195,8 +195,8 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='mcpIfPol',
|
||||
aci_rn='infra/mcpIfP-{0}'.format(mcp),
|
||||
filter_target='eq(mcpIfPol.name, "{0}")'.format(mcp),
|
||||
module_object=mcp,
|
||||
target_filter={'name': mcp},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -346,8 +346,8 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='ospfIfPol',
|
||||
aci_rn='tn-{0}/ospfIfPol-{1}'.format(tenant, ospf),
|
||||
filter_target='eq(ospfIfPol.name, "{0}")'.format(ospf),
|
||||
module_object=ospf,
|
||||
target_filter={'name': ospf},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -273,8 +273,8 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='lacpLagPol',
|
||||
aci_rn='infra/lacplagp-{0}'.format(port_channel),
|
||||
filter_target='eq(lacpLagPol.name, "{0}")'.format(port_channel),
|
||||
module_object=port_channel,
|
||||
target_filter={'name': port_channel},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -197,8 +197,8 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='l2PortSecurityPol',
|
||||
aci_rn='infra/portsecurityP-{0}'.format(port_security),
|
||||
filter_target='eq(l2PortSecurityPol.name, "{0}")'.format(port_security),
|
||||
module_object=port_security,
|
||||
target_filter={'name': port_security},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -210,14 +210,14 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='infraNodeP',
|
||||
aci_rn='infra/nprof-{0}'.format(leaf_profile),
|
||||
filter_target='eq(infraNodeP.name, "{0}")'.format(leaf_profile),
|
||||
module_object=leaf_profile
|
||||
module_object=leaf_profile,
|
||||
target_filter={'name': leaf_profile},
|
||||
),
|
||||
subclass_1=dict(
|
||||
aci_class='infraRsAccPortP',
|
||||
aci_rn='rsaccPortP-[{0}]'.format(interface_selector_tDn),
|
||||
filter_target='eq(infraRsAccPortP.name, "{0}")'.format(interface_selector),
|
||||
module_object=interface_selector,
|
||||
target_filter={'name': interface_selector},
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -269,14 +269,14 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='fvTenant',
|
||||
aci_rn='tn-{0}'.format(tenant),
|
||||
filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
|
||||
module_object=tenant,
|
||||
target_filter={'name': tenant},
|
||||
),
|
||||
subclass_1=dict(
|
||||
aci_class='l3extOut',
|
||||
aci_rn='out-{0}'.format(l3out),
|
||||
filter_target='eq(l3extOut.name, "{0}")'.format(l3out),
|
||||
module_object=l3out,
|
||||
target_filter={'name': l3out},
|
||||
),
|
||||
child_classes=child_classes,
|
||||
)
|
||||
|
||||
@@ -205,14 +205,14 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='fvTenant',
|
||||
aci_rn='tn-{0}'.format(tenant),
|
||||
filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
|
||||
module_object=tenant,
|
||||
target_filter={'name': tenant},
|
||||
),
|
||||
subclass_1=dict(
|
||||
aci_class='l3extRouteTagPol',
|
||||
aci_rn='rttag-{0}'.format(rtp),
|
||||
filter_target='eq(l3extRouteTagPol.name, "{0}")'.format(rtp),
|
||||
module_object=rtp,
|
||||
target_filter={'name': rtp},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -358,6 +358,11 @@ def main():
|
||||
)
|
||||
|
||||
static_path = INTERFACE_TYPE_MAPPING[interface_type]
|
||||
|
||||
path_target_filter = {}
|
||||
if pod_id is not None and leafs is not None and interface is not None and (interface_type != 'fex' or extpaths is not None):
|
||||
path_target_filter = {'tDn': static_path}
|
||||
|
||||
if interface_mode is not None:
|
||||
interface_mode = INTERFACE_MODE_MAPPING[interface_mode]
|
||||
|
||||
@@ -366,26 +371,26 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='fvTenant',
|
||||
aci_rn='tn-{0}'.format(tenant),
|
||||
filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
|
||||
module_object=tenant,
|
||||
target_filter={'name': tenant},
|
||||
),
|
||||
subclass_1=dict(
|
||||
aci_class='fvAp',
|
||||
aci_rn='ap-{0}'.format(ap),
|
||||
filter_target='eq(fvAp.name, "{0}")'.format(ap),
|
||||
module_object=ap,
|
||||
target_filter={'name': ap},
|
||||
),
|
||||
subclass_2=dict(
|
||||
aci_class='fvAEPg',
|
||||
aci_rn='epg-{0}'.format(epg),
|
||||
filter_target='eq(fvAEPg.name, "{0}")'.format(epg),
|
||||
module_object=epg,
|
||||
target_filter={'name': epg},
|
||||
),
|
||||
subclass_3=dict(
|
||||
aci_class='fvRsPathAtt',
|
||||
aci_rn='rspathAtt-[{0}]'.format(static_path),
|
||||
filter_target='eq(fvRsPathAtt.tDn, "{0}"'.format(static_path),
|
||||
module_object=static_path,
|
||||
target_filter=path_target_filter,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -260,15 +260,15 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='infraNodeP',
|
||||
aci_rn='infra/nprof-{0}'.format(leaf_profile),
|
||||
filter_target='eq(infraNodeP.name, "{0}")'.format(leaf_profile),
|
||||
module_object=leaf_profile
|
||||
module_object=leaf_profile,
|
||||
target_filter={'name': leaf_profile},
|
||||
),
|
||||
subclass_1=dict(
|
||||
aci_class='infraLeafS',
|
||||
# NOTE: normal rn: leaves-{name}-typ-{type}, hence here hardcoded to range for purposes of module
|
||||
aci_rn='leaves-{0}-typ-range'.format(leaf),
|
||||
filter_target='eq(infraLeafS.name, "{0}")'.format(leaf),
|
||||
module_object=leaf,
|
||||
target_filter={'name': leaf},
|
||||
),
|
||||
# NOTE: infraNodeBlk is not made into a subclass because there is a 1-1 mapping between node block and leaf selector name
|
||||
child_classes=['infraNodeBlk', 'infraRsAccNodePGrp'],
|
||||
|
||||
@@ -203,8 +203,8 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='infraNodeP',
|
||||
aci_rn='infra/nprof-{0}'.format(leaf_profile),
|
||||
filter_target='eq(infraNodeP.name, "{0}")'.format(leaf_profile),
|
||||
module_object=leaf_profile,
|
||||
target_filter={'name': leaf_profile},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -235,8 +235,8 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='fabricExplicitGEp',
|
||||
aci_rn='fabric/protpol/expgep-{0}'.format(protection_group),
|
||||
filter_target='eq(fabricExplicitGEp.name, "{0}")'.format(protection_group),
|
||||
module_object=protection_group,
|
||||
target_filter={'name': protection_group},
|
||||
),
|
||||
child_classes=['fabricNodePEp', 'fabricNodePEp', 'fabricRsVpcInstPol'],
|
||||
)
|
||||
|
||||
@@ -229,14 +229,14 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='fvTenant',
|
||||
aci_rn='tn-{0}'.format(tenant),
|
||||
filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
|
||||
module_object=tenant,
|
||||
target_filter={'name': tenant},
|
||||
),
|
||||
subclass_1=dict(
|
||||
aci_class='vzTaboo',
|
||||
aci_rn='taboo-{0}'.format(taboo_contract),
|
||||
filter_target='eq(vzTaboo.name, "{0}")'.format(taboo_contract),
|
||||
module_object=taboo_contract,
|
||||
target_filter={'name': taboo_contract},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -210,8 +210,8 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='fvTenant',
|
||||
aci_rn='tn-{0}'.format(tenant),
|
||||
filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
|
||||
module_object=tenant,
|
||||
target_filter={'name': tenant},
|
||||
),
|
||||
)
|
||||
aci.get_existing()
|
||||
|
||||
@@ -194,14 +194,14 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='fvTenant',
|
||||
aci_rn='tn-{0}'.format(tenant),
|
||||
filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
|
||||
module_object=tenant,
|
||||
target_filter={'name': tenant},
|
||||
),
|
||||
subclass_1=dict(
|
||||
aci_class='rtctrlAttrP',
|
||||
aci_rn='attr-{0}'.format(action_rule),
|
||||
filter_target='eq(rtctrlAttrP.name, "{0}")'.format(action_rule),
|
||||
module_object=action_rule,
|
||||
target_filter={'name': action_rule},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -294,14 +294,14 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='fvTenant',
|
||||
aci_rn='tn-{0}'.format(tenant),
|
||||
filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
|
||||
module_object=tenant,
|
||||
target_filter={'name': tenant},
|
||||
),
|
||||
subclass_1=dict(
|
||||
aci_class='fvEpRetPol',
|
||||
aci_rn='epRPol-{0}'.format(epr_policy),
|
||||
filter_target='eq(fvEpRetPol.name, "{0}")'.format(epr_policy),
|
||||
module_object=epr_policy,
|
||||
target_filter={'name': epr_policy},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -196,14 +196,14 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='fvTenant',
|
||||
aci_rn='tn-{0}'.format(tenant),
|
||||
filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
|
||||
module_object=tenant,
|
||||
target_filter={'name': tenant},
|
||||
),
|
||||
subclass_1=dict(
|
||||
aci_class='spanDestGrp',
|
||||
aci_rn='destgrp-{0}'.format(dst_group),
|
||||
filter_target='eq(spanDestGrp.name, "{0}")'.format(dst_group),
|
||||
module_object=dst_group,
|
||||
target_filter={'name': dst_group},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -208,14 +208,14 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='fvTenant',
|
||||
aci_rn='tn-{0}'.format(tenant),
|
||||
filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
|
||||
module_object=tenant,
|
||||
target_filter={'name': tenant},
|
||||
),
|
||||
subclass_1=dict(
|
||||
aci_class='spanSrcGrp',
|
||||
aci_rn='srcgrp-{0}'.format(src_group),
|
||||
filter_target='eq(spanSrcGrp.name, "{0}")'.format(src_group),
|
||||
module_object=src_group,
|
||||
target_filter={'name': src_group},
|
||||
),
|
||||
child_classes=['spanSpanLbl'],
|
||||
)
|
||||
|
||||
@@ -198,20 +198,20 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='fvTenant',
|
||||
aci_rn='tn-{0}'.format(tenant),
|
||||
filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
|
||||
module_object=tenant,
|
||||
target_filter={'name': tenant},
|
||||
),
|
||||
subclass_1=dict(
|
||||
aci_class='spanSrcGrp',
|
||||
aci_rn='srcgrp-{0}'.format(src_group),
|
||||
filter_target='eq(spanSrcGrp.name, "{0}")'.format(src_group),
|
||||
module_object=src_group,
|
||||
target_filter={'name': src_group},
|
||||
),
|
||||
subclass_2=dict(
|
||||
aci_class='spanSpanLbl',
|
||||
aci_rn='spanlbl-{0}'.format(dst_group),
|
||||
filter_target='eq(spanSpanLbl.name, "{0}")'.format(dst_group),
|
||||
module_object=dst_group,
|
||||
target_filter={'name': dst_group},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -231,8 +231,8 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='fvnsVlanInstP',
|
||||
aci_rn='infra/vlanns-{0}'.format(pool_name),
|
||||
filter_target='eq(fvnsVlanInstP.name, "{0}")'.format(pool),
|
||||
module_object=pool,
|
||||
target_filter={'name': pool},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -275,33 +275,15 @@ def main():
|
||||
if not 1 <= encap_id <= 4094:
|
||||
module.fail_json(msg="vlan pools must have 'block_start' and 'block_end' values between 1 and 4094")
|
||||
|
||||
# Build proper proper filter_target based on block_start, block_end, and block_name
|
||||
if block_end is not None and block_start is not None:
|
||||
# Validate block_start is less than block_end
|
||||
if block_start > block_end:
|
||||
module.fail_json(msg="The 'block_start' must be less than or equal to the 'block_end'")
|
||||
|
||||
if block_name is None:
|
||||
block_filter_target = 'and(eq({0}.from, "{1}"),eq({0}.to, "{2}"))'.format('fvnsEncapBlk', encap_start, encap_end)
|
||||
else:
|
||||
block_filter_target = 'and(eq({0}.from, "{1}"),eq({0}.to, "{2}"),eq({0}.name, "{3}"))'.format('fvnsEncapBlk', encap_start, encap_end, block_name)
|
||||
elif block_end is None and block_start is None:
|
||||
if block_name is None:
|
||||
# Reset range managed object to None for aci util to properly handle query
|
||||
aci_block_mo = None
|
||||
block_filter_target = ''
|
||||
else:
|
||||
block_filter_target = 'eq({0}.name, "{1}")'.format('fvnsEncapBlk', block_name)
|
||||
elif block_start is not None:
|
||||
if block_name is None:
|
||||
block_filter_target = 'eq({0}.from, "{1}")'.format('fvnsEncapBlk', encap_start)
|
||||
else:
|
||||
block_filter_target = 'and(eq({0}.from, "{1}"),eq({0}.name, "{2}"))'.format('fvnsEncapBlk', encap_start, block_name)
|
||||
else:
|
||||
if block_name is None:
|
||||
block_filter_target = 'eq({0}.to, "{1}")'.format('fvnsEncapBlk', encap_end)
|
||||
else:
|
||||
block_filter_target = 'and(eq({0}.to, "{1}"),eq({0}.name, "{2}"))'.format('fvnsEncapBlk', encap_end, block_name)
|
||||
|
||||
# ACI Pool URL requires the allocation mode (ex: uni/infra/vlanns-[poolname]-static)
|
||||
if pool is not None:
|
||||
@@ -315,14 +297,14 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='fvnsVlanInstP',
|
||||
aci_rn='infra/vlanns-{0}'.format(pool_name),
|
||||
filter_target='eq(fvnsVlanInstP.name, "{0}")'.format(pool),
|
||||
module_object=pool,
|
||||
target_filter={'name': pool},
|
||||
),
|
||||
subclass_1=dict(
|
||||
aci_class='fvnsEncapBlk',
|
||||
aci_rn=aci_block_mo,
|
||||
filter_target=block_filter_target,
|
||||
module_object=aci_block_mo,
|
||||
target_filter={'from': encap_start, 'to': encap_end, 'name': block_name},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -235,14 +235,14 @@ def main():
|
||||
root_class=dict(
|
||||
aci_class='fvTenant',
|
||||
aci_rn='tn-{0}'.format(tenant),
|
||||
filter_target='eq(fvTenant.name, "{0}")'.format(tenant),
|
||||
module_object=tenant,
|
||||
target_filter={'name': tenant},
|
||||
),
|
||||
subclass_1=dict(
|
||||
aci_class='fvCtx',
|
||||
aci_rn='ctx-{0}'.format(vrf),
|
||||
filter_target='eq(fvCtx.name, "{0}")'.format(vrf),
|
||||
module_object=vrf,
|
||||
target_filter={'name': vrf},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user