def _translate_list(self, attribute, model, mapping, translation, other): # Saving state to restore them later old_parent_key = self.keys["parent_key"] old_parent_bookmark = self.bookmarks["parent"] old_extra_vars = copy.deepcopy(self.extra_vars) # We will use this to store blocks of configuration # for each individual element of the list self.bookmarks[attribute] = {} for key in model: element = model[key] logger.debug("Translating {} {}".format(attribute, key)) try: other_element = other[key] except Exception: other_element = None key_name = "{}_key".format(attribute) self.keys[key_name] = key self.keys["parent_key"] = key translation_rule_negate = helpers.resolve_rule(mapping["_process"], attribute, self.keys, self.extra_vars, element, bool(self.replace), bool(self.merge), True) translation_rule = helpers.resolve_rule(mapping["_process"], attribute, self.keys, self.extra_vars, element, bool(self.replace), bool(self.merge), False) self.translator.default_element(translation_rule_negate, translation, self.bookmarks, replacing=True) et, extra_vars = self.translator.init_element(attribute, element, other_element, translation_rule, translation, self.bookmarks) if et is None: logger.info("Skipping {} as not implemented or objects are equal".format(attribute)) continue self.bookmarks[attribute][key] = et self.bookmarks["parent"] = et self.extra_vars.update(extra_vars) self._translate(attribute, element, mapping, et, other_element) # Restore state self.keys["parent_key"] = old_parent_key self.bookmarks["parent"] = old_parent_bookmark self.extra_vars = old_extra_vars if other: # Let's default elements not present in the model self._default_element_list(attribute, other, mapping, translation, model)
def parse_container(self, attribute, mapping, bookmarks): mapping = helpers.resolve_rule(mapping, attribute, self.keys, self.extra_vars, None, process_all=False) extra_vars = {} for m in mapping: pdb = m.get("pdb", {}) if pdb: _set_pdb_trace() continue # parent will change as the tree is processed so we save it # so we can restore it parent = bookmarks["parent"] data = self.resolve_path(bookmarks, m.get("from", "parent")) result, e = self._parse_container_default(attribute, m, data) extra_vars.update(e) if result: break # we restore the parent bookmarks["parent"] = parent return result, extra_vars
def parse_list(self, attribute, mapping, bookmarks): mapping = copy.deepcopy(mapping) mapping = helpers.resolve_rule(mapping, attribute, self.keys, self.extra_vars, None, process_all=False) for m in mapping: pdb = m.get("pdb", {}) if pdb: _set_pdb_trace() continue # parent will change as the tree is processed so we save it # so we can restore it parent = bookmarks["parent"] data = self.resolve_path(bookmarks, m.get("from", "parent")) for key, block, extra_vars in self._parse_list_default( attribute, m, data): yield key, block, extra_vars # we restore the parent bookmarks["parent"] = parent
def _default_element_list(self, attribute, running, mapping, translation, candidate): # we'll restore old values when we leave this branch old_extra_vars = copy.deepcopy(self.extra_vars) for key in running: logger.info("Defaulting {}: {}".format(attribute, key)) element = running[key] candidate = candidate or {} if key not in candidate.keys(): key_name = "{}_key".format(attribute) self.keys[key_name] = key self.keys["parent_key"] = key translation_rule = helpers.resolve_rule( mapping["_process"], attribute, self.keys, self.extra_vars, element, bool(self.replace), bool(self.merge), True) extra_vars = self.translator.default_element( translation_rule, translation, self.bookmarks) self.extra_vars.update(extra_vars) if any([ t.get("continue_negating", False) for t in translation_rule ]): self._default_child(attribute, element, mapping, translation) # Restore state self.extra_vars = old_extra_vars
def _translate_container(self, attribute, model, mapping, translation, other): if model._yang_type: self.bookmarks["parent"] = translation rule = helpers.resolve_rule(mapping["_process"], attribute, self.keys, self.extra_vars, model, bool(self.replace), bool(self.merge)) et, extra_vars = self.translator.translate_container(attribute, model, other, rule, translation, self.bookmarks) if et is None: return self.bookmarks[attribute] = et self.extra_vars.update(extra_vars) else: et = translation for k, v in model: logger.debug("Parsing attribute: {}".format(v._yang_path())) other_attr = getattr(other, k, None) if not v._is_config or k == "state": logger.debug("Skipping attribute: {}:{}".format(v._defining_module, attribute)) continue if v._defining_module != self._defining_module and v._defining_module is not None: logger.debug("Skipping attribute: {}:{}".format(v._defining_module, attribute)) translator = Translator(v, self.profile, et, self.keys, self.bookmarks, self.merge, self.replace, other_attr, self.extra_vars) translator.translate() else: self._translate(k, v, mapping[v._yang_name], et, other_attr)
def _default_element_list(self, attribute, running, mapping, translation, candidate): # we'll restore old values when we leave this branch old_extra_vars = copy.deepcopy(self.extra_vars) for key in running: logger.info("Defaulting {}: {}".format(attribute, key)) element = running[key] candidate = candidate or {} if key not in candidate.keys(): key_name = "{}_key".format(attribute) self.keys[key_name] = key self.keys["parent_key"] = key translation_rule = helpers.resolve_rule(mapping["_process"], attribute, self.keys, self.extra_vars, element, bool(self.replace), bool(self.merge), True) extra_vars = self.translator.default_element(translation_rule, translation, self.bookmarks) self.extra_vars.update(extra_vars) if any([t.get("continue_negating", False) for t in translation_rule]): self._default_child(attribute, element, mapping, translation) # Restore state self.extra_vars = old_extra_vars
def _translate_leaf(self, attribute, model, mapping, translation, other): rules = [mapping["_process"]] if isinstance(mapping["_process"], str) \ else mapping["_process"] for rule in rules: rule = helpers.resolve_rule(rule, attribute, self.keys, None, model, self.bookmarks) translation_point = _find_translation_point( rule, self.bookmarks, translation) self.translator.parse_leaf(attribute, model, other, rule, translation_point)
def _translate_leaf(self, attribute, model, mapping, translation, other): rule = helpers.resolve_rule( mapping["_process"], attribute, self.keys, self.extra_vars, model, bool(self.replace), bool(self.merge), ) self.translator.translate_leaf(attribute, model, other, rule, translation, self.bookmarks)
def _translate_container(self, attribute, model, mapping, translation, other): if model._yang_type: self.bookmarks["parent"] = translation rule = helpers.resolve_rule( mapping["_process"], attribute, self.keys, self.extra_vars, model, bool(self.replace), bool(self.merge), ) et, extra_vars = self.translator.translate_container( attribute, model, other, rule, translation, self.bookmarks) if et is None: return self.bookmarks[attribute] = et self.extra_vars.update(extra_vars) else: et = translation for k, v in model: logger.debug("Parsing attribute: {}".format(v._yang_path())) other_attr = getattr(other, k, None) if not v._is_config or k == "state": logger.debug("Skipping attribute: {}:{}".format( v._defining_module, attribute)) continue if (v._defining_module != self._defining_module and v._defining_module is not None): logger.debug("Skipping attribute: {}:{}".format( v._defining_module, attribute)) translator = Translator( v, self.profile, et, self.keys, self.bookmarks, self.merge, self.replace, other_attr, self.extra_vars, ) translator.translate() else: self._translate(k, v, mapping[v._yang_name], et, other_attr)
def parse_leaf(self, attribute, mapping, bookmarks): mapping = helpers.resolve_rule(mapping, attribute, self.keys, self.extra_vars, None, process_all=False) for m in mapping: data = self.resolve_path(bookmarks, m.get("from", "parent")) result = self._parse_leaf_default(attribute, m, data) if result is not None: try: result = ast.literal_eval(result) except (ValueError, SyntaxError): pass return result
def parse_container(self, attribute, mapping, bookmarks): mapping = helpers.resolve_rule(mapping, attribute, self.keys, self.extra_vars, None, process_all=False) for m in mapping: # parent will change as the tree is processed so we save it # so we can restore it parent = bookmarks["parent"] data = self.resolve_path(bookmarks, m.get("from", "parent")) result, extra_vars = self._parse_container_default(attribute, m, data) if result or extra_vars: break # we restore the parent bookmarks["parent"] = parent return result, extra_vars
def parse_list(self, attribute, mapping, bookmarks): mapping = copy.deepcopy(mapping) mapping = helpers.resolve_rule(mapping, attribute, self.keys, self.extra_vars, None, process_all=False) for m in mapping: # parent will change as the tree is processed so we save it # so we can restore it parent = bookmarks["parent"] data = self.resolve_path(bookmarks, m.get("from", "parent")) for key, block, extra_vars in self._parse_list_default(attribute, m, data): yield key, block, extra_vars # we restore the parent bookmarks["parent"] = parent
def _parse_leaf(self, attribute, model, mapping): mapping["_parse"] = helpers.resolve_rule(mapping["_parse"], attribute, self.keys, self.extra_vars, None, self.bookmarks) # We can't set attributes that are keys if model._is_keyval: return value = self.parser.parse_leaf(mapping["_parse"]) if value is not None and (value != model.default() or isinstance(value, bool)): setter = getattr(model._parent, "_set_{}".format(attribute)) setter(value) # parent.model is now a new class model = getattr(model._parent, attribute) model._mchanged = True
def parse_container(self, attribute, mapping, bookmarks): mapping = helpers.resolve_rule(mapping, attribute, self.keys, self.extra_vars, None, process_all=False) for m in mapping: # parent will change as the tree is processed so we save it # so we can restore it parent = bookmarks["parent"] data = self.resolve_path(bookmarks, m.get("from", "parent")) result, extra_vars = self._parse_container_default( attribute, m, data) if result or extra_vars: break # we restore the parent bookmarks["parent"] = parent return result, extra_vars
def _parse_container(self, attribute, model, mapping): mapping["_parse"] = helpers.resolve_rule(mapping["_parse"], attribute, self.keys, self.extra_vars, None, self.bookmarks) for k, v in model: logger.debug("Parsing attribute: {}".format(v._yang_path())) if self.is_config and (not v._is_config or k == "state"): continue elif not self.is_config and (v._is_config or k == "config") \ and v._yang_type not in ("container", "list"): continue if v._defining_module != self._defining_module and v._defining_module is not None: logger.debug("Skipping attribute: {}:{}".format( v._defining_module, attribute)) parser = Parser(v, self.device, self.profile, self.is_config, self.native, self.keys, self.bookmarks, self.extra_vars) parser.parse() else: self._parse(k, v, mapping[k])
def _parse_list(self, attribute, model, mapping): mapping_copy = copy.deepcopy(mapping) mapping_copy["_parse"] = helpers.resolve_rule(mapping_copy["_parse"], attribute, self.keys, self.extra_vars, None, self.bookmarks) # Saving state to restore them later old_parent_key = self.keys["parent_key"] old_parent_bookmark = self.bookmarks["parent"] old_parent_extra_vars = self.extra_vars # We will use this to store blocks of configuration # for each individual element of the list self.bookmarks[attribute] = {} for key, block, extra_vars in self.parser.parse_list( mapping_copy["_parse"]): logger.debug("Parsing element {}[{}]".format(attribute, key)) obj = model.add(key) key_name = "{}_key".format(attribute) self.keys[key_name] = key self.bookmarks[attribute][key] = block self.extra_vars[attribute] = extra_vars # These two are necessary in cases where an element may be present in subtrees. For # example, ipv4.config.enabled is present in both interfaces and subinterfaces self.keys["parent_key"] = key self.bookmarks["parent"] = block self.extra_vars = extra_vars element_mapping = copy.deepcopy(mapping) self._parse(key, obj, element_mapping) # Restore state self.keys["parent_key"] = old_parent_key self.bookmarks["parent"] = old_parent_bookmark self.extra_vars = old_parent_extra_vars
def _translate_container(self, attribute, model, mapping, translation, other): if model._yang_type: self.bookmarks["parent"] = translation rule = helpers.resolve_rule(mapping["_process"], attribute, self.keys, None, model, self.bookmarks) translation_point = _find_translation_point( rule, self.bookmarks, translation) et = self.translator.parse_container(attribute, model, other, rule, translation_point) self.bookmarks[attribute] = et else: translation_point = _find_translation_point( mapping, self.bookmarks, translation) et = translation for k, v in model: logger.debug("Parsing attribute: {}".format(v._yang_path())) other_attr = getattr(other, k, None) if not v._is_config or k == "state": logger.debug("Skipping attribute: {}:{}".format( v._defining_module, attribute)) continue if v._defining_module != self._defining_module and v._defining_module is not None: logger.debug("Skipping attribute: {}:{}".format( v._defining_module, attribute)) translator = Translator(v, self.profile, translation_point, self.keys, self.bookmarks, self.merge, self.replace, other_attr) translator.translate() else: self._translate(v._yang_name, v, mapping[v._yang_name], et, other_attr)
def _translate_leaf(self, attribute, model, mapping, translation, other): rule = helpers.resolve_rule(mapping["_process"], attribute, self.keys, self.extra_vars, model, bool(self.replace), bool(self.merge)) self.translator.translate_leaf(attribute, model, other, rule, translation, self.bookmarks)
def _translate_list(self, attribute, model, mapping, translation, other): # Saving state to restore them later old_parent_key = self.keys["parent_key"] old_parent_bookmark = self.bookmarks["parent"] # We will use this to store blocks of configuration # for each individual element of the list self.bookmarks[attribute] = {} for key in model: element = model[key] logger.debug("Translating {} {}".format(attribute, key)) try: other_element = other[key] except Exception: other_element = None key_name = "{}_key".format(attribute) self.keys[key_name] = key self.keys["parent_key"] = key translation_rule = helpers.resolve_rule(mapping["_process"], attribute, self.keys, None, element, self.bookmarks) translation_point = _find_translation_point( translation_rule, self.bookmarks, translation) self.translator.default_element(translation_rule, translation_point, replacing=True) et = self.translator.init_element(attribute, element, other_element, translation_rule, translation_point) if et is None: logger.info( "Skipping {} as not implemented or objects are equal". format(attribute)) continue self.bookmarks[attribute][key] = et self.bookmarks["parent"] = et self._translate(attribute, element, mapping, et, other_element) # Restore state self.keys["parent_key"] = old_parent_key self.bookmarks["parent"] = old_parent_bookmark if other: # Let's default elements not present in the model for key in other: element = other[key] if key not in model.keys(): key_name = "{}_key".format(attribute) self.keys[key_name] = key self.keys["parent_key"] = key translation_rule = helpers.resolve_rule( mapping["_process"], attribute, self.keys, None, element, self.bookmarks) translation_point = _find_translation_point( translation_rule, self.bookmarks, translation) self.translator.default_element(translation_rule, translation_point)
def _translate_list(self, attribute, model, mapping, translation, other): # Saving state to restore them later old_parent_key = self.keys["parent_key"] old_parent_bookmark = self.bookmarks["parent"] old_extra_vars = copy.deepcopy(self.extra_vars) # We will use this to store blocks of configuration # for each individual element of the list self.bookmarks[attribute] = {} for key in model: element = model[key] logger.debug("Translating {} {}".format(attribute, key)) try: other_element = other[key] except Exception: other_element = None key_name = "{}_key".format(attribute) self.keys[key_name] = key self.keys["parent_key"] = key translation_rule_negate = helpers.resolve_rule( mapping["_process"], attribute, self.keys, self.extra_vars, element, bool(self.replace), bool(self.merge), True) translation_rule = helpers.resolve_rule(mapping["_process"], attribute, self.keys, self.extra_vars, element, bool(self.replace), bool(self.merge), False) self.translator.default_element(translation_rule_negate, translation, self.bookmarks, replacing=True) et, extra_vars = self.translator.init_element( attribute, element, other_element, translation_rule, translation, self.bookmarks) if et is None: logger.info( "Skipping {} as not implemented or objects are equal". format(attribute)) continue self.bookmarks[attribute][key] = et self.bookmarks["parent"] = et self.extra_vars.update(extra_vars) self._translate(attribute, element, mapping, et, other_element) # Restore state self.keys["parent_key"] = old_parent_key self.bookmarks["parent"] = old_parent_bookmark self.extra_vars = old_extra_vars if other: # Let's default elements not present in the model self._default_element_list(attribute, other, mapping, translation, model)