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 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") 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 = self.module.from_json(reply.text.strip()) elif config_format == "set": config = self.get_text(reply, "configuration-set") self.facts["config"] = config
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 = self.module.from_json(reply.text.strip()) elif config_format == 'set': config = self.get_text(reply, 'configuration-set') self.facts['config'] = config
def main(): """ main entry point for module execution """ backup_spec = dict(filename=dict(), dir_path=dict(type="path")) argument_spec = dict( lines=dict(aliases=["commands"], type="list", elements="str"), 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), check_commit=dict(type="bool", default=False), # config operations backup=dict(type="bool", default=False), backup_options=dict(type="dict", options=backup_spec), 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() rollback_id = module.params["rollback"] if rollback_id: diff = rollback(module, rollback_id) if commit: kwargs = {"comment": module.params["comment"]} with locked_config(module): load_configuration(module, rollback=rollback_id) commit_configuration(module, **kwargs) 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"], "check": module.params["check_commit"], } confirm = module.params["confirm"] if confirm > 0: kwargs.update( { "confirm": True, "confirm_timeout": to_text( confirm, errors="surrogate_then_replace", ), } ) commit_configuration(module, **kwargs) else: discard_changes(module) result["changed"] = True if module._diff: result["diff"] = {"prepared": diff} elif module.params["check_commit"]: commit_configuration(module, check=True) 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 = exec_rpc(module, tostring(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 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 = exec_rpc(module, tostring(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