def rpc(module, items): responses = list() for item in items: name = item['name'] xattrs = item['xattrs'] fetch_config = False #args = item.get('args') text = item.get('text') #name = str(name).replace('_', '-') name = str(name) #if all((module.check_mode, not name.startswith('get'))): #module.fail_json(msg='invalid rpc for running in check_mode') if name == 'command' and text.startswith( 'show configuration') or name == 'get-configuration': fetch_config = True element = Element(name, xattrs) if text: element.text = text if fetch_config: reply = get_configuration(module, format=xattrs['format']) else: reply = send_request(module, element, ignore_warning=False) responses.append(tostring(reply)) return responses
def rpc(module, items): responses = list() for item in items: name = item['name'] xattrs = item['xattrs'] fetch_config = False text = item.get('text') name = str(name) if name == 'command' and text.startswith( 'show configuration') or name == 'get-configuration': fetch_config = True element = Element(name, xattrs) if text: element.text = text if fetch_config: reply = get_configuration(module, format=xattrs['format']) else: reply = send_request(module, element, ignore_warning=False) responses.append(tostring(reply)) return responses
def configure_member_params(module, requests, item): top = 'interfaces/interface' members = item['members'] if members: member_to_xpath_map = collections.OrderedDict() member_to_xpath_map.update([ ('name', {'xpath': 'name', 'is_key': True, 'parent_attrib': False}), ('bundle', {'xpath': 'bundle', 'leaf_only': True, 'top': 'ether-options/ieee-802.3ad', 'is_key': True}), ]) # link aggregation bundle assigned to member item['bundle'] = item['name'] for member in members: if item['state'] == 'absent': # if link aggregate bundle is not assigned to member, trying to # delete it results in rpc-reply error, hence if is not assigned # skip deleting it and continue to next member. resp = get_configuration(module) bundle = resp.xpath("configuration/interfaces/interface[name='%s']/ether-options/" "ieee-802.3ad[bundle='%s']" % (member, item['bundle'])) if not bundle: continue # Name of member to be assigned to link aggregation bundle item['name'] = member validate_param_values(module, member_to_xpath_map, item) want = map_params_to_obj(module, member_to_xpath_map, param=item) ele = map_obj_to_ele(module, want, top, param=item) requests.append(ele)
def filter_delete_statements(module, candidate): reply = get_configuration(module, format='set') config = reply.xpath('//configuration-set')[0].text.strip() for index, line in enumerate(candidate): if line.startswith('delete'): newline = re.sub('^delete', 'set', line) if newline not in config: del candidate[index] return candidate
def main(): """ main entry point for module execution """ argument_spec = dict( lines=dict(type='list'), src=dict(type='path'), src_format=dict(choices=['xml', 'text', 'set', 'json']), # update operations update=dict(default='merge', choices=['merge', 'overwrite', 'replace', 'update']), # deprecated replace in Ansible 2.3 replace=dict(type='bool'), confirm=dict(default=0, type='int'), comment=dict(default=DEFAULT_COMMENT), # config operations backup=dict(type='bool', default=False), rollback=dict(type='int'), # deprecated zeroize in Ansible 2.3 zeroize=dict(default=False, type='bool'), ) argument_spec.update(junos_argument_spec) mutually_exclusive = [('lines', 'src', 'rollback')] module = AnsibleModule(argument_spec=argument_spec, mutually_exclusive=mutually_exclusive, supports_check_mode=True) warnings = list() check_args(module, warnings) result = {'changed': False, 'warnings': warnings} if module.params['backup']: result['__backup__'] = get_configuration() if module.params['rollback']: diff = get_diff(module) update_result(module, result, diff) elif not any((module.params['src'], module.params['lines'])): confirm_config(module) else: diff = load_config(module) update_result(module, result, diff) module.exit_json(**result)
def main(): argument_spec = dict( src=dict(required=True, type='path'), confirm=dict(default=0, type='int'), comment=dict(default=DEFAULT_COMMENT), action=dict(default='merge', choices=['merge', 'overwrite', 'replace']), config_format=dict(choices=['text', 'set', 'xml'], default='text'), backup=dict(default=False, type='bool'), ) argument_spec.update(junos_argument_spec) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) warnings = list() check_args(module, warnings) result = {'changed': False, 'warnings': warnings} commit = not module.check_mode action = module.params['action'] src = module.params['src'] fmt = module.params['config_format'] if action == 'overwrite' and fmt == 'set': module.fail_json( msg= "overwrite cannot be used when format is set per junos-pyez documentation" ) if module.params['backup']: reply = get_configuration(module, format='set') match = reply.find('.//configuration-set') if match is None: module.fail_json(msg='unable to retrieve device configuration') result['__backup__'] = str(match.text).strip() with locked_config(module): diff = load_config(module, src, warnings, action=action, format=fmt) if diff: if commit: commit_configuration(module) else: discard_changes(module) result['changed'] = True if module._diff: result['diff'] = {'prepared': diff} module.exit_json(**result)
def filter_delete_statements(module, candidate): reply = get_configuration(module, format='set') match = reply.find('.//configuration-set') if match is None: # Could not find configuration-set in reply, perhaps device does not support it? return candidate config = str(match.text) modified_candidate = candidate[:] for index, line in enumerate(candidate): if line.startswith('delete'): newline = re.sub('^delete', 'set', line) if newline not in config: del modified_candidate[index] return modified_candidate
def filter_delete_statements(module, candidate): reply = get_configuration(module, format='set') match = reply.find('.//configuration-set') if match is None: # Could not find configuration-set in reply, perhaps device does not support it? return candidate config = to_native(match.text, encoding='latin-1') modified_candidate = candidate[:] for index, line in reversed(list(enumerate(candidate))): if line.startswith('delete'): newline = re.sub('^delete', 'set', line) if newline not in config: del modified_candidate[index] return modified_candidate
def populate(self): config_format = self.module.params['config_format'] reply = get_configuration(self.module, format=config_format) if config_format == 'xml': config = tostring(reply.find('configuration')).strip() elif config_format == 'text': config = self.get_text(reply, 'configuration-text') elif config_format == 'json': config = str(reply.text).strip() elif config_format == 'set': config = self.get_text(reply, 'configuration-set') self.facts['config'] = config
def configure_member_params(module, warnings, diff=None): top = 'interfaces/interface' members = module.params['members'] if members: member_to_xpath_map = collections.OrderedDict() member_to_xpath_map.update([ ('name', { 'xpath': 'name', 'is_key': True, 'parent_attrib': False }), ('bundle', { 'xpath': 'bundle', 'leaf_only': True, 'top': 'ether-options/ieee-802.3ad', 'is_key': True }), ]) # link aggregation bundle assigned to member module.params['bundle'] = module.params['name'] for member in members: if module.params['state'] == 'absent': # if link aggregate bundle is not assigned to member, trying to # delete it results in rpc-reply error, hence if is not assigned # skip deleting it and continue to next member. resp = get_configuration(module) bundle = resp.xpath( "configuration/interfaces/interface[name='%s']/ether-options/" "ieee-802.3ad[bundle='%s']" % (member, module.params['bundle'])) if not bundle: continue # Name of member to be assigned to link aggregation bundle module.params['name'] = member validate_param_values(module, member_to_xpath_map) want = map_params_to_obj(module, member_to_xpath_map) ele = map_obj_to_ele(module, want, top) diff = load_config(module, tostring(ele), warnings) return diff
def populate(self): config_format = self.module.params['config_format'] reply = get_configuration(self.module, format=config_format) if config_format == 'xml': config = tostring(reply.find('configuration')).strip() elif config_format == 'text': config = self.get_text(reply, 'configuration-text') elif config_format == 'json': config = str(reply.text).strip() elif config_format == 'set': config = self.get_text(reply, 'configuration-set') self.facts['config'] = config
def main(): argument_spec = dict( src=dict(required=True, type='path'), confirm=dict(default=0, type='int'), comment=dict(default=DEFAULT_COMMENT), action=dict(default='merge', choices=['merge', 'overwrite', 'replace']), config_format=dict(choices=['text', 'set', 'xml']), backup=dict(default=False, type='bool'), ) argument_spec.update(junos_argument_spec) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) check_transport(module) warnings = list() check_args(module, warnings) result = {'changed': False, 'warnings': warnings} comment = module.params['comment'] confirm = module.params['confirm'] commit = not module.check_mode action = module.params['action'] src = module.params['src'] fmt = module.params['config_format'] if action == 'overwrite' and fmt == 'set': module.fail_json(msg="overwrite cannot be used when format is " "set per junos-pyez documentation") if module.params['backup']: result['__backup__'] = text_type(get_configuration(module)) diff = load(module, src, action=action, commit=commit, format=fmt) if diff: result['changed'] = True if module._diff: result['diff'] = {'prepared': diff} module.exit_json(**result)
def filter_delete_statements(module, candidate): reply = get_configuration(module, format='set') match = reply.find('.//configuration-set') if match is None: module.fail_json(msg='unable to retrieve device configuration') config = str(match.text) #if 'delete interfaces lo0' in candidate: # raise ValueError(config) modified_candidate = candidate[:] for index, line in enumerate(candidate): if line.startswith('delete'): newline = re.sub('^delete', 'set', line) if newline not in config: del modified_candidate[index] return modified_candidate
def rpc(module, items): responses = list() for item in items: name = item['name'] xattrs = item['xattrs'] fetch_config = False args = item.get('args') text = item.get('text') name = str(name).replace('_', '-') if all((module.check_mode, not name.startswith('get'))): module.fail_json(msg='invalid rpc for running in check_mode') if name == 'command' and text.startswith('show configuration') or name == 'get-configuration': fetch_config = True element = Element(name, xattrs) if text: element.text = text elif args: for key, value in iteritems(args): key = str(key).replace('_', '-') if isinstance(value, list): for item in value: child = SubElement(element, key) if item is not True: child.text = item else: child = SubElement(element, key) if value is not True: child.text = value if fetch_config: reply = get_configuration(module, format=xattrs['format']) else: reply = send_request(module, element, ignore_warning=False) if xattrs['format'] == 'text': if fetch_config: data = reply.find('.//configuration-text') else: data = reply.find('.//output') if data is None: module.fail_json(msg=tostring(reply)) responses.append(data.text.strip()) elif xattrs['format'] == 'json': responses.append(module.from_json(reply.text.strip())) elif xattrs['format'] == 'set': data = reply.find('.//configuration-set') if data is None: module.fail_json(msg="Display format 'set' is not supported by remote device.") responses.append(data.text.strip()) else: responses.append(tostring(reply)) return responses
def main(): """ main entry point for module execution """ argument_spec = dict( lines=dict(type='list'), src=dict(type='path'), src_format=dict(choices=['xml', 'text', 'set', 'json']), # update operations update=dict(default='merge', choices=['merge', 'override', 'replace', 'update']), # deprecated replace in Ansible 2.3 replace=dict(type='bool'), confirm=dict(default=0, type='int'), comment=dict(default=DEFAULT_COMMENT), # config operations backup=dict(type='bool', default=False), rollback=dict(type='int'), zeroize=dict(default=False, type='bool'), ) argument_spec.update(junos_argument_spec) mutually_exclusive = [('lines', 'src', 'rollback', 'zeroize')] module = AnsibleModule(argument_spec=argument_spec, mutually_exclusive=mutually_exclusive, supports_check_mode=True) warnings = list() check_args(module, warnings) result = {'changed': False, 'warnings': warnings} if module.params['backup']: for conf_format in ['set', 'text']: reply = get_configuration(module, format=conf_format) match = reply.find('.//configuration-%s' % conf_format) if match is not None: break else: module.fail_json(msg='unable to retrieve device configuration') result['__backup__'] = str(match.text).strip() if module.params['rollback']: if not module.check_mode: diff = rollback(module) if module._diff: result['diff'] = {'prepared': diff} result['changed'] = True elif module.params['zeroize']: if not module.check_mode: zeroize(module) result['changed'] = True else: diff = configure_device(module, warnings) if diff: if module._diff: result['diff'] = {'prepared': diff} result['changed'] = True module.exit_json(**result)
def main(): """ main entry point for module execution """ argument_spec = dict( lines=dict(type='list'), src=dict(type='path'), src_format=dict(choices=['xml', 'text', 'set', 'json']), # update operations update=dict(default='merge', choices=['merge', 'override', 'replace', 'update']), # deprecated replace in Ansible 2.3 replace=dict(type='bool'), confirm=dict(default=0, type='int'), comment=dict(default=DEFAULT_COMMENT), confirm_commit=dict(type='bool', default=False), # config operations backup=dict(type='bool', default=False), rollback=dict(type='int'), zeroize=dict(default=False, type='bool'), ) argument_spec.update(junos_argument_spec) mutually_exclusive = [('lines', 'src', 'rollback', 'zeroize')] module = AnsibleModule(argument_spec=argument_spec, mutually_exclusive=mutually_exclusive, supports_check_mode=True) warnings = list() check_args(module, warnings) candidate = module.params['lines'] or module.params['src'] commit = not module.check_mode result = {'changed': False, 'warnings': warnings} if module.params['backup']: for conf_format in ['set', 'text']: reply = get_configuration(module, format=conf_format) match = reply.find('.//configuration-%s' % conf_format) if match is not None: break else: module.fail_json(msg='unable to retrieve device configuration') result['__backup__'] = match.text.strip() if module.params['rollback']: if commit: diff = rollback(module) if module._diff: result['diff'] = {'prepared': diff} result['changed'] = True elif module.params['zeroize']: if commit: zeroize(module) result['changed'] = True else: if candidate: with locked_config(module): diff = configure_device(module, warnings, candidate) if diff: if commit: kwargs = { 'comment': module.params['comment'] } if module.params['confirm'] > 0: kwargs.update({ 'confirm': True, 'confirm_timeout': module.params['confirm'] }) commit_configuration(module, **kwargs) else: discard_changes(module) result['changed'] = True if module._diff: result['diff'] = {'prepared': diff} elif module.params['confirm_commit']: with locked_config(module): # confirm a previous commit commit_configuration(module) result['changed'] = True module.exit_json(**result)
def rpc(module, items): responses = list() for item in items: name = item['name'] xattrs = item['xattrs'] fetch_config = False args = item.get('args') text = item.get('text') name = str(name).replace('_', '-') if all((module.check_mode, not name.startswith('get'))): module.fail_json(msg='invalid rpc for running in check_mode') if name == 'command' and text.startswith('show configuration') or name == 'get-configuration': fetch_config = True element = Element(name, xattrs) if text: element.text = text elif args: for key, value in iteritems(args): key = str(key).replace('_', '-') if isinstance(value, list): for item in value: child = SubElement(element, key) if item is not True: child.text = item else: child = SubElement(element, key) if value is not True: child.text = value if fetch_config: reply = get_configuration(module, format=xattrs['format']) else: reply = send_request(module, element, ignore_warning=False) if xattrs['format'] == 'text': if fetch_config: data = reply.find('.//configuration-text') else: data = reply.find('.//output') if data is None: module.fail_json(msg=tostring(reply)) responses.append(data.text.strip()) elif xattrs['format'] == 'json': responses.append(module.from_json(reply.text.strip())) elif xattrs['format'] == 'set': data = reply.find('.//configuration-set') if data is None: module.fail_json(msg="Display format 'set' is not supported by remote device.") responses.append(data.text.strip()) else: responses.append(tostring(reply)) return responses