def main(): argument_spec = aci_argument_spec argument_spec.update( ap=dict(type='str', aliases=['app_profile', 'app_profile_name']), epg=dict(type='str', aliases=['epg_name']), contract=dict(type='str', aliases=['contract_name']), contract_type=dict(type='str', required=True, choices=['consumer', 'provider']), priority=dict(type='str', choices=['level1', 'level2', 'level3', 'unspecified']), provider_match=dict(type='str', choices=['all', 'at_least_one', 'at_most_one', 'none']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), tenant=dict(type='str', aliases=['tenant_name']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[['state', 'absent', ['ap', 'contract', 'epg', 'tenant']], ['state', 'present', ['ap', 'contract', 'epg', 'tenant']]] ) contract = module.params['contract'] contract_type = module.params['contract_type'] aci_class = ACI_CLASS_MAPPING[contract_type] priority = module.params['priority'] provider_match = module.params['provider_match'] state = module.params['state'] if contract_type == "consumer" and provider_match is not None: module.fail_json(msg="the 'provider_match' is only configurable for Provided Contracts") # Construct contract_class key and add to module.params for building URL contract_class = 'epg_' + contract_type module.params[contract_class] = contract aci = ACIModule(module) aci.construct_url(root_class='tenant', subclass_1='ap', subclass_2='epg', subclass_3=contract_class) aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload(aci_class=aci_class, class_config=dict(matchT=provider_match, prio=priority, tnVzBrCPName=contract)) # Generate config diff which will be used as POST request body aci.get_diff(aci_class=aci_class) # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() # Remove contract_class that is used to build URL from module.params module.params.pop(contract_class) module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( l2_policy=dict(type='str', required=False, aliases=['name']), # Not required for querying all policies description=dict(type='str', aliases=['descr']), vlan_scope=dict(type='str', choices=['global', 'portlocal']), # No default provided on purpose qinq=dict(type='str', choices=['core', 'disabled', 'edge']), vepa=dict(type='str', choices=['disabled', 'enabled']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['l2_policy']], ['state', 'present', ['l2_policy']], ], ) l2_policy = module.params['l2_policy'] vlan_scope = module.params['vlan_scope'] qinq = module.params['qinq'] if qinq is not None: qinq = QINQ_MAPPING[qinq] vepa = module.params['vepa'] description = module.params['description'] state = module.params['state'] aci = ACIModule(module) aci.construct_url( root_class=dict( aci_class='l2IfPol', aci_rn='infra/l2IfP-{}'.format(l2_policy), filter_target='eq(l2IfPol.name, "{}")'.format(l2_policy), module_object=l2_policy, ), ) aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload( aci_class='l2IfPol', class_config=dict( name=l2_policy, descr=description, vlanScope=vlan_scope, qinq=qinq, vepa=vepa, ), ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='l2IfPol') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( path=dict(type='str', required=True, aliases=['uri']), method=dict(type='str', default='get', choices=['delete', 'get', 'post'], aliases=['action']), src=dict(type='path', aliases=['config_file']), content=dict(type='raw'), ) module = AnsibleModule( argument_spec=argument_spec, mutually_exclusive=[['content', 'src']], ) path = module.params['path'] content = module.params['content'] src = module.params['src'] method = module.params['method'] timeout = module.params['timeout'] # Report missing file file_exists = False if src: if os.path.isfile(src): file_exists = True else: module.fail_json(msg="Cannot find/access src '%s'" % src) # Find request type if path.find('.xml') != -1: rest_type = 'xml' if not HAS_LXML_ETREE: module.fail_json(msg='The lxml python library is missing, or lacks etree support.') if not HAS_XMLJSON_COBRA: module.fail_json(msg='The xmljson python library is missing, or lacks cobra support.') elif path.find('.json') != -1: rest_type = 'json' else: module.fail_json(msg='Failed to find REST API content type (neither .xml nor .json).') aci = ACIModule(module) # We include the payload as it may be templated payload = content if file_exists: with open(src, 'r') as config_object: # TODO: Would be nice to template this, requires action-plugin payload = config_object.read() # Validate content if rest_type == 'json': if content and isinstance(content, dict): # Validate inline YAML/JSON payload = json.dumps(payload) elif payload and isinstance(payload, str) and HAS_YAML: try: # Validate YAML/JSON string payload = json.dumps(yaml.safe_load(payload)) except Exception as e: module.fail_json(msg='Failed to parse provided JSON/YAML content: %s' % to_text(e), exception=to_text(e), payload=payload) elif rest_type == 'xml' and HAS_LXML_ETREE: if content and isinstance(content, dict) and HAS_XMLJSON_COBRA: # Validate inline YAML/JSON # FIXME: Converting from a dictionary to XML is unsupported at this time # payload = etree.tostring(payload) pass elif payload and isinstance(payload, str): try: # Validate XML string payload = lxml.etree.tostring(lxml.etree.fromstring(payload)) except Exception as e: module.fail_json(msg='Failed to parse provided XML content: %s' % to_text(e), payload=payload) # Perform actual request using auth cookie (Same as aci_request,but also supports XML) url = '%(protocol)s://%(hostname)s/' % aci.params + path.lstrip('/') if method != 'get': url = update_qsl(url, {'rsp-subtree': 'modified'}) aci.result['url'] = url resp, info = fetch_url(module, url, data=payload, method=method.upper(), timeout=timeout, headers=aci.headers) aci.result['response'] = info['msg'] aci.result['status'] = info['status'] # Report failure if info['status'] != 200: try: aci_response(aci.result, info['body'], rest_type) module.fail_json(msg='Request failed: %(error_code)s %(error_text)s' % aci.result, payload=payload, **aci.result) except KeyError: module.fail_json(msg='Request failed for %(url)s. %(msg)s' % info, payload=payload, **aci.result) aci_response(aci.result, resp.read(), rest_type) # Report success module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( epg=dict(type='str', aliases=['name', 'epg_name']), bd=dict(type='str', aliases=['bd_name', 'bridge_domain']), ap=dict(type='str', aliases=['app_profile', 'app_profile_name']), tenant=dict(type='str', aliases=['tenant_name']), description=dict(type='str', aliases=['descr']), priority=dict(type='str', choices=['level1', 'level2', 'level3', 'unspecified']), intra_epg_isolation=dict(choices=['enforced', 'unenforced']), fwd_control=dict(type='str', choices=['none', 'proxy-arp']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[['state', 'absent', ['ap', 'epg', 'tenant']], ['state', 'present', ['ap', 'epg', 'tenant']]]) epg = module.params['epg'] bd = module.params['bd'] description = module.params['description'] priority = module.params['priority'] intra_epg_isolation = module.params['intra_epg_isolation'] fwd_control = module.params['fwd_control'] state = module.params['state'] aci = ACIModule(module) aci.construct_url(root_class="tenant", subclass_1="ap", subclass_2="epg", child_classes=['fvRsBd']) aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload( aci_class='fvAEPg', class_config=dict(name=epg, descr=description, prio=priority, pcEnfPref=intra_epg_isolation, fwdCtrl=fwd_control), child_configs=[dict(fvRsBd=dict(attributes=dict(tnFvBDName=bd)))]) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='fvAEPg') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( description=dict(type='str', aliases=['descr']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 policy_control_direction=dict(choices=['ingress', 'egress'], type='str'), policy_control_preference=dict(choices=['enforced', 'unenforced'], type='str'), state=dict(choices=['absent', 'present', 'query'], type='str', default='present'), tenant=dict(type='str', required=False, aliases=['tenant_name' ]), # Not required for querying all objects vrf=dict(type='str', required=False, aliases=['context', 'name', 'vrf_name' ]), # Not required for querying all objects ) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) description = module.params['description'] policy_control_direction = module.params['policy_control_direction'] policy_control_preference = module.params['policy_control_preference'] state = module.params['state'] tenant = module.params['tenant'] vrf = module.params['vrf'] aci = ACIModule(module) if vrf is not None: if tenant is not None: path = 'api/mo/uni/tn-%(tenant)s/ctx-%(vrf)s.json' % module.params elif state == 'query': path = 'api/mo/uni/tn-%(tenant)s.json?rsp-subtree=children&rsp-subtree-class=fvCtx&rsp-subtree-include=no-scoped' % module.params else: module.fail_json( msg= "Parameter 'tenant' is required for state 'absent' or 'present'" ) elif state == 'query': path = 'api/class/fvCtx.json' else: module.fail_json( msg="Parameter 'vrf' is required for state 'absent' or 'present'") aci.result['url'] = '%(protocol)s://%(hostname)s/' % aci.params + path aci.get_existing() if state == 'present': # Filter out module params with null values aci.payload(aci_class='fvCtx', class_config=dict(descr=description, pcEnfDir=policy_control_direction, pcEnfPref=policy_control_preference, name=vrf)) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='fvCtx') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( rtp=dict(type='str', required=False, aliases=['name', 'rtp_name' ]), # Not required for querying all objects tenant=dict(type='str', required=False, aliases=['tenant_name' ]), # Not required for quering all objects description=dict(type='str', aliases=['descr']), tag=dict(type='int'), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['rtp', 'tenant']], ['state', 'present', ['rtp', 'tenant']], ], ) rtp = module.params['rtp'] description = module.params['description'] tag = module.params['tag'] state = module.params['state'] tenant = module.params['tenant'] aci = ACIModule(module) aci.construct_url( root_class=dict( aci_class='fvTenant', aci_rn='tn-{}'.format(tenant), filter_target='(fvTenant.name, "{}")'.format(tenant), module_object=tenant, ), subclass_1=dict( aci_class='l3extRouteTagPol', aci_rn='rttag-{}'.format(rtp), filter_target='(l3extRouteTagPol.name, "{}")'.format(rtp), module_object=rtp, ), ) aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload( aci_class='l3extRouteTagPol', class_config=dict( name=rtp, descr=description, tag=tag, ), ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='l3extRouteTagPol') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( epg=dict(type='str', aliases=['name', 'epg_name']), bd=dict(type='str', aliases=['bd_name', 'bridge_domain']), ap=dict(type='str', aliases=['app_profile', 'app_profile_name']), tenant=dict(type='str', aliases=['tenant_name']), description=dict(type='str', aliases=['descr']), priority=dict(type='str', choices=['level1', 'level2', 'level3', 'unspecified']), intra_epg_isolation=dict(choices=['enforced', 'unenforced']), fwd_control=dict(type='str', choices=['none', 'proxy-arp']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['ap', 'epg', 'tenant']], ['state', 'present', ['ap', 'epg', 'tenant']], ], ) epg = module.params['epg'] bd = module.params['bd'] description = module.params['description'] priority = module.params['priority'] intra_epg_isolation = module.params['intra_epg_isolation'] fwd_control = module.params['fwd_control'] state = module.params['state'] aci = ACIModule(module) aci.construct_url(root_class="tenant", subclass_1="ap", subclass_2="epg", child_classes=['fvRsBd']) aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload( aci_class='fvAEPg', class_config=dict( name=epg, descr=description, prio=priority, pcEnfPref=intra_epg_isolation, fwdCtrl=fwd_control, ), child_configs=[ dict(fvRsBd=dict(attributes=dict(tnFvBDName=bd))), ], ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='fvAEPg') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( contract=dict(type='str', required=False, aliases=['contract_name', 'name']), # Not required for querying all objects tenant=dict(type='str', required=False, aliases=['tenant_name']), # Not required for querying all objects description=dict(type='str', aliases=['descr']), scope=dict(type='str', choices=['application-profile', 'context', 'global', 'tenant']), priority=dict(type='str', choices=['level1', 'level2', 'level3', 'unspecified']), # No default provided on purpose dscp=dict(type='str', choices=['AF11', 'AF12', 'AF13', 'AF21', 'AF22', 'AF23', 'AF31', 'AF32', 'AF33', 'AF41', 'AF42', 'AF43', 'CS0', 'CS1', 'CS2', 'CS3', 'CS4', 'CS5', 'CS6', 'CS7', 'EF', 'VA', 'unspecified'], aliases=['target']), # No default provided on purpose state=dict(type='str', default='present', choices=['absent', 'present', 'query']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['tenant', 'contract']], ['state', 'present', ['tenant', 'contract']], ], ) contract = module.params['contract'] description = module.params['description'] scope = module.params['scope'] priority = module.params['priority'] dscp = module.params['dscp'] state = module.params['state'] tenant = module.params['tenant'] aci = ACIModule(module) aci.construct_url( root_class=dict( aci_class='fvTenant', aci_rn='tn-{}'.format(tenant), filter_target='eq(fvTenant.name, "{}")'.format(tenant), module_object=tenant, ), subclass_1=dict( aci_class='vzBrCP', aci_rn='brc-{}'.format(contract), filter_target='eq(vzBrCP.name, "{}")'.format(contract), module_object=contract, ), ) aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload( aci_class='vzBrCP', class_config=dict( name=contract, descr=description, scope=scope, prio=priority, targetDscp=dscp, ), ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='vzBrCP') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( description=dict(type='str', aliases=['descr']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 policy_control_direction=dict(choices=['ingress', 'egress'], type='str'), policy_control_preference=dict(choices=['enforced', 'unenforced'], type='str'), state=dict(choices=['absent', 'present', 'query'], type='str', default='present'), tenant=dict(type='str', required=False, aliases=['tenant_name']), # Not required for querying all objects vrf=dict(type='str', required=False, aliases=['context', 'name', 'vrf_name']), # Not required for querying all objects ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['tenant', 'vrf']], ['state', 'present', ['tenant', 'vrf']], ], ) description = module.params['description'] policy_control_direction = module.params['policy_control_direction'] policy_control_preference = module.params['policy_control_preference'] state = module.params['state'] tenant = module.params['tenant'] vrf = module.params['vrf'] aci = ACIModule(module) aci.construct_url( root_class=dict( aci_class='fvTenant', aci_rn='tn-{}'.format(tenant), filter_target='eq(fvTenant.name, "{}")'.format(tenant), module_object=tenant, ), subclass_1=dict( aci_class='fvCtx', aci_rn='ctx-{}'.format(vrf), filter_target='eq(fvCtx.name, "{}")'.format(vrf), module_object=vrf, ), ) aci.get_existing() if state == 'present': # Filter out module params with null values aci.payload( aci_class='fvCtx', class_config=dict( descr=description, pcEnfDir=policy_control_direction, pcEnfPref=policy_control_preference, name=vrf, ), ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='fvCtx') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( aep=dict(type='str', aliases=['name', 'aep_name']), # not required for querying all AEPs description=dict(type='str', aliases=['descr']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[['state', 'absent', ['aep']], ['state', 'present', ['aep']]] ) aep = module.params['aep'] description = module.params['description'] state = module.params['state'] aci = ACIModule(module) aci.construct_url(root_class="aep") aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload(aci_class='infraAttEntityP', class_config=dict(name=aep, descr=description)) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='infraAttEntityP') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( bd=dict(type='str', aliases=['bd_name', 'bridge_domain']), l3out=dict(type='str'), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), tenant=dict(type='str', aliases=['tenant_name']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6') # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_together=[['gateway', 'mask']], required_if=[ ['state', 'present', ['bd', 'l3out', 'tenant']], ['state', 'absent', ['bd', 'l3out', 'tenant']], ], ) bd = module.params['bd'] l3out = module.params['l3out'] state = module.params['state'] tenant = module.params['tenant'] aci = ACIModule(module) aci.construct_url( root_class=dict( aci_class='fvTenant', aci_rn='tn-{}'.format(tenant), filter_target='eq(fvTenant.name, "{}")'.format(tenant), module_object=tenant, ), subclass_1=dict( aci_class='fvBD', aci_rn='BD-{}'.format(bd), filter_target='eq(fvBD.name, "{}")'.format(bd), module_object=bd, ), subclass_2=dict( aci_class='fvRsBDToOut', aci_rn='rsBDToOut-{}'.format(l3out), filter_target='eq(fvRsBDToOut.tnL3extOutName, "{}")'.format(l3out), module_object=l3out, ), ) aci.get_existing() if state == 'present': # Filter out module params with null values aci.payload( aci_class='fvRsBDToOut', class_config=dict(tnL3extOutName=l3out), ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='fvRsBDToOut') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( arp_flag=dict(type='str', choices=VALID_ARP_FLAGS), description=dict(type='str'), dst_port=dict(type='str'), dst_port_end=dict(type='str'), dst_port_start=dict(type='str'), entry=dict(type='str', aliases=['entry_name', 'filter_entry', 'name']), ether_type=dict(choices=VALID_ETHER_TYPES, type='str'), filter=dict(type='str', aliases=['filter_name']), icmp_msg_type=dict(type='str', choices=VALID_ICMP_TYPES), icmp6_msg_type=dict(type='str', choices=VALID_ICMP6_TYPES), ip_protocol=dict(choices=VALID_IP_PROTOCOLS, type='str'), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), stateful=dict(type='str', choices=['no', 'yes']), tenant=dict(type="str", aliases=['tenant_name']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['entry', 'filter', 'tenant']], ['state', 'present', ['entry', 'filter', 'tenant']], ], ) arp_flag = module.params['arp_flag'] if arp_flag is not None: arp_flag = ARP_FLAG_MAPPING[arp_flag] description = module.params['description'] dst_port = module.params['dst_port'] if dst_port in FILTER_PORT_MAPPING.keys(): dst_port = FILTER_PORT_MAPPING[dst_port] dst_end = module.params['dst_port_end'] if dst_end in FILTER_PORT_MAPPING.keys(): dst_end = FILTER_PORT_MAPPING[dst_end] dst_start = module.params['dst_port_start'] if dst_start in FILTER_PORT_MAPPING.keys(): dst_start = FILTER_PORT_MAPPING[dst_start] entry = module.params['entry'] ether_type = module.params['ether_type'] filter_name = module.params['filter'] icmp_msg_type = module.params['icmp_msg_type'] if icmp_msg_type is not None: icmp_msg_type = ICMP_MAPPING[icmp_msg_type] icmp6_msg_type = module.params['icmp6_msg_type'] if icmp6_msg_type is not None: icmp6_msg_type = ICMP6_MAPPING[icmp6_msg_type] ip_protocol = module.params['ip_protocol'] state = module.params['state'] stateful = module.params['stateful'] tenant = module.params['tenant'] # validate that dst_port is not passed with dst_start or dst_end if dst_port is not None and (dst_end is not None or dst_start is not None): module.fail_json(msg="Parameter 'dst_port' cannot be used with 'dst_end' and 'dst_start'") elif dst_port is not None: dst_end = dst_port dst_start = dst_port aci = ACIModule(module) aci.construct_url( root_class=dict( aci_class='fvTenant', aci_rn='tn-{}'.format(tenant), filter_target='eq(fvTenant.name, "{}")'.format(tenant), module_object=tenant, ), subclass_1=dict( aci_class='vzFilter', aci_rn='flt-{}'.format(filter_name), filter_target='eq(vzFilter.name, "{}")'.format(filter_name), module_object=filter_name, ), subclass_2=dict( aci_class='vzEntry', aci_rn='e-{}'.format(entry), filter_target='eq(vzEntry.name, "{}")'.format(entry), module_object=entry ), ) aci.get_existing() if state == 'present': # Filter out module params with null values aci.payload( aci_class='vzEntry', class_config=dict( arpOpc=arp_flag, descr=description, dFromPort=dst_start, dToPort=dst_end, etherT=ether_type, icmpv4T=icmp_msg_type, icmpv6T=icmp6_msg_type, name=entry, prot=ip_protocol, stateful=stateful, ), ) # generate config diff which will be used as POST request body aci.get_diff(aci_class='vzEntry') # submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( allow_useg=dict(type='str', choices=['encap', 'useg']), ap=dict(type='str', aliases=['app_profile', 'app_profile_name']), deploy_immediacy=dict(type='str', choices=['immediate', 'on-demand']), domain=dict(type='str', aliases=['domain_name', 'domain_profile']), domain_type=dict(type='str', choices=['phys', 'vmm'], aliases=['type']), encap=dict(type='int'), encap_mode=dict(type='str', choices=['auto', 'vlan', 'vxlan']), epg=dict(type='str', aliases=['name', 'epg_name']), netflow=dict(type='str', choices=['disabled', 'enabled']), primary_encap=dict(type='int'), resolution_immediacy=dict(type='str', choices=['immdediate', 'lazy', 'pre-provision']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), tenant=dict(type='str', aliases=['tenant_name']), vm_provider=dict(type='str', choices=['vmware']), # TODO: Find out OVS and Hyper-V options method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[['domain_type', 'vmm', ['vm_provider']], ['state', 'absent', ['ap', 'domain', 'domain_type', 'epg', 'tenant']], ['state', 'present', ['ap', 'domain', 'domain_type', 'epg', 'tenant']]] ) allow_useg = module.params['allow_useg'] deploy_immediacy = module.params['deploy_immediacy'] domain = module.params['domain'] domain_type = module.params['domain_type'] vm_provider = module.params['vm_provider'] encap = module.params['encap'] if encap is not None: if encap in range(1, 4097): encap = 'vlan-{}'.format(encap) else: module.fail_json(msg='Valid VLAN assigments are from 1 to 4096') encap_mode = module.params['encap_mode'] netflow = module.params['netflow'] primary_encap = module.params['primary_encap'] if primary_encap is not None: if primary_encap in range(1, 4097): primary_encap = 'vlan-{}'.format(primary_encap) else: module.fail_json(msg='Valid VLAN assigments are from 1 to 4096') resolution_immediacy = module.params['resolution_immediacy'] state = module.params['state'] if domain_type == 'phys' and vm_provider is not None: module.fail_json(msg="Domain type 'phys' cannot have a 'vm_provider'") # Compile the full domain and add it to module.params for URL building if domain_type == 'vmm': module.params["epg_domain"] = VM_PROVIDER_MAPPING[vm_provider] + domain elif domain_type is not None: module.params["epg_domain"] = 'uni/phys-' + domain aci = ACIModule(module) aci.construct_url(root_class="tenant", subclass_1="ap", subclass_2="epg", subclass_3="epg_domain") aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload( aci_class='fvRsDomAtt', class_config=dict( classPref=allow_useg, encap=encap, encapMode=encap_mode, instrImedcy=deploy_immediacy, netflowPref=netflow, primaryEncap=primary_encap, resImedcy=resolution_immediacy ) ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='fvRsDomAtt') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() # Pop the epg_domain key that was added for URL building module.params.pop("epg_domain") module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( bd=dict(type='str', aliases=['bd_name']), description=dict(type='str', aliases=['descr']), enable_vip=dict(type='str', choices=['no', 'yes']), gateway=dict(type='str', aliases=['gateway_ip']), mask=dict(type='int', aliases=['subnet_mask']), subnet_name=dict(type='str', aliases=['name']), nd_prefix_policy=dict(type='str'), preferred=dict(type='str', choices=['no', 'yes']), route_profile=dict(type='str'), route_profile_l3_out=dict(type='str'), scope=dict(type='str', choices=['private', 'public', 'shared']), subnet_control=dict(type='str', choices=['nd_ra', 'no_gw', 'querier_ip', 'unspecified']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), tenant=dict(type='str', aliases=['tenant_name']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_together=[['gateway', 'mask']], required_if=[ ['state', 'present', ['bd', 'gateway', 'mask', 'tenant']], ['state', 'absent', ['bd', 'gateway', 'mask', 'tenant']], ], ) description = module.params['description'] enable_vip = module.params['enable_vip'] gateway = module.params['gateway'] mask = module.params['mask'] if mask is not None and mask not in range(0, 129): # TODO: split checkes between IPv4 and IPv6 Addresses module.fail_json(msg='Valid Subnet Masks are 0 to 32 for IPv4 Addresses and 0 to 128 for IPv6 addresses') subnet_name = module.params['subnet_name'] nd_prefix_policy = module.params['nd_prefix_policy'] preferred = module.params['preferred'] route_profile = module.params['route_profile'] route_profile_l3_out = module.params['route_profile_l3_out'] scope = module.params['scope'] state = module.params['state'] subnet_control = module.params['subnet_control'] if subnet_control: subnet_control = SUBNET_CONTROL_MAPPING[subnet_control] # Construct gateway_addr and add to module.params for constructing URL if gateway is not None and mask is not None: gateway_addr = '{}/{}'.format(gateway, str(mask)) module.params['gateway_addr'] = gateway_addr aci = ACIModule(module) aci.construct_url( root_class='tenant', subclass_1='bd', subclass_2='gateway_addr', child_classes=['fvRsBDSubnetToProfile', 'fvRsNdPfxPol'], ) aci.get_existing() if state == 'present': # Filter out module params with null values aci.payload( aci_class='fvSubnet', class_config=dict( ctrl=subnet_control, descr=description, ip=gateway_addr, name=subnet_name, preferred=preferred, scope=scope, virtual=enable_vip, ), child_configs=[ {'fvRsBDSubnetToProfile': {'attributes': {'tnL3extOutName': route_profile_l3_out, 'tnRtctrlProfileName': route_profile}}}, {'fvRsNdPfxPol': {'attributes': {'tnNdPfxPolName': nd_prefix_policy}}}, ], ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='fvSubnet') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() # Remove gateway_addr used to form URL from module.params module.params.pop("gateway_addr", None) module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( arp_flag=dict(type='str', choices=VALID_ARP_FLAGS), description=dict(type='str'), dst_port=dict(type='str'), dst_port_end=dict(type='str'), dst_port_start=dict(type='str'), entry=dict(type='str', aliases=['entry_name', 'filter_entry', 'name']), ether_type=dict(choices=VALID_ETHER_TYPES, type='str'), filter=dict(type='str', aliases=['filter_name']), icmp_msg_type=dict(type='str', choices=VALID_ICMP_TYPES), icmp6_msg_type=dict(type='str', choices=VALID_ICMP6_TYPES), ip_protocol=dict(choices=VALID_IP_PROTOCOLS, type='str'), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), stateful=dict(type='str', choices=['no', 'yes']), tenant=dict(type="str", aliases=['tenant_name']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['entry', 'filter', 'tenant']], ['state', 'present', ['entry', 'filter', 'tenant']], ], ) arp_flag = module.params['arp_flag'] if arp_flag is not None: arp_flag = ARP_FLAG_MAPPING[arp_flag] description = module.params['description'] dst_port = module.params['dst_port'] if dst_port in FILTER_PORT_MAPPING.keys(): dst_port = FILTER_PORT_MAPPING[dst_port] dst_end = module.params['dst_port_end'] if dst_end in FILTER_PORT_MAPPING.keys(): dst_end = FILTER_PORT_MAPPING[dst_end] dst_start = module.params['dst_port_start'] if dst_start in FILTER_PORT_MAPPING.keys(): dst_start = FILTER_PORT_MAPPING[dst_start] entry = module.params['entry'] ether_type = module.params['ether_type'] filter_name = module.params['filter'] icmp_msg_type = module.params['icmp_msg_type'] if icmp_msg_type is not None: icmp_msg_type = ICMP_MAPPING[icmp_msg_type] icmp6_msg_type = module.params['icmp6_msg_type'] if icmp6_msg_type is not None: icmp6_msg_type = ICMP6_MAPPING[icmp6_msg_type] ip_protocol = module.params['ip_protocol'] state = module.params['state'] stateful = module.params['stateful'] tenant = module.params['tenant'] # validate that dst_port is not passed with dst_start or dst_end if dst_port is not None and (dst_end is not None or dst_start is not None): module.fail_json( msg= "Parameter 'dst_port' cannot be used with 'dst_end' and 'dst_start'" ) elif dst_port is not None: dst_end = dst_port dst_start = dst_port aci = ACIModule(module) aci.construct_url( root_class=dict( aci_class='fvTenant', aci_rn='tn-{}'.format(tenant), filter_target='(fvTenant.name, "{}")'.format(tenant), module_object=tenant, ), subclass_1=dict( aci_class='vzFilter', aci_rn='flt-{}'.format(filter_name), filter_target='(vzFilter.name, "{}")'.format(filter_name), module_object=filter_name, ), subclass_2=dict(aci_class='vzEntry', aci_rn='e-{}'.format(entry), filter_target='(vzEntry.name, "{}")'.format(entry), module_object=entry), ) aci.get_existing() if state == 'present': # Filter out module params with null values aci.payload( aci_class='vzEntry', class_config=dict( arpOpc=arp_flag, descr=description, dFromPort=dst_start, dToPort=dst_end, etherT=ether_type, icmpv4T=icmp_msg_type, icmpv6T=icmp6_msg_type, name=entry, prot=ip_protocol, stateful=stateful, ), ) # generate config diff which will be used as POST request body aci.get_diff(aci_class='vzEntry') # submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( compare_export_policy=dict(type='str'), compare_snapshot=dict(type='str'), description=dict(type='str', aliases=['descr']), export_policy=dict(type='str'), fail_on_decrypt=dict(type='bool'), import_mode=dict(type='str', choices=['atomic', 'best-effort']), import_policy=dict(type='str'), import_type=dict(type='str', choices=['merge', 'replace']), snapshot=dict(type='str', required=True), state=dict(type='str', default='rollback', choices=['preview', 'rollback']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=False, required_if=[ ['state', 'preview', ['compare_export_policy', 'compare_snapshot']], ['state', 'rollback', ['import_policy']], ], ) description = module.params['description'] export_policy = module.params['export_policy'] fail_on_decrypt = module.params['fail_on_decrypt'] if fail_on_decrypt is True: fail_on_decrypt = 'yes' elif fail_on_decrypt is False: fail_on_decrypt = 'no' import_mode = module.params['import_mode'] import_policy = module.params['import_policy'] import_type = module.params['import_type'] snapshot = module.params['snapshot'] state = module.params['state'] aci = ACIModule(module) if state == 'rollback': if snapshot.startswith('run-'): snapshot = snapshot.replace('run-', '', 1) if not snapshot.endswith('.tar.gz'): snapshot += '.tar.gz' filename = 'ce2_{}-{}'.format(export_policy, snapshot) aci.construct_url(root_class="import_policy") aci.get_existing() # Filter out module parameters with null values aci.payload( aci_class='configImportP', class_config=dict( adminSt='triggered', descr=description, failOnDecryptErrors=fail_on_decrypt, fileName=filename, importMode=import_mode, importType=import_type, name=import_policy, snapshot='yes', ), ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='configImportP') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'preview': aci.result['url'] = '%(protocol)s://%(hostname)s/mqapi2/snapshots.diff.xml' % module.params aci.result['filter_string'] = ( '?s1dn=uni/backupst/snapshots-[uni/fabric/configexp-%(export_policy)s]/snapshot-%(snapshot)s&' 's2dn=uni/backupst/snapshots-[uni/fabric/configexp-%(compare_export_policy)s]/snapshot-%(compare_snapshot)s' ) % module.params # Generate rollback comparison get_preview(aci) module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( mcp=dict(type='str', required=False, aliases=['mcp_interface', 'name']), # Not required for querying all objects description=dict(type='str', aliases=['descr']), admin_state=dict(type='str', choices=['disabled', 'enabled']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['mcp']], ['state', 'present', ['mcp']], ], ) mcp = module.params['mcp'] description = module.params['description'] admin_state = module.params['admin_state'] state = module.params['state'] aci = ACIModule(module) aci.construct_url(root_class=dict( aci_class='mcpIfPol', aci_rn='infra/mcpIfP-{}'.format(mcp), filter_target='(mcpIfPol.name, "{}")'.format(mcp), module_object=mcp, ), ) aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload( aci_class='mcpIfPol', class_config=dict( name=mcp, descr=description, adminSt=admin_state, ), ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='mcpIfPol') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( tenant=dict(type='str', aliases=['tenant_name']), # not required for querying all EPRs epr_policy=dict(type='str', aliases=['epr_name', 'name']), bounce_age=dict(type='int'), bounce_trigger=dict(type='str', choices=['coop', 'flood']), hold_interval=dict(type='int'), local_ep_interval=dict(type='int'), remote_ep_interval=dict(type='int'), description=dict(type='str', aliases=['descr']), move_frequency=dict(type='int'), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['epr_policy', 'tenant']], ['state', 'present', ['epr_policy', 'tenant']], ], ) epr_policy = module.params['epr_policy'] bounce_age = module.params['bounce_age'] if bounce_age is not None and bounce_age != 0 and bounce_age not in range(150, 65536): module.fail_json(msg="The bounce_age must be a value of 0 or between 150 and 65535") if bounce_age == 0: bounce_age = 'infinite' bounce_trigger = module.params['bounce_trigger'] if bounce_trigger is not None: bounce_trigger = BOUNCE_TRIG_MAPPING[bounce_trigger] description = module.params['description'] hold_interval = module.params['hold_interval'] if hold_interval is not None and hold_interval not in range(5, 65536): module.fail_json(msg="The hold_interval must be a value between 5 and 65535") local_ep_interval = module.params['local_ep_interval'] if local_ep_interval is not None and local_ep_interval != 0 and local_ep_interval not in range(120, 65536): module.fail_json(msg="The local_ep_interval must be a value of 0 or between 120 and 65535") if local_ep_interval == 0: local_ep_interval = "infinite" move_frequency = module.params['move_frequency'] if move_frequency is not None and move_frequency not in range(65536): module.fail_json(msg="The move_frequency must be a value between 0 and 65535") if move_frequency == 0: move_frequency = "none" remote_ep_interval = module.params['remote_ep_interval'] if remote_ep_interval is not None and remote_ep_interval not in range(120, 65536): module.fail_json(msg="The remote_ep_interval must be a value of 0 or between 120 and 65535") if remote_ep_interval == 0: remote_ep_interval = "infinite" state = module.params['state'] aci = ACIModule(module) aci.construct_url(root_class='tenant', subclass_1='epr_policy') aci.get_existing() if state == 'present': # filter out module parameters with null values aci.payload( aci_class='fvEpRetPol', class_config=dict( name=epr_policy, descr=description, bounceAgeIntvl=bounce_age, bounceTrig=bounce_trigger, holdIntvl=hold_interval, localEpAgeIntvl=local_ep_interval, remoteEpAgeIntvl=remote_ep_interval, moveFreq=move_frequency, ), ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='fvEpRetPol') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( admin_state=dict(type='str', choices=['enabled', 'disabled']), description=dict(type='str', aliases=['descr']), dst_group=dict(type='str'), src_group=dict(type='str', required=False, aliases=['name' ]), # Not required for querying all objects state=dict(type='str', default='present', choices=['absent', 'present', 'query']), tenant=dict(type='str', required=False, aliases=['tenant_name' ]), # Not required for querying all objects method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[['state', 'absent', ['src_group', 'tenant']], ['state', 'present', ['src_group', 'tenant']]], ) admin_state = module.params['admin_state'] description = module.params['description'] dst_group = module.params['dst_group'] src_group = module.params['src_group'] state = module.params['state'] # Add tenant_span_dst_grp to module.params for URL building module.params['tenant_span_src_grp'] = src_group aci = ACIModule(module) aci.construct_url(root_class='tenant', subclass_1='tenant_span_src_grp', child_classes=['spanSpanLbl']) aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload( aci_class='spanSrcGrp', class_config=dict(adminSt=admin_state, descr=description, name=src_group), child_configs=[{ 'spanSpanLbl': { 'attributes': { 'name': dst_group } } }], ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='spanSrcGrp') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() # Remove tenant_span_src_grp that was used to build URL from module.params module.params.pop('tenant_span_src_grp') module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( contract=dict(type='str', aliases=['contract_name']), filter=dict(type='str', aliases=['filter_name']), log=dict(tyep='str', choices=['log', 'none'], aliases=['directive']), subject=dict(type='str', aliases=['contract_subject', 'subject_name']), tenant=dict(type='str', aliases=['tenant_name']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[['state', 'absent', ['contract', 'filter', 'subject', 'tenant']], ['state', 'present', ['contract', 'filter', 'subject', 'tenant']]] ) # contract = module.params['contract'] filter_name = module.params['filter'] log = module.params['log'] # subject = module.params['subject'] # tenant = module.params['tenant'] state = module.params['state'] # Add subject_filter key to modul.params for building the URL module.params['subject_filter'] = filter_name # Convert log to empty string if none, as that is what API expects. An empty string is not a good option to present the user. if log == 'none': log = '' aci = ACIModule(module) aci.construct_url(root_class='tenant', subclass_1='contract', subclass_2='subject', subclass_3='subject_filter') aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload(aci_class='vzRsSubjFiltAtt', class_config=dict(tnVzFilterName=filter_name, directives=log)) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='vzRsSubjFiltAtt') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() # Remove subject_filter used to build URL from module.params module.params.pop('subject_filter') module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( path=dict(type='str', required=True, aliases=['uri']), method=dict(type='str', default='get', choices=['delete', 'get', 'post'], aliases=['action']), src=dict(type='path', aliases=['config_file']), content=dict(type='str'), ) module = AnsibleModule( argument_spec=argument_spec, mutually_exclusive=[['content', 'src']], supports_check_mode=True, ) path = module.params['path'] content = module.params['content'] src = module.params['src'] method = module.params['method'] timeout = module.params['timeout'] # Report missing file file_exists = False if src: if os.path.isfile(src): file_exists = True else: module.fail_json(msg="Cannot find/access src '%s'" % src) # Find request type if path.find('.xml') != -1: rest_type = 'xml' if not HAS_LXML_ETREE: module.fail_json( msg= 'The lxml python library is missing, or lacks etree support.') if not HAS_XMLJSON_COBRA: module.fail_json( msg= 'The xmljson python library is missing, or lacks cobra support.' ) elif path.find('.json') != -1: rest_type = 'json' else: module.fail_json( msg='Failed to find REST API content type (neither .xml nor .json).' ) aci = ACIModule(module) if method == 'get': aci.request(path) module.exit_json(**aci.result) elif module.check_mode: # In check_mode we assume it works, but we don't actually perform the requested change # TODO: Could we turn this request in a GET instead ? aci.result['changed'] = True module.exit_json(response='OK (Check mode)', status=200, **aci.result) # Prepare request data if content: # We include the payload as it may be templated payload = content elif file_exists: with open(src, 'r') as config_object: # TODO: Would be nice to template this, requires action-plugin payload = config_object.read() # Perform actual request using auth cookie (Same as aci_request,but also supports XML) url = '%(protocol)s://%(hostname)s/' % aci.params + path.lstrip('/') resp, info = fetch_url(module, url, data=payload, method=method.upper(), timeout=timeout, headers=aci.headers) aci.result['response'] = info['msg'] aci.result['status'] = info['status'] # Report failure if info['status'] != 200: try: aci_response(aci.result, info['body'], rest_type) module.fail_json( msg='Request failed: %(error_code)s %(error_text)s' % aci.result, **aci.result) except KeyError: module.fail_json(msg='Request failed for %(url)s. %(msg)s' % info, **aci.result) aci_response(aci.result, resp.read(), rest_type) # Report success module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( lldp_policy=dict(type='str', require=False, aliases=['name']), description=dict(type='str', aliases=['descr']), receive_state=dict(type='str', choices=['disabled', 'enabled']), transmit_state=dict(type='str', choices=['disabled', 'enabled']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['lldp_policy']], ['state', 'present', ['lldp_policy']], ], ) lldp_policy = module.params['lldp_policy'] description = module.params['description'] receive_state = module.params['receive_state'] transmit_state = module.params['transmit_state'] state = module.params['state'] aci = ACIModule(module) aci.construct_url(root_class='lldp_policy') aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload( aci_class='lldpIfPol', class_config=dict( name=lldp_policy, descr=description, adminRxSt=receive_state, adminTxSt=transmit_state, ), ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='lldpIfPol') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( taboo_contract=dict( type='str', required=False, aliases=['name']), # Not required for querying all contracts tenant=dict(type='str', required=False, aliases=['tenant_name' ]), # Not required for querying all contracts scope=dict( type='str', choices=['application-profile', 'context', 'global', 'tenant']), description=dict(type='str', aliases=['descr']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['tenant', 'taboo_contract']], ['state', 'present', ['tenant', 'taboo_contract']], ], ) taboo_contract = module.params['taboo_contract'] description = module.params['description'] scope = module.params['scope'] state = module.params['state'] aci = ACIModule(module) aci.construct_url(root_class='tenant', subclass_1='taboo_contract') aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload( aci_class='vzTaboo', class_config=dict( name=taboo_contract, descr=description, scope=scope, ), ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='vzTaboo') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( ap=dict(type='str', aliases=['app_profile', 'app_profile_name']), epg=dict(type='str', aliases=['epg_name']), contract=dict(type='str', aliases=['contract_name']), contract_type=dict(type='str', required=True, choices=['consumer', 'provider']), priority=dict(type='str', choices=['level1', 'level2', 'level3', 'unspecified']), provider_match=dict( type='str', choices=['all', 'at_least_one', 'at_most_one', 'none']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), tenant=dict(type='str', aliases=['tenant_name']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['ap', 'contract', 'epg', 'tenant']], ['state', 'present', ['ap', 'contract', 'epg', 'tenant']], ], ) ap = module.params['ap'] contract = module.params['contract'] contract_type = module.params['contract_type'] epg = module.params['epg'] priority = module.params['priority'] provider_match = module.params['provider_match'] if provider_match is not None: provider_match = PROVIDER_MATCH_MAPPING[provider_match] state = module.params['state'] tenant = module.params['tenant'] aci_class = ACI_CLASS_MAPPING[contract_type]["class"] aci_rn = ACI_CLASS_MAPPING[contract_type]["rn"] if contract_type == "consumer" and provider_match is not None: module.fail_json( msg= "the 'provider_match' is only configurable for Provided Contracts") aci = ACIModule(module) aci.construct_url( root_class=dict( aci_class='fvTenant', aci_rn='tn-{}'.format(tenant), filter_target='(fvTenant.name, "{}")'.format(tenant), module_object=tenant, ), subclass_1=dict( aci_class='fvAp', aci_rn='ap-{}'.format(ap), filter_target='(fvAp.name, "{}")'.format(ap), module_object=ap, ), subclass_2=dict( aci_class='fvAEPg', aci_rn='epg-{}'.format(epg), filter_target='(fvAEPg.name, "{}")'.format(epg), module_object=epg, ), subclass_3=dict( aci_class=aci_class, aci_rn='{}{}'.format(aci_rn, contract), filter_target='({}.tnVzBrCPName, "{}'.format(aci_class, contract), module_object=contract, ), ) aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload( aci_class=aci_class, class_config=dict( matchT=provider_match, prio=priority, tnVzBrCPName=contract, ), ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class=aci_class) # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( filter=dict(type='str', required=False, aliases=['name', 'filter_name' ]), # Not required for querying all objects tenant=dict(type='str', required=True, aliases=['tenant_name' ]), # Not required for querying all objects description=dict(type='str', aliases=['descr']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, ) filter_name = module.params['filter'] tenant = module.params['tenant'] description = module.params['description'] state = module.params['state'] aci = ACIModule(module) # TODO: Currently we require a tenant for a query, we could make this optional # TODO: Investigate for a URI to query objects for a specific tenant if filter_name is not None: # Work with a specific object path = 'api/mo/uni/tn-%(tenant)s/flt-%(filter_name)s.json' % module.params elif state == 'query': # Query all objects path = 'api/node/class/vzFilter.json' else: module.fail_json( msg="Parameter 'filter' is required for state 'absent' or 'present'" ) aci.result['url'] = '%(protocol)s://%(hostname)s/' % aci.params + path aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload(aci_class='vzFilter', class_config=dict(name=filter_name, descr=description)) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='vzFilter') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( ap=dict(type='str', aliases=['app_profile', 'app_profile_name']), epg=dict(type='str', aliases=['epg_name']), contract=dict(type='str', aliases=['contract_name']), contract_type=dict(type='str', required=True, choices=['consumer', 'provider']), priority=dict(type='str', choices=['level1', 'level2', 'level3', 'unspecified']), provider_match=dict(type='str', choices=['all', 'at_least_one', 'at_most_one', 'none']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), tenant=dict(type='str', aliases=['tenant_name']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['ap', 'contract', 'epg', 'tenant']], ['state', 'present', ['ap', 'contract', 'epg', 'tenant']], ], ) ap = module.params['ap'] contract = module.params['contract'] contract_type = module.params['contract_type'] epg = module.params['epg'] priority = module.params['priority'] provider_match = module.params['provider_match'] if provider_match is not None: provider_match = PROVIDER_MATCH_MAPPING[provider_match] state = module.params['state'] tenant = module.params['tenant'] aci_class = ACI_CLASS_MAPPING[contract_type]["class"] aci_rn = ACI_CLASS_MAPPING[contract_type]["rn"] if contract_type == "consumer" and provider_match is not None: module.fail_json(msg="the 'provider_match' is only configurable for Provided Contracts") aci = ACIModule(module) aci.construct_url( root_class=dict( aci_class='fvTenant', aci_rn='tn-{}'.format(tenant), filter_target='eq(fvTenant.name, "{}")'.format(tenant), module_object=tenant, ), subclass_1=dict( aci_class='fvAp', aci_rn='ap-{}'.format(ap), filter_target='eq(fvAp.name, "{}")'.format(ap), module_object=ap, ), subclass_2=dict( aci_class='fvAEPg', aci_rn='epg-{}'.format(epg), filter_target='eq(fvAEPg.name, "{}")'.format(epg), module_object=epg, ), subclass_3=dict( aci_class=aci_class, aci_rn='{}{}'.format(aci_rn, contract), filter_target='eq({}.tnVzBrCPName, "{}'.format(aci_class, contract), module_object=contract, ), ) aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload( aci_class=aci_class, class_config=dict( matchT=provider_match, prio=priority, tnVzBrCPName=contract, ), ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class=aci_class) # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( description=dict(type='str', aliases=['descr']), dst_group=dict(type='str'), src_group=dict(type='str'), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), tenant=dict(type='str', aliases=['tenant_name']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['dst_group', 'src_group', 'tenant']], ['state', 'present', ['dst_group', 'src_group', 'tenant']], ], ) description = module.params['description'] dst_group = module.params['dst_group'] src_group = module.params['src_group'] state = module.params['state'] # Add tenant_span_src_grp and tenant_span_src_grp_dst_grp to module.params for URL building module.params['tenant_span_src_grp'] = src_group module.params['tenant_span_src_grp_dst_grp'] = dst_group aci = ACIModule(module) aci.construct_url(root_class='tenant', subclass_1='tenant_span_src_grp', subclass_2='tenant_span_src_grp_dst_grp') aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload( aci_class='spanSpanLbl', class_config=dict( descr=description, name=dst_group, ), ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='spanSpanLbl') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() # Remove tenant_span_src_grp and tenant_span_src_grp_dst_grp that was used to build URL from module.params module.params.pop('tenant_span_src_grp') module.params.pop('tenant_span_src_grp_dst_grp') module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( port_channel=dict(type='str', required=False, aliases=['name' ]), # Not required for querying all objects description=dict(type='str', aliases=['descr']), min_links=dict(type='int'), max_links=dict(type='int'), mode=dict( type='str', choices=['off', 'mac-pin', 'active', 'passive', 'mac-pin-nicload']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, ) port_channel = module.params['port_channel'] description = module.params['description'] # TODO: Validate min_links is in the acceptable range min_links = module.params['min_link'] # TODO: Validate max_links is in the acceptable range min_links = str(min_links) max_links = module.params['max_link'] max_links = str(max_links) mode = module.params['mode'] state = module.params['state'] aci = ACIModule(module) # TODO: This logic could be cleaner. if port_channel is not None: path = 'api/mo/uni/infra/lacplagp-%(port_channel)s.json' % module.params elif state == 'query': # Query all objects path = 'api/node/class/lacplagPol.json' else: module.fail_json( msg= "Parameter 'port_channel' is required for state 'absent' or 'present'" ) aci.result['url'] = '%(protocol)s://%(hostname)s/' % aci.params + path aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload(aci_class='lacpLagPol', class_config=dict(name=port_channel, descr=description, minLinks=min_links, maxLinks=max_links, mode=mode)) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='lacpLagPol') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( contract=dict(type='str', aliases=['contract_name']), filter=dict(type='str', aliases=['filter_name']), log=dict(tyep='str', choices=['log', 'none'], aliases=['directive']), subject=dict(type='str', aliases=['contract_subject', 'subject_name']), tenant=dict(type='str', aliases=['tenant_name']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['contract', 'filter', 'subject', 'tenant']], ['state', 'present', ['contract', 'filter', 'subject', 'tenant']], ], ) contract = module.params['contract'] filter_name = module.params['filter'] log = module.params['log'] subject = module.params['subject'] tenant = module.params['tenant'] state = module.params['state'] # Add subject_filter key to modul.params for building the URL module.params['subject_filter'] = filter_name # Convert log to empty string if none, as that is what API expects. An empty string is not a good option to present the user. if log == 'none': log = '' aci = ACIModule(module) aci.construct_url( root_class=dict( aci_class='fvTenant', aci_rn='tn-{}'.format(tenant), filter_target='eq(fvTenant.name, "{}")'.format(tenant), module_object=tenant, ), subclass_1=dict( aci_class='vzBrCP', aci_rn='brc-{}'.format(contract), filter_target='eq(vzBrCP.name, "{}")'.format(contract), module_object=contract, ), subclass_2=dict( aci_class='vzSubj', aci_rn='subj-{}'.format(subject), filter_target='eq(vzSubj.name, "{}")'.format(subject), module_object=subject, ), subclass_3=dict( aci_class='vzRsSubjFiltAtt', aci_rn='rssubjFiltAtt-{}'.format(filter_name), filter_target='eq(vzRsSubjFiltAtt.tnVzFilterName, "{}")'.format( filter_name), module_object=filter_name, ), ) aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload( aci_class='vzRsSubjFiltAtt', class_config=dict( tnVzFilterName=filter_name, directives=log, ), ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='vzRsSubjFiltAtt') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() # Remove subject_filter used to build URL from module.params module.params.pop('subject_filter') module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( bd=dict(type='str', aliases=['bd_name']), description=dict(type='str', aliases=['descr']), enable_vip=dict(type='str', choices=['no', 'yes']), gateway=dict(type='str', aliases=['gateway_ip']), mask=dict(type='int', aliases=['subnet_mask']), subnet_name=dict(type='str', aliases=['name']), nd_prefix_policy=dict(type='str'), preferred=dict(type='str', choices=['no', 'yes']), route_profile=dict(type='str'), route_profile_l3_out=dict(type='str'), scope=dict(type='str', choices=['private', 'public', 'shared']), subnet_control=dict( type='str', choices=['nd_ra', 'no_gw', 'querier_ip', 'unspecified']), state=dict(type='str', choices=['absent', 'present', 'query']), tenant=dict(type='str', aliases=['tenant_name']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_together=[['gateway', 'mask']], required_if=[ ['state', 'present', ['bd', 'gateway', 'mask', 'tenant']], ['state', 'absent', ['bd', 'gateway', 'mask', 'tenant']], ], ) description = module.params['description'] enable_vip = module.params['enable_vip'] gateway = module.params['gateway'] mask = module.params['mask'] if mask is not None and mask not in range(0, 129): # TODO: split checkes between IPv4 and IPv6 Addresses module.fail_json( msg= 'Valid Subnet Masks are 0 to 32 for IPv4 Addresses and 0 to 128 for IPv6 addresses' ) subnet_name = module.params['subnet_name'] nd_prefix_policy = module.params['nd_prefix_policy'] preferred = module.params['preferred'] route_profile = module.params['route_profile'] route_profile_l3_out = module.params['route_profile_l3_out'] scope = module.params['scope'] state = module.params['state'] subnet_control = module.params['subnet_control'] if subnet_control: subnet_control = SUBNET_CONTROL_MAPPING[subnet_control] # Construct gateway_addr and add to module.params for constructing URL if gateway is not None and mask is not None: gateway_addr = '{}/{}'.format(gateway, str(mask)) module.params['gateway_addr'] = gateway_addr aci = ACIModule(module) aci.construct_url( root_class='tenant', subclass_1='bd', subclass_2='gateway_addr', child_classes=['fvRsBDSubnetToProfile', 'fvRsNdPfxPol'], ) aci.get_existing() if state == 'present': # Filter out module params with null values aci.payload( aci_class='fvSubnet', class_config=dict( ctrl=subnet_control, descr=description, ip=gateway_addr, name=subnet_name, preferred=preferred, scope=scope, virtual=enable_vip, ), child_configs=[ { 'fvRsBDSubnetToProfile': { 'attributes': { 'tnL3extOutName': route_profile_l3_out, 'tnRtctrlProfileName': route_profile } } }, { 'fvRsNdPfxPol': { 'attributes': { 'tnNdPfxPolName': nd_prefix_policy } } }, ], ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='fvSubnet') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() # Remove gateway_addr used to form URL from module.params module.params.pop("gateway_addr", None) module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( compare_export_policy=dict(type='str'), compare_snapshot=dict(type='str'), description=dict(type='str', aliases=['descr']), export_policy=dict(type='str'), fail_on_decrypt=dict(type='bool'), import_mode=dict(type='str', choices=['atomic', 'best-effort']), import_policy=dict(type='str'), import_type=dict(type='str', choices=['merge', 'replace']), snapshot=dict(type='str', required=True), state=dict(type='str', default='rollback', choices=['preview', 'rollback']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=False, required_if=[ [ 'state', 'preview', ['compare_export_policy', 'compare_snapshot'] ], ['state', 'rollback', ['import_policy']], ], ) description = module.params['description'] export_policy = module.params['export_policy'] fail_on_decrypt = module.params['fail_on_decrypt'] if fail_on_decrypt is True: fail_on_decrypt = 'yes' elif fail_on_decrypt is False: fail_on_decrypt = 'no' import_mode = module.params['import_mode'] import_policy = module.params['import_policy'] import_type = module.params['import_type'] snapshot = module.params['snapshot'] state = module.params['state'] aci = ACIModule(module) if state == 'rollback': if snapshot.startswith('run-'): snapshot = snapshot.replace('run-', '', 1) if not snapshot.endswith('.tar.gz'): snapshot += '.tar.gz' filename = 'ce2_{0}-{1}'.format(export_policy, snapshot) aci.construct_url(root_class="import_policy") aci.get_existing() # Filter out module parameters with null values aci.payload( aci_class='configImportP', class_config=dict( adminSt='triggered', descr=description, failOnDecryptErrors=fail_on_decrypt, fileName=filename, importMode=import_mode, importType=import_type, name=import_policy, snapshot='yes', ), ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='configImportP') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'preview': aci.result[ 'url'] = '%(protocol)s://%(hostname)s/mqapi2/snapshots.diff.xml' % module.params aci.result['filter_string'] = ( '?s1dn=uni/backupst/snapshots-[uni/fabric/configexp-%(export_policy)s]/snapshot-%(snapshot)s&' 's2dn=uni/backupst/snapshots-[uni/fabric/configexp-%(compare_export_policy)s]/snapshot-%(compare_snapshot)s' ) % module.params # Generate rollback comparison get_preview(aci) module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( tenant=dict(type='str', aliases=['tenant_name' ]), # tenant not required for querying all anps app_profile=dict(type='str', aliases=['app_profile_name', 'name']), description=dict(type='str', aliases=['descr'], required=False), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[['state', 'absent', ['tenant', 'app_profile']], ['state', 'present', ['tenant', 'app_profile']]]) tenant = module.params['tenant'] app_profile = module.params['app_profile'] description = module.params['description'] state = module.params['state'] aci = ACIModule(module) if tenant is not None and app_profile is not None: path = 'api/mo/uni/tn-%(tenant)s/ap-%(app_profile)s.json' % module.params filter_string = '' elif tenant is None and app_profile is None: path = 'api/class/fvAp.json' filter_string = '' elif tenant is not None: path = 'api/mo/uni/tn-%(tenant)s.json' % module.params filter_string = '?rsp-subtree=children&rsp-subtree-class=fvAp&rsp-subtree-include=no-scoped' else: path = 'api/class/fvAp.json' filter_string = '?query-target-filter=eq(fvAp.name, \"%(app_profile)s\")' % module.params aci.result['url'] = '%(protocol)s://%(hostname)s/' % aci.params + path aci.get_existing(filter_string=filter_string) if state == 'present': # Filter out module parameters with null values aci.payload(aci_class='fvAp', class_config=dict(name=app_profile, descr=description)) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='fvAp') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( aep=dict(type='str', aliases=['name', 'aep_name']), # not required for querying all AEPs description=dict(type='str', aliases=['descr']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['aep']], ['state', 'present', ['aep']], ], ) aep = module.params['aep'] description = module.params['description'] state = module.params['state'] aci = ACIModule(module) aci.construct_url(root_class=dict( aci_class='infraAttEntityP', aci_rn='infra/attentp-{}'.format(aep), filter_target='eq(infraAttEntityP.name, "{}")'.format(aep), module_object=aep, ), ) aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload( aci_class='infraAttEntityP', class_config=dict( name=aep, descr=description, ), ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='infraAttEntityP') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( port_security=dict(type='str', required=False, aliases=['name']), # Not required for querying all objects description=dict(type='str', aliases=['descr']), max_end_points=dict(type='int'), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['port_security']], ['state', 'present', ['port_security']], ], ) port_security = module.params['port_security'] description = module.params['description'] max_end_points = module.params['max_end_points'] if max_end_points is not None and max_end_points not in range(12001): module.fail_json(msg='The "max_end_points" must be between 0 and 12000') state = module.params['state'] aci = ACIModule(module) aci.construct_url(root_class='port_security') aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload( aci_class='l2PortSecurityPol', class_config=dict( name=port_security, descr=description, maximum=max_end_points, ), ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='l2PortSecurityPol') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( port_channel=dict(type='str', required=False, aliases=['name']), # Not required for querying all objects description=dict(type='str', aliases=['descr']), min_links=dict(type='int'), max_links=dict(type='int'), mode=dict(type='str', choices=['off', 'mac-pin', 'active', 'passive', 'mac-pin-nicload']), fast_select=dict(type='bool'), graceful_convergence=dict(type='bool'), load_defer=dict(type='bool'), suspend_individual=dict(type='bool'), symmetric_hash=dict(type='bool'), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['port_channel']], ['state', 'present', ['port_channel']], ], ) port_channel = module.params['port_channel'] description = module.params['description'] min_links = module.params['min_links'] if min_links is not None and min_links not in range(1, 17): module.fail_json(msg='The "min_links" must be a value between 1 and 16') max_links = module.params['max_links'] if max_links is not None and max_links not in range(1, 17): module.fail_json(msg='The "max_links" must be a value between 1 and 16') mode = module.params['mode'] state = module.params['state'] # Build ctrl value for request ctrl = [] if module.params['fast_select'] is True: ctrl.append('fast-sel-hot-stdby') if module.params['graceful_convergence'] is True: ctrl.append('graceful-conv') if module.params['load_defer'] is True: ctrl.append('load-defer') if module.params['suspend_individual'] is True: ctrl.append('susp-individual') if module.params['symmetric_hash'] is True: ctrl.append('symmetric-hash') if not ctrl: ctrl = None else: ctrl = ",".join(ctrl) aci = ACIModule(module) aci.construct_url( root_class=dict( aci_class='lacpLagPol', aci_rn='infra/lacplagp-{}'.format(port_channel), filter_target='eq(lacpLagPol.name, "{}")'.format(port_channel), module_object=port_channel, ), ) aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload( aci_class='lacpLagPol', class_config=dict( name=port_channel, ctrl=ctrl, descr=description, minLinks=min_links, maxLinks=max_links, mode=mode, ), ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='lacpLagPol') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( port_security=dict(type='str', required=False, aliases=['name']), # Not required for querying all objects description=dict(type='str', aliases=['descr']), max_end_points=dict(type='int'), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[['state', 'absent', ['port_security']], ['state', 'present', ['port_security']]], ) port_security = module.params['port_security'] description = module.params['description'] max_end_points = module.params['max_end_points'] if max_end_points is not None and max_end_points not in range(12001): module.fail_json(msg='The "max_end_points" must be between 0 and 12000') state = module.params['state'] aci = ACIModule(module) aci.construct_url(root_class='port_security') aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload( aci_class='l2PortSecurityPol', class_config=dict(name=port_security, descr=description, maximum=max_end_points), ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='l2PortSecurityPol') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( tenant=dict(type='str', aliases=['tenant_name' ]), # not required for querying all EPRs epr_policy=dict(type='str', aliases=['epr_name', 'name']), bounce_age=dict(type='int'), bounce_trigger=dict(type='str', choices=['coop', 'flood']), hold_interval=dict(type='int'), local_ep_interval=dict(type='int'), remote_ep_interval=dict(type='int'), description=dict(type='str', aliases=['descr']), move_frequency=dict(type='int'), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['epr_policy', 'tenant']], ['state', 'present', ['epr_policy', 'tenant']], ], ) epr_policy = module.params['epr_policy'] bounce_age = module.params['bounce_age'] if bounce_age is not None and bounce_age != 0 and bounce_age not in range( 150, 65536): module.fail_json( msg="The bounce_age must be a value of 0 or between 150 and 65535") if bounce_age == 0: bounce_age = 'infinite' bounce_trigger = module.params['bounce_trigger'] if bounce_trigger is not None: bounce_trigger = BOUNCE_TRIG_MAPPING[bounce_trigger] description = module.params['description'] hold_interval = module.params['hold_interval'] if hold_interval is not None and hold_interval not in range(5, 65536): module.fail_json( msg="The hold_interval must be a value between 5 and 65535") local_ep_interval = module.params['local_ep_interval'] if local_ep_interval is not None and local_ep_interval != 0 and local_ep_interval not in range( 120, 65536): module.fail_json( msg= "The local_ep_interval must be a value of 0 or between 120 and 65535" ) if local_ep_interval == 0: local_ep_interval = "infinite" move_frequency = module.params['move_frequency'] if move_frequency is not None and move_frequency not in range(65536): module.fail_json( msg="The move_frequency must be a value between 0 and 65535") if move_frequency == 0: move_frequency = "none" remote_ep_interval = module.params['remote_ep_interval'] if remote_ep_interval is not None and remote_ep_interval not in range( 120, 65536): module.fail_json( msg= "The remote_ep_interval must be a value of 0 or between 120 and 65535" ) if remote_ep_interval == 0: remote_ep_interval = "infinite" state = module.params['state'] tenant = module.params['tenant'] aci = ACIModule(module) aci.construct_url( root_class=dict( aci_class='fvTenant', aci_rn='tn-{}'.format(tenant), filter_target='(fvTenant.name, "{}")'.format(tenant), module_object=tenant, ), subclass_1=dict( aci_class='fvEpRetPol', aci_rn='epRPol-{}'.format(epr_policy), filter_target='(fvEpRetPol.name, "{}")'.format(epr_policy), module_object=epr_policy, ), ) aci.get_existing() if state == 'present': # filter out module parameters with null values aci.payload( aci_class='fvEpRetPol', class_config=dict( name=epr_policy, descr=description, bounceAgeIntvl=bounce_age, bounceTrig=bounce_trigger, holdIntvl=hold_interval, localEpAgeIntvl=local_ep_interval, remoteEpAgeIntvl=remote_ep_interval, moveFreq=move_frequency, ), ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='fvEpRetPol') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( epg=dict(type='str', aliases=['name', 'epg_name']), bridge_domain=dict(type='str', aliases=['bd_name']), app_profile=dict(type='str', aliases=['app_profile_name']), tenant=dict(type='str', aliases=['tenant_name']), description=dict(type='str', aliases=['descr']), priority=dict(type='str', choices=['level1', 'level2', 'level3', 'unspecified']), intra_epg_isolation=dict(choices=['enforced', 'unenforced']), fwd_control=dict(type='str', choices=['none', 'proxy-arp']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[['state', 'absent', ['app_profile', 'epg', 'tenant']], ['state', 'present', ['app_profile', 'epg', 'tenant']]]) epg = module.params['epg'] # app_profile = module.params['app_profile'] # tenant = module.params['tenant'] bridge_domain = module.params['bridge_domain'] description = module.params['description'] priority = module.params['priority'] intra_epg_isolation = module.params['intra_epg_isolation'] fwd_control = module.params['fwd_control'] state = module.params['state'] aci = ACIModule(module) # TODO: Add logic to handle multiple input variations when query if state != 'query': # Work with a specific EPG path = 'api/mo/uni/tn-%(tenant)s/ap-%(app_profile)s/epg-%(epg)s.json' % module.params filter_string = '?rsp-subtree=children&rsp-subtree-class=fvRsBd&rsp-prop-include=config-only' else: # Query all EPGs path = 'api/class/fvAEPg.json' filter_string = '?rsp-subtree=children&rsp-subtree-class=fvRsBd' aci.result['url'] = '%(protocol)s://%(hostname)s/' % aci.params + path aci.get_existing(filter_string=filter_string) if state == 'present': # Filter out module parameters with null values aci.payload( aci_class='fvAEPg', class_config=dict(name=epg, descr=description, prio=priority, pcEnfPref=intra_epg_isolation, fwdCtrl=fwd_control), child_configs=[ dict(fvRsBd=dict(attributes=dict(tnFvBDName=bridge_domain))) ]) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='fvAEPg') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( arp_flooding=dict(choices=['no', 'yes']), bd=dict(type='str', aliases=['bd_name', 'name']), bd_type=dict(type='str', choices=['ethernet', 'fc']), description=dict(type='str'), enable_multicast=dict(type='str', choices=['no', 'yes']), enable_routing=dict(type='str', choices=['no', 'yes']), endpoint_clear=dict(type='str', choices=['no', 'yes']), endpoint_move_detect=dict(type='str', choices=['default', 'garp']), endpoint_retention_action=dict(type='str', choices=['inherit', 'resolve']), endpoint_retention_policy=dict(type='str'), igmp_snoop_policy=dict(type='str'), ip_learning=dict(type='str', choices=['no', 'yes']), ipv6_nd_policy=dict(type='str'), l2_unknown_unicast=dict(choices=['proxy', 'flood']), l3_unknown_multicast=dict(choices=['flood', 'opt-flood']), limit_ip_learn=dict(type='str', choices=['no', 'yes']), multi_dest=dict(choices=['bd-flood', 'drop', 'encap-flood']), state=dict(choices=['absent', 'present', 'query'], type='str', default='present'), tenant=dict(type='str', aliases=['tenant_name']), vrf=dict(type='str', aliases=['vrf_name']), gateway_ip=dict(type='str', removed_in_version='2.4'), # Deprecated starting from v2.4 method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 scope=dict(type='str', removed_in_version='2.4'), # Deprecated starting from v2.4 subnet_mask=dict(type='str', removed_in_version='2.4'), # Deprecated starting from v2.4 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['bd', 'tenant']], ['state', 'present', ['bd', 'tenant']], ], ) arp_flooding = module.params['arp_flooding'] bd = module.params['bd'] bd_type = module.params['bd_type'] if bd_type == 'ethernet': # ethernet type is represented as regular, but that is not clear to the users bd_type = 'regular' description = module.params['description'] enable_multicast = module.params['enable_multicast'] enable_routing = module.params['enable_routing'] endpoint_clear = module.params['endpoint_clear'] endpoint_move_detect = module.params['endpoint_move_detect'] if endpoint_move_detect == 'default': # the ACI default setting is an empty string, but that is not a good input value endpoint_move_detect = '' endpoint_retention_action = module.params['endpoint_retention_action'] endpoint_retention_policy = module.params['endpoint_retention_policy'] igmp_snoop_policy = module.params['igmp_snoop_policy'] ip_learning = module.params['ip_learning'] ipv6_nd_policy = module.params['ipv6_nd_policy'] l2_unknown_unicast = module.params['l2_unknown_unicast'] l3_unknown_multicast = module.params['l3_unknown_multicast'] limit_ip_learn = module.params['limit_ip_learn'] multi_dest = module.params['multi_dest'] state = module.params['state'] tenant = module.params['tenant'] vrf = module.params['vrf'] # Give warning when fvSubnet parameters are passed as those have been moved to the aci_subnet module if module.params['gateway_ip'] or module.params['subnet_mask'] or module.params['scope']: module._warnings = ["The support for managing Subnets has been moved to its own module, aci_subnet. \ The new modules still supports 'gateway_ip' and 'subnet_mask' along with more features"] aci = ACIModule(module) aci.construct_url( root_class=dict( aci_class='fvTenant', aci_rn='tn-{}'.format(tenant), filter_target='(fvTenant.name, "{}")'.format(tenant), module_object=tenant, ), subclass_1=dict( aci_class='fvBD', aci_rn='BD-{}'.format(bd), filter_target='(fvBD.name, "{}")'.format(bd), module_object=bd, ), child_classes=['fvRsCtx', 'fvRsIgmpsn', 'fvRsBDToNdP', 'fvRsBdToEpRet'], ) aci.get_existing() if state == 'present': # Filter out module params with null values aci.payload( aci_class='fvBD', class_config=dict( arpFlood=arp_flooding, descr=description, epClear=endpoint_clear, epMoveDetectMode=endpoint_move_detect, ipLearning=ip_learning, limitIpLearnToSubnets=limit_ip_learn, mcastAllow=enable_multicast, multiDstPktAct=multi_dest, name=bd, type=bd_type, unicastRoute=enable_routing, unkMacUcastAct=l2_unknown_unicast, unkMcastAct=l3_unknown_multicast, ), child_configs=[ {'fvRsCtx': {'attributes': {'tnFvCtxName': vrf}}}, {'fvRsIgmpsn': {'attributes': {'tnIgmpSnoopPolName': igmp_snoop_policy}}}, {'fvRsBDToNdP': {'attributes': {'tnNdIfPolName': ipv6_nd_policy}}}, {'fvRsBdToEpRet': {'attributes': {'resolveAct': endpoint_retention_action, 'tnFvEpRetPolName': endpoint_retention_policy}}}, ], ) # generate config diff which will be used as POST request body aci.get_diff(aci_class='fvBD') # submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( rtp=dict(type='str', required=False, aliases=['name', 'rtp_name' ]), # Not required for querying all objects tenant=dict(type='str', required=False, aliases=['tenant_name' ]), # Not required for quering all objects description=dict(type='str', aliases=['descr']), tag=dict(type='int'), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, ) rtp = module.params['rtp'] tenant = module.params['tenant'] description = module.params['description'] tag = module.params['tag'] state = module.params['state'] aci = ACIModule(module) if rtp is not None: # Work with a specific object if tenant is not None: path = 'api/mo/uni/tn-%(tenant)s/rttag-%(rtp)s.json' % module.params else: path = 'api/class/l3extRouteTagPol.json?query-target-filter=eq(l3extRouteTagPol.name,"%(rtp)s")' % module.params elif state == 'query': # Query all objects if tenant is not None: path = 'api/mo/uni/tn-%(tenant)s.json?rsp-subtree=children&rsp-subtree-class=l3extRouteTagPol&rsp-subtree-include=no-scoped' % module.params else: path = 'api/node/class/l3extRouteTagPol.json' else: module.fail_json( msg="Parameter 'rtp' is required for state 'absent' or 'present'") aci.result['url'] = '%(protocol)s://%(hostname)s/' % aci.params + path aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload(aci_class='l3extRouteTagPol', class_config=dict(name=rtp, descr=description, tag=tag)) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='l3extRouteTagPol') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( allow_useg=dict(type='str', choices=['encap', 'useg']), ap=dict(type='str', aliases=['app_profile', 'app_profile_name']), deploy_immediacy=dict(type='str', choices=['immediate', 'on-demand']), domain=dict(type='str', aliases=['domain_name', 'domain_profile']), domain_type=dict(type='str', choices=['phys', 'vmm'], aliases=['type']), encap=dict(type='int'), encap_mode=dict(type='str', choices=['auto', 'vlan', 'vxlan']), epg=dict(type='str', aliases=['name', 'epg_name']), netflow=dict(type='str', choices=['disabled', 'enabled']), primary_encap=dict(type='int'), resolution_immediacy=dict( type='str', choices=['immediate', 'lazy', 'pre-provision']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), tenant=dict(type='str', aliases=['tenant_name']), vm_provider=dict(type='str', choices=['microsoft', 'openstack', 'vmware']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['domain_type', 'vmm', ['vm_provider']], [ 'state', 'absent', ['ap', 'domain', 'domain_type', 'epg', 'tenant'] ], [ 'state', 'present', ['ap', 'domain', 'domain_type', 'epg', 'tenant'] ], ], ) allow_useg = module.params['allow_useg'] ap = module.params['ap'] deploy_immediacy = module.params['deploy_immediacy'] domain = module.params['domain'] domain_type = module.params['domain_type'] vm_provider = module.params['vm_provider'] encap = module.params['encap'] if encap is not None: if encap in range(1, 4097): encap = 'vlan-{}'.format(encap) else: module.fail_json(msg='Valid VLAN assigments are from 1 to 4096') encap_mode = module.params['encap_mode'] epg = module.params['epg'] netflow = module.params['netflow'] primary_encap = module.params['primary_encap'] if primary_encap is not None: if primary_encap in range(1, 4097): primary_encap = 'vlan-{}'.format(primary_encap) else: module.fail_json(msg='Valid VLAN assigments are from 1 to 4096') resolution_immediacy = module.params['resolution_immediacy'] state = module.params['state'] tenant = module.params['tenant'] if domain_type == 'phys' and vm_provider is not None: module.fail_json(msg="Domain type 'phys' cannot have a 'vm_provider'") # Compile the full domain for URL building if domain_type == 'vmm': epg_domain = '{}{}'.format(VM_PROVIDER_MAPPING[vm_provider], domain) elif domain_type is not None: epg_domain = 'uni/phys-{}'.format(domain) else: epg_domain = None aci = ACIModule(module) aci.construct_url( root_class=dict( aci_class='fvTenant', aci_rn='tn-{}'.format(tenant), filter_target='(fvTenant.name, "{}")'.format(tenant), module_object=tenant, ), subclass_1=dict( aci_class='fvAp', aci_rn='ap-{}'.format(ap), filter_target='(fvAp.name, "{}")'.format(ap), module_object=ap, ), subclass_2=dict( aci_class='fvAEPg', aci_rn='epg-{}'.format(epg), filter_target='(fvTenant.name, "{}")'.format(epg), module_object=epg, ), subclass_3=dict( aci_class='fvRsDomAtt', aci_rn='rsdomAtt-[{}]'.format(epg_domain), filter_target='(fvRsDomAtt.tDn, "{}")'.format(epg_domain), module_object=epg_domain, ), ) aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload( aci_class='fvRsDomAtt', class_config=dict( classPref=allow_useg, encap=encap, encapMode=encap_mode, instrImedcy=deploy_immediacy, netflowPref=netflow, primaryEncap=primary_encap, resImedcy=resolution_immediacy, ), ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='fvRsDomAtt') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( port_channel=dict(type='str', required=False, aliases=['name' ]), # Not required for querying all objects description=dict(type='str', aliases=['descr']), min_links=dict(type='int'), max_links=dict(type='int'), mode=dict( type='str', choices=['off', 'mac-pin', 'active', 'passive', 'mac-pin-nicload']), fast_select=dict(type='bool'), graceful_convergence=dict(type='bool'), load_defer=dict(type='bool'), suspend_individual=dict(type='bool'), symmetric_hash=dict(type='bool'), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['port_channel']], ['state', 'present', ['port_channel']], ], ) port_channel = module.params['port_channel'] description = module.params['description'] min_links = module.params['min_links'] if min_links is not None and min_links not in range(1, 17): module.fail_json( msg='The "min_links" must be a value between 1 and 16') max_links = module.params['max_links'] if max_links is not None and max_links not in range(1, 17): module.fail_json( msg='The "max_links" must be a value between 1 and 16') mode = module.params['mode'] state = module.params['state'] # Build ctrl value for request ctrl = [] if module.params['fast_select'] is True: ctrl.append('fast-sel-hot-stdby') if module.params['graceful_convergence'] is True: ctrl.append('graceful-conv') if module.params['load_defer'] is True: ctrl.append('load-defer') if module.params['suspend_individual'] is True: ctrl.append('susp-individual') if module.params['symmetric_hash'] is True: ctrl.append('symmetric-hash') if not ctrl: ctrl = None else: ctrl = ",".join(ctrl) aci = ACIModule(module) aci.construct_url(root_class='port_channel') aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload( aci_class='lacpLagPol', class_config=dict( name=port_channel, ctrl=ctrl, descr=description, minLinks=min_links, maxLinks=max_links, mode=mode, ), ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='lacpLagPol') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( dst_group=dict(type='str', required=False, aliases=['name' ]), # Not required for querying all objects tenant=dict(type='str', required=True, aliases=['tenant_name' ]), # Not required for querying all objects description=dict(type='str', aliases=['descr']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, ) dst_group = module.params['dst_group'] # tenant = module.params['tenant'] description = module.params['description'] state = module.params['state'] aci = ACIModule(module) # TODO: This logic could be cleaner. if dst_group is not None: path = 'api/mo/uni/tn-%(tenant)s/destgrp-%(dst_group)s.json' % module.params elif state == 'query': # Query all contracts path = 'api/node/class/spanDestGrp.json' else: module.fail_json( msg= "Parameter 'dst_group' is required for state 'absent' or 'present'" ) aci.result['url'] = '%(protocol)s://%(hostname)s/' % aci.params + path aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload(aci_class='spanDestGrp', class_config=dict(name=dst_group, descr=description)) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='spanDestGrp') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( contract=dict(type='str', aliases=['contract_name']), subject=dict(type='str', aliases=['contract_subject', 'name', 'subject_name']), tenant=dict(type='str', aliases=['tenant_name']), priority=dict(type='str', choices=['unspecified', 'level1', 'level2', 'level3']), reverse_filter=dict(type='str', choices=['yes', 'no']), dscp=dict(type='str', aliases=['target']), description=dict(type='str', aliases=['descr']), consumer_match=dict(type='str', choices=['all', 'at_least_one', 'at_most_one', 'none']), provider_match=dict(type='str', choices=['all', 'at_least_one', 'at_most_one', 'none']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 directive=dict(type='str', removed_in_version='2.4'), # Deprecated starting from v2.4 filter=dict(type='str', aliases=['filter_name'], removed_in_version='2.4'), # Deprecated starting from v2.4 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['contract', 'subject', 'tenant']], ['state', 'present', ['contract', 'subject', 'tenant']], ], ) subject = module.params['subject'] priority = module.params['priority'] reverse_filter = module.params['reverse_filter'] dscp = module.params['dscp'] description = module.params['description'] filter_name = module.params['filter'] directive = module.params['directive'] consumer_match = module.params['consumer_match'] provider_match = module.params['provider_match'] state = module.params['state'] if directive is not None or filter_name is not None: module.fail_json(msg='Managing Contract Subjects to Filter bindings has been moved to M(aci_subject_bind_filter)') aci = ACIModule(module) aci.construct_url(root_class='tenant', subclass_1='contract', subclass_2='subject') aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload( aci_class='vzSubj', class_config=dict( name=subject, prio=priority, revFltPorts=reverse_filter, targetDscp=dscp, consMatchT=consumer_match, provMatchT=provider_match, descr=description, ), ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='vzSubj') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( filter=dict(type='str', required=False, aliases=['name', 'filter_name']), # Not required for querying all objects tenant=dict(type='str', required=False, aliases=['tenant_name']), # Not required for querying all objects description=dict(type='str', aliases=['descr']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[['state', 'absent', ['filter', 'tenant']], ['state', 'present', ['filter', 'tenant']]] ) filter_name = module.params['filter'] description = module.params['description'] state = module.params['state'] aci = ACIModule(module) aci.construct_url(root_class="tenant", subclass_1="filter") aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload( aci_class='vzFilter', class_config=dict(name=filter_name, descr=description) ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='vzFilter') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( path=dict(type='str', required=True, aliases=['uri']), method=dict(type='str', default='get', choices=['delete', 'get', 'post'], aliases=['action']), src=dict(type='path', aliases=['config_file']), content=dict(type='raw'), ) module = AnsibleModule( argument_spec=argument_spec, mutually_exclusive=[['content', 'src']], ) path = module.params['path'] content = module.params['content'] src = module.params['src'] method = module.params['method'] timeout = module.params['timeout'] # Report missing file file_exists = False if src: if os.path.isfile(src): file_exists = True else: module.fail_json(msg="Cannot find/access src '%s'" % src) # Find request type if path.find('.xml') != -1: rest_type = 'xml' if not HAS_LXML_ETREE: module.fail_json( msg= 'The lxml python library is missing, or lacks etree support.') if not HAS_XMLJSON_COBRA: module.fail_json( msg= 'The xmljson python library is missing, or lacks cobra support.' ) elif path.find('.json') != -1: rest_type = 'json' else: module.fail_json( msg='Failed to find REST API content type (neither .xml nor .json).' ) aci = ACIModule(module) # We include the payload as it may be templated payload = content if file_exists: with open(src, 'r') as config_object: # TODO: Would be nice to template this, requires action-plugin payload = config_object.read() # Validate content if rest_type == 'json': if content and isinstance(content, dict): # Validate inline YAML/JSON payload = json.dumps(payload) elif payload and isinstance(payload, str) and HAS_YAML: try: # Validate YAML/JSON string payload = json.dumps(yaml.safe_load(payload)) except Exception as e: module.fail_json( msg='Failed to parse provided JSON/YAML content: %s' % to_text(e), exception=to_text(e), payload=payload) elif rest_type == 'xml' and HAS_LXML_ETREE: if content and isinstance(content, dict) and HAS_XMLJSON_COBRA: # Validate inline YAML/JSON # FIXME: Converting from a dictionary to XML is unsupported at this time # payload = etree.tostring(payload) pass elif payload and isinstance(payload, str): try: # Validate XML string payload = lxml.etree.tostring(lxml.etree.fromstring(payload)) except Exception as e: module.fail_json( msg='Failed to parse provided XML content: %s' % to_text(e), payload=payload) # Perform actual request using auth cookie (Same as aci_request,but also supports XML) url = '%(protocol)s://%(hostname)s/' % aci.params + path.lstrip('/') if method != 'get': url = update_qsl(url, {'rsp-subtree': 'modified'}) aci.result['url'] = url resp, info = fetch_url(module, url, data=payload, method=method.upper(), timeout=timeout, headers=aci.headers) aci.result['response'] = info['msg'] aci.result['status'] = info['status'] # Report failure if info['status'] != 200: try: aci_response(aci.result, info['body'], rest_type) module.fail_json( msg='Request failed: %(error_code)s %(error_text)s' % aci.result, payload=payload, **aci.result) except KeyError: module.fail_json(msg='Request failed for %(url)s. %(msg)s' % info, payload=payload, **aci.result) aci_response(aci.result, resp.read(), rest_type) # Report success module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( contract=dict(type='str', aliases=['contract_name']), filter_name=dict(type='str'), log=dict(tyep='str', choices=['log', 'none'], aliases=['directive']), subject=dict(type='str', aliases=['subject_name']), tenant=dict(type='str', aliases=['tenant_name']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[['state', 'absent', ['contract', 'filter_name', 'subject', 'tenant']], ['state', 'present', ['contract', 'filter_name', 'subject', 'tenant']]] ) # contract = module.params['contract'] filter_name = module.params['filter_name'] log = module.params['log'] # subject = module.params['subject'] # tenant = module.params['tenant'] state = module.params['state'] # Convert log to empty string if none, as that is what API expects. An empty string is not a good option to present the user. if log == 'none': log = '' # TODO: cleanup this logic and provide better filter_strings for all options if filter_name is not None: # Work with specific binding path = 'api/mo/uni/tn-%(tenant)s/brc-%(contract)s/subj-%(subject)s/rssubjFiltAtt-%(filter_name)s.json' % module.params else: path = 'api/class/vzRsSubjFiltAtt.json' aci = ACIModule(module) aci.result['url'] = '%(protocol)s://%(hostname)s/' % aci.params + path aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload(aci_class='vzRsSubjFiltAtt', class_config=dict(tnVzFilterName=filter_name, directives=log)) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='vzRsSubjFiltAtt') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( lldp_policy=dict(type='str', require=False, aliases=['name']), description=dict(type='str', aliases=['descr']), receive_state=dict(type='str', choices=['disabled', 'enabled']), transmit_state=dict(type='str', choices=['disabled', 'enabled']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, ) lldp_policy = module.params['lldp_policy'] description = module.params['description'] receive_state = module.params['receive_state'] transmit_state = module.params['transmit_state'] state = module.params['state'] aci = ACIModule(module) if lldp_policy is not None: # Work with a specific object path = 'api/mo/uni/infra/lldpIfP-%(lldp_policy)s.json' % module.params elif state == 'query': # Query all objects path = 'api/node/class/lldpIfPol.json' else: module.fail_json( msg= "Parameter 'lldp_policy' is required for state 'absent' or 'present'" ) aci.result['url'] = '%(protocol)s://%(hostname)s/' % aci.params + path aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload(aci_class='lldpIfPol', class_config=dict(name=lldp_policy, descr=description, adminRxSt=receive_state, adminTxSt=transmit_state)) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='lldpIfPol') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( monitoring_policy=dict(type='str', required=False, aliases=['name']), # Not required for querying all objects tenant=dict(type='str', required=False, aliases=['tenant_name']), # Not required for querying all objects description=dict(type='str', aliases=['descr']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['monitoring_policy', 'tenant']], ['state', 'present', ['monitoring_policy', 'tenant']], ], ) monitoring_policy = module.params['monitoring_policy'] description = module.params['description'] state = module.params['state'] tenant = module.params['tenant'] aci = ACIModule(module) aci.construct_url( root_class=dict( aci_class='fvTenant', aci_rn='tn-{}'.format(tenant), filter_target='eq(fvTenant.name, "{}")'.format(tenant), module_object=tenant, ), subclass_1=dict( aci_class='monEPGPol', aci_rn='monepg-{}'.format(monitoring_policy), filter_target='eq(monEPGPol.name, "{}")'.format(monitoring_policy), module_object=monitoring_policy, ), ) aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload( aci_class='monEPGPol', class_config=dict( name=monitoring_policy, descr=description, ), ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='monEPGPol') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( contract=dict(type='str', aliases=['contract_name']), subject=dict(type='str', aliases=['contract_subject', 'name', 'subject_name']), tenant=dict(type='str', aliases=['tenant_name']), priority=dict(type='str', choices=['unspecified', 'level1', 'level2', 'level3']), reverse_filter=dict(type='str', choices=['yes', 'no']), dscp=dict(type='str', aliases=['target']), description=dict(type='str', aliases=['descr']), consumer_match=dict( type='str', choices=['all', 'at_least_one', 'at_most_one', 'none']), provider_match=dict( type='str', choices=['all', 'at_least_one', 'at_most_one', 'none']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 directive=dict( type='str', removed_in_version='2.4'), # Deprecated starting from v2.4 filter=dict(type='str', aliases=['filter_name'], removed_in_version='2.4'), # Deprecated starting from v2.4 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['contract', 'subject', 'tenant']], ['state', 'present', ['contract', 'subject', 'tenant']], ], ) subject = module.params['subject'] priority = module.params['priority'] reverse_filter = module.params['reverse_filter'] dscp = module.params['dscp'] description = module.params['description'] filter_name = module.params['filter'] directive = module.params['directive'] consumer_match = module.params['consumer_match'] provider_match = module.params['provider_match'] state = module.params['state'] if directive is not None or filter_name is not None: module.fail_json( msg= 'Managing Contract Subjects to Filter bindings has been moved to M(aci_subject_bind_filter)' ) aci = ACIModule(module) aci.construct_url(root_class='tenant', subclass_1='contract', subclass_2='subject') aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload( aci_class='vzSubj', class_config=dict( name=subject, prio=priority, revFltPorts=reverse_filter, targetDscp=dscp, consMatchT=consumer_match, provMatchT=provider_match, descr=description, ), ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='vzSubj') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( arp_flooding=dict(choices=['no', 'yes']), bd=dict(type='str', aliases=['bd_name', 'name']), bd_type=dict(type='str', choices=['ethernet', 'fc']), description=dict(type='str'), enable_multicast=dict(type='str', choices=['no', 'yes']), enable_routing=dict(type='str', choices=['no', 'yes']), endpoint_clear=dict(type='str', choices=['no', 'yes']), endpoint_move_detect=dict(type='str', choices=['default', 'garp']), endpoint_retention_action=dict(type='str', choices=['inherit', 'resolve']), endpoint_retention_policy=dict(type='str'), igmp_snoop_policy=dict(type='str'), ip_learning=dict(type='str', choices=['no', 'yes']), ipv6_nd_policy=dict(type='str'), l2_unknown_unicast=dict(choices=['proxy', 'flood']), l3_unknown_multicast=dict(choices=['flood', 'opt-flood']), limit_ip_learn=dict(type='str', choices=['no', 'yes']), multi_dest=dict(choices=['bd-flood', 'drop', 'encap-flood']), state=dict(choices=['absent', 'present', 'query'], type='str', default='present'), tenant=dict(type='str', aliases=['tenant_name']), vrf=dict(type='str', aliases=['vrf_name']), gateway_ip=dict(type='str', removed_in_version='2.4'), # Deprecated starting from v2.4 method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 scope=dict(type='str', removed_in_version='2.4'), # Deprecated starting from v2.4 subnet_mask=dict(type='str', removed_in_version='2.4'), # Deprecated starting from v2.4 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['bd', 'tenant']], ['state', 'present', ['bd', 'tenant']], ], ) arp_flooding = module.params['arp_flooding'] bd = module.params['bd'] bd_type = module.params['bd_type'] if bd_type == 'ethernet': # ethernet type is represented as regular, but that is not clear to the users bd_type = 'regular' description = module.params['description'] enable_multicast = module.params['enable_multicast'] enable_routing = module.params['enable_routing'] endpoint_clear = module.params['endpoint_clear'] endpoint_move_detect = module.params['endpoint_move_detect'] if endpoint_move_detect == 'default': # the ACI default setting is an empty string, but that is not a good input value endpoint_move_detect = '' endpoint_retention_action = module.params['endpoint_retention_action'] endpoint_retention_policy = module.params['endpoint_retention_policy'] igmp_snoop_policy = module.params['igmp_snoop_policy'] ip_learning = module.params['ip_learning'] ipv6_nd_policy = module.params['ipv6_nd_policy'] l2_unknown_unicast = module.params['l2_unknown_unicast'] l3_unknown_multicast = module.params['l3_unknown_multicast'] limit_ip_learn = module.params['limit_ip_learn'] multi_dest = module.params['multi_dest'] state = module.params['state'] vrf = module.params['vrf'] # Give warning when fvSubnet parameters are passed as those have been moved to the aci_subnet module if module.params['gateway_ip'] or module.params['subnet_mask'] or module.params['scope']: module._warnings = ["The support for managing Subnets has been moved to its own module, aci_subnet. \ The new modules still supports 'gateway_ip' and 'subnet_mask' along with more features"] aci = ACIModule(module) aci.construct_url(root_class="tenant", subclass_1="bd", child_classes=['fvRsCtx', 'fvRsIgmpsn', 'fvRsBDToNdP', 'fvRsBdToEpRet']) aci.get_existing() if state == 'present': # Filter out module params with null values aci.payload( aci_class='fvBD', class_config=dict( arpFlood=arp_flooding, descr=description, epClear=endpoint_clear, epMoveDetectMode=endpoint_move_detect, ipLearning=ip_learning, limitIpLearnToSubnets=limit_ip_learn, mcastAllow=enable_multicast, multiDstPktAct=multi_dest, name=bd, type=bd_type, unicastRoute=enable_routing, unkMacUcastAct=l2_unknown_unicast, unkMcastAct=l3_unknown_multicast, ), child_configs=[ {'fvRsCtx': {'attributes': {'tnFvCtxName': vrf}}}, {'fvRsIgmpsn': {'attributes': {'tnIgmpSnoopPolName': igmp_snoop_policy}}}, {'fvRsBDToNdP': {'attributes': {'tnNdIfPolName': ipv6_nd_policy}}}, {'fvRsBdToEpRet': {'attributes': {'resolveAct': endpoint_retention_action, 'tnFvEpRetPolName': endpoint_retention_policy}}}, ], ) # generate config diff which will be used as POST request body aci.get_diff(aci_class='fvBD') # submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( description=dict(type='str', aliases=['descr']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 policy_control_direction=dict(choices=['ingress', 'egress'], type='str'), policy_control_preference=dict(choices=['enforced', 'unenforced'], type='str'), state=dict(choices=['absent', 'present', 'query'], type='str', default='present'), tenant=dict(type='str', required=False, aliases=['tenant_name' ]), # Not required for querying all objects vrf=dict(type='str', required=False, aliases=['context', 'name', 'vrf_name' ]), # Not required for querying all objects ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['state', 'absent', ['tenant', 'vrf']], ['state', 'present', ['tenant', 'vrf']], ], ) description = module.params['description'] policy_control_direction = module.params['policy_control_direction'] policy_control_preference = module.params['policy_control_preference'] state = module.params['state'] tenant = module.params['tenant'] vrf = module.params['vrf'] aci = ACIModule(module) aci.construct_url( root_class=dict( aci_class='fvTenant', aci_rn='tn-{}'.format(tenant), filter_target='(fvTenant.name, "{}")'.format(tenant), module_object=tenant, ), subclass_1=dict( aci_class='fvCtx', aci_rn='ctx-{}'.format(vrf), filter_target='(fvCtx.name, "{}")'.format(vrf), module_object=vrf, ), ) aci.get_existing() if state == 'present': # Filter out module params with null values aci.payload( aci_class='fvCtx', class_config=dict( descr=description, pcEnfDir=policy_control_direction, pcEnfPref=policy_control_preference, name=vrf, ), ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='fvCtx') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( description=dict(type='str', aliases=['descr']), export_policy=dict(type='str', aliases=['name']), format=dict(type='str', choices=['json', 'xml']), include_secure=dict(type='str', choices=['no', 'yes']), max_count=dict(type='int'), snapshot=dict(type='str'), state=dict(type='str', choices=['absent', 'present', 'query'], default='present'), ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=False, required_if=[ ['state', 'absent', ['export_policy', 'snapshot']], ['state', 'present', ['export_policy']], ], ) description = module.params['description'] export_policy = module.params['export_policy'] file_format = module.params['format'] include_secure = module.params['include_secure'] max_count = module.params['max_count'] if max_count is not None: if max_count in range(1, 11): max_count = str(max_count) else: module.fail_json(msg='The "max_count" must be a number between 1 and 10') snapshot = module.params['snapshot'] if snapshot is not None and not snapshot.startswith('run-'): snapshot = 'run-' + snapshot state = module.params['state'] aci = ACIModule(module) if state == 'present': aci.construct_url( root_class=dict( aci_class='configExportP', aci_rn='fabric/configexp-{}'.format(export_policy), filter_target='eq(configExportP.name, "{}")'.format(export_policy), module_object=export_policy, ), ) aci.get_existing() # Filter out module params with null values aci.payload( aci_class='configExportP', class_config=dict( adminSt='triggered', descr=description, format=file_format, includeSecureFields=include_secure, maxSnapshotCount=max_count, name=export_policy, snapshot='yes', ), ) aci.get_diff('configExportP') # Create a new Snapshot aci.post_config() else: # Prefix the proper url to export_policy if export_policy is not None: export_policy = 'uni/fabric/configexp-{}'.format(export_policy) aci.construct_url( root_class=dict( aci_class='configSnapshotCont', aci_rn='backupst/snapshots-[{}]'.format(export_policy), filter_target='(configSnapshotCont.name, "{}")'.format(export_policy), module_object=export_policy, ), subclass_1=dict( aci_class='configSnapshot', aci_rn='snapshot-{}'.format(snapshot), filter_target='(configSnapshot.name, "{}")'.format(snapshot), module_object=snapshot, ), ) aci.get_existing() if state == 'absent': # Build POST request to used to remove Snapshot aci.payload( aci_class='configSnapshot', class_config=dict( name=snapshot, retire="yes", ), ) if aci.result['existing']: aci.get_diff('configSnapshot') # Mark Snapshot for Deletion aci.post_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( allow_useg=dict(type='str', choices=['encap', 'useg']), ap=dict(type='str', aliases=['app_profile', 'app_profile_name']), deploy_immediacy=dict(type='str', choices=['immediate', 'on-demand']), domain=dict(type='str', aliases=['domain_name', 'domain_profile']), domain_type=dict(type='str', choices=['phys', 'vmm'], aliases=['type']), encap=dict(type='int'), encap_mode=dict(type='str', choices=['auto', 'vlan', 'vxlan']), epg=dict(type='str', aliases=['name', 'epg_name']), netflow=dict(type='str', choices=['disabled', 'enabled']), primary_encap=dict(type='int'), resolution_immediacy=dict(type='str', choices=['immediate', 'lazy', 'pre-provision']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), tenant=dict(type='str', aliases=['tenant_name']), vm_provider=dict(type='str', choices=['microsoft', 'openstack', 'vmware']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6'), # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[ ['domain_type', 'vmm', ['vm_provider']], ['state', 'absent', ['ap', 'domain', 'domain_type', 'epg', 'tenant']], ['state', 'present', ['ap', 'domain', 'domain_type', 'epg', 'tenant']], ], ) allow_useg = module.params['allow_useg'] ap = module.params['ap'] deploy_immediacy = module.params['deploy_immediacy'] domain = module.params['domain'] domain_type = module.params['domain_type'] vm_provider = module.params['vm_provider'] encap = module.params['encap'] if encap is not None: if encap in range(1, 4097): encap = 'vlan-{}'.format(encap) else: module.fail_json(msg='Valid VLAN assigments are from 1 to 4096') encap_mode = module.params['encap_mode'] epg = module.params['epg'] netflow = module.params['netflow'] primary_encap = module.params['primary_encap'] if primary_encap is not None: if primary_encap in range(1, 4097): primary_encap = 'vlan-{}'.format(primary_encap) else: module.fail_json(msg='Valid VLAN assigments are from 1 to 4096') resolution_immediacy = module.params['resolution_immediacy'] state = module.params['state'] tenant = module.params['tenant'] if domain_type == 'phys' and vm_provider is not None: module.fail_json(msg="Domain type 'phys' cannot have a 'vm_provider'") # Compile the full domain for URL building if domain_type == 'vmm': epg_domain = '{}{}'.format(VM_PROVIDER_MAPPING[vm_provider], domain) elif domain_type is not None: epg_domain = 'uni/phys-{}'.format(domain) else: epg_domain = None aci = ACIModule(module) aci.construct_url( root_class=dict( aci_class='fvTenant', aci_rn='tn-{}'.format(tenant), filter_target='eq(fvTenant.name, "{}")'.format(tenant), module_object=tenant, ), subclass_1=dict( aci_class='fvAp', aci_rn='ap-{}'.format(ap), filter_target='eq(fvAp.name, "{}")'.format(ap), module_object=ap, ), subclass_2=dict( aci_class='fvAEPg', aci_rn='epg-{}'.format(epg), filter_target='eq(fvTenant.name, "{}")'.format(epg), module_object=epg, ), subclass_3=dict( aci_class='fvRsDomAtt', aci_rn='rsdomAtt-[{}]'.format(epg_domain), filter_target='eq(fvRsDomAtt.tDn, "{}")'.format(epg_domain), module_object=epg_domain, ), ) aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload( aci_class='fvRsDomAtt', class_config=dict( classPref=allow_useg, encap=encap, encapMode=encap_mode, instrImedcy=deploy_immediacy, netflowPref=netflow, primaryEncap=primary_encap, resImedcy=resolution_immediacy, ), ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='fvRsDomAtt') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( lldp_policy=dict(type='str', require=False, aliases=['name']), description=dict(type='str', aliases=['descr']), receive_state=dict(type='str', choices=['disabled', 'enabled']), transmit_state=dict(type='str', choices=['disabled', 'enabled']), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6') # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_if=[['state', 'absent', ['lldp_policy']], ['state', 'present', ['lldp_policy']]] ) lldp_policy = module.params['lldp_policy'] description = module.params['description'] receive_state = module.params['receive_state'] transmit_state = module.params['transmit_state'] state = module.params['state'] aci = ACIModule(module) aci.construct_url(root_class='lldp_policy') aci.get_existing() if state == 'present': # Filter out module parameters with null values aci.payload( aci_class='lldpIfPol', class_config=dict(name=lldp_policy, descr=description, adminRxSt=receive_state, adminTxSt=transmit_state) ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='lldpIfPol') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() module.exit_json(**aci.result)
def main(): argument_spec = aci_argument_spec argument_spec.update( bd=dict(type='str', aliases=['bd_name', 'bridge_domain']), l3out=dict(type='str'), state=dict(type='str', default='present', choices=['absent', 'present', 'query']), tenant=dict(type='str', aliases=['tenant_name']), method=dict(type='str', choices=['delete', 'get', 'post'], aliases=['action'], removed_in_version='2.6') # Deprecated starting from v2.6 ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_together=[['gateway', 'mask']], required_if=[ ['state', 'present', ['bd', 'l3out', 'tenant']], ['state', 'absent', ['bd', 'l3out', 'tenant']], ], ) l3out = module.params['l3out'] state = module.params['state'] # Add bd_l3out key to module.params for building the URL module.params['bd_l3out'] = l3out aci = ACIModule(module) aci.construct_url(root_class='tenant', subclass_1='bd', subclass_2='bd_l3out') aci.get_existing() if state == 'present': # Filter out module params with null values aci.payload( aci_class='fvRsBDToOut', class_config=dict(tnL3extOutName=l3out), ) # Generate config diff which will be used as POST request body aci.get_diff(aci_class='fvRsBDToOut') # Submit changes if module not in check_mode and the proposed is different than existing aci.post_config() elif state == 'absent': aci.delete_config() # Remove bd_l3out key used for URL building from module.params module.params.pop('bd_l3out') module.exit_json(**aci.result)