def main(): argument_specs = dict(http_method=dict( required=True, choices=['get', 'put', 'post', 'patch', 'delete']), path=dict(type='str', required=True), params=dict(type='dict'), data=dict(type='jsonarg'), timeout=dict(type='int', default=60)) argument_specs.update(avi_common_argument_spec()) module = AnsibleModule(argument_spec=argument_specs) if not HAS_AVI: return module.fail_json( msg=('Avi python API SDK (avisdk) is not installed. ' 'For more details visit https://github.com/avinetworks/sdk.')) tenant_uuid = module.params.get('tenant_uuid', None) api = ApiSession.get_session(module.params['controller'], module.params['username'], module.params['password'], tenant=module.params['tenant'], tenant_uuid=tenant_uuid) tenant = module.params.get('tenant', '') timeout = int(module.params.get('timeout')) # path is a required argument path = module.params.get('path', '') params = module.params.get('params', None) data = module.params.get('data', None) # Get the api_version from module. api_version = module.params.get('api_version', '16.4') if data is not None: data = json.loads(data) method = module.params['http_method'] existing_obj = None changed = method != 'get' gparams = deepcopy(params) if params else {} gparams.update({'include_refs': '', 'include_name': ''}) if method == 'post': # need to check if object already exists. In that case # change the method to be put gparams['name'] = data['name'] rsp = api.get(path, tenant=tenant, tenant_uuid=tenant_uuid, params=gparams, api_version=api_version) try: existing_obj = rsp.json()['results'][0] except IndexError: # object is not found pass else: # object is present method = 'put' path += '/' + existing_obj['uuid'] if method == 'put': # put can happen with when full path is specified or it is put + post if existing_obj is None: using_collection = False if (len(path.split('/')) == 1) and ('name' in data): gparams['name'] = data['name'] using_collection = True rsp = api.get(path, tenant=tenant, tenant_uuid=tenant_uuid, params=gparams, api_version=api_version) rsp_data = rsp.json() if using_collection: if rsp_data['results']: existing_obj = rsp_data['results'][0] path += '/' + existing_obj['uuid'] else: method = 'post' else: if rsp.status_code == 404: method = 'post' else: existing_obj = rsp_data if existing_obj: changed = not avi_obj_cmp(data, existing_obj) cleanup_absent_fields(data) if method == 'patch': rsp = api.get(path, tenant=tenant, tenant_uuid=tenant_uuid, params=gparams, api_version=api_version) existing_obj = rsp.json() if (method == 'put' and changed) or (method != 'put'): fn = getattr(api, method) rsp = fn(path, tenant=tenant, tenant_uuid=tenant, timeout=timeout, params=params, data=data, api_version=api_version) else: rsp = None if method == 'delete' and rsp.status_code == 404: changed = False rsp.status_code = 200 if method == 'patch' and existing_obj and rsp.status_code < 299: # Ideally the comparison should happen with the return values # from the patch API call. However, currently Avi API are # returning different hostname when GET is used vs Patch. # tracked as AV-12561 if path.startswith('pool'): time.sleep(1) gparams = deepcopy(params) if params else {} gparams.update({'include_refs': '', 'include_name': ''}) rsp = api.get(path, tenant=tenant, tenant_uuid=tenant_uuid, params=gparams, api_version=api_version) new_obj = rsp.json() changed = not avi_obj_cmp(new_obj, existing_obj) if rsp is None: return module.exit_json(changed=changed, obj=existing_obj) return ansible_return(module, rsp, changed, req=data)
def main(): argument_specs = dict( http_method=dict(required=True, choices=['get', 'put', 'post', 'patch', 'delete']), path=dict(type='str', required=True), params=dict(type='dict'), data=dict(type='jsonarg'), timeout=dict(type='int', default=60) ) argument_specs.update(avi_common_argument_spec()) module = AnsibleModule(argument_spec=argument_specs) if not HAS_AVI: return module.fail_json(msg=( 'Avi python API SDK (avisdk) is not installed. ' 'For more details visit https://github.com/avinetworks/sdk.')) tenant_uuid = module.params.get('tenant_uuid', None) api = ApiSession.get_session( module.params['controller'], module.params['username'], module.params['password'], tenant=module.params['tenant'], tenant_uuid=tenant_uuid) tenant = module.params.get('tenant', '') timeout = int(module.params.get('timeout')) # path is a required argument path = module.params.get('path', '') params = module.params.get('params', None) data = module.params.get('data', None) # Get the api_version from module. api_version = module.params.get('api_version', '16.4') if data is not None: data = json.loads(data) method = module.params['http_method'] existing_obj = None changed = method != 'get' gparams = deepcopy(params) if params else {} gparams.update({'include_refs': '', 'include_name': ''}) if method == 'post': # need to check if object already exists. In that case # change the method to be put gparams['name'] = data['name'] rsp = api.get(path, tenant=tenant, tenant_uuid=tenant_uuid, params=gparams, api_version=api_version) try: existing_obj = rsp.json()['results'][0] except IndexError: # object is not found pass else: # object is present method = 'put' path += '/' + existing_obj['uuid'] if method == 'put': # put can happen with when full path is specified or it is put + post if existing_obj is None: using_collection = False if (len(path.split('/')) == 1) and ('name' in data): gparams['name'] = data['name'] using_collection = True rsp = api.get(path, tenant=tenant, tenant_uuid=tenant_uuid, params=gparams, api_version=api_version) rsp_data = rsp.json() if using_collection: if rsp_data['results']: existing_obj = rsp_data['results'][0] path += '/' + existing_obj['uuid'] else: method = 'post' else: if rsp.status_code == 404: method = 'post' else: existing_obj = rsp_data if existing_obj: changed = not avi_obj_cmp(data, existing_obj) cleanup_absent_fields(data) if method == 'patch': rsp = api.get(path, tenant=tenant, tenant_uuid=tenant_uuid, params=gparams, api_version=api_version) existing_obj = rsp.json() if (method == 'put' and changed) or (method != 'put'): fn = getattr(api, method) rsp = fn(path, tenant=tenant, tenant_uuid=tenant, timeout=timeout, params=params, data=data, api_version=api_version) else: rsp = None if method == 'delete' and rsp.status_code == 404: changed = False rsp.status_code = 200 if method == 'patch' and existing_obj and rsp.status_code < 299: # Ideally the comparison should happen with the return values # from the patch API call. However, currently Avi API are # returning different hostname when GET is used vs Patch. # tracked as AV-12561 if path.startswith('pool'): time.sleep(1) gparams = deepcopy(params) if params else {} gparams.update({'include_refs': '', 'include_name': ''}) rsp = api.get(path, tenant=tenant, tenant_uuid=tenant_uuid, params=gparams, api_version=api_version) new_obj = rsp.json() changed = not avi_obj_cmp(new_obj, existing_obj) if rsp is None: return module.exit_json(changed=changed, obj=existing_obj) return ansible_return(module, rsp, changed, req=data)