#!/usr/bin/python # Copyright 2013 Cisco Systems, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ This module generated the python script using UCS GUI, GUI logs and xml request. """ from __future__ import print_function try: import xml.etree.cElementTree as ET from xml.etree.cElementTree import Element, SubElement except ImportError: import cElementTree as ET from cElementTree import Element, SubElement import os import re from ucsmsdk import ucsgenutils from ucsmsdk import ucscoreutils import logging log = logging.getLogger('ucs') classid_dn_map = { "OrgOrg": "org-root", "FabricEp": "fabric", "FaultHolder": "fault", "StatsHolder": "stats", "CallHomeEp": "call-home", "TopSystem": "sys" } import_list = [] def _generate_imports(imports): import_str = "" for each in imports: import_str += "from " + ucscoreutils.get_import_str(each) + " import " + each + "\n" import_str += "\n\n" return import_str def _ignore_elem(elem): if elem.tag.startswith('aaa'): return True if elem.tag in ["biosVfUCSMBootOrderRuleControl", "biosVfOptionROMLoad", "policyControlEp", "storageLocalDiskPartition"]: return True return False class Node(object): def __init__(self, elem, tag, parent_dn=None, parent_tag=None, parent_verb=None): self.elem = elem self.tag = tag self.parent_dn = parent_dn self.parent_tag = parent_tag self.parent_verb = parent_verb self.class_id = ucsgenutils.word_u(elem.tag) self.class_ref = ucscoreutils.load_class(self.class_id) self.mo_meta = self.class_ref.mo_meta self.prop_meta = self.class_ref.prop_meta self.prop_map = self.class_ref.prop_map self.dn = self._make_dn() self.verb = self._get_verb() self.child = [] def _get_verb(self): verbs = self.mo_meta.verbs if "Add" in verbs: return "Add" elif "Set" in verbs: return "Set" else: return "Get" def _make_rn(self): rn_pattern = self.class_ref.mo_meta.rn prop_meta = self.class_ref.prop_meta for prop in re.findall(r"""\[([^\]]*)\]""", rn_pattern): prop_val = self.elem.attrib[prop_meta[prop].xml_attribute] rn_pattern = re.sub(r"""\[%s\]""" % prop, prop_val, rn_pattern) return rn_pattern def _make_dn(self): if self.parent_dn: return self.parent_dn + "/" + self._make_rn() return self._make_rn() def _create_prop_map(self, *args): property_map = {} for attribute in self.elem.attrib: if attribute not in self.prop_map: print( "# attribute:" + attribute + " not recognised by this version of SDK. Ignoring..") continue prop_name_py = self.prop_map[attribute] prop_access = self.prop_meta[prop_name_py].access if prop_access in args: continue prop_val = self.elem.attrib[attribute] if prop_val != "": property_map[prop_name_py] = prop_val return property_map def _create_add_prop_map(self): return self._create_prop_map(2, 4) def _create_set_prop_map(self): return self._create_prop_map(0, 1, 2, 4) def _create_add_query(self): if self.class_id not in import_list: import_list.append(self.class_id) property_map = self._create_add_prop_map() property_map_str = ", ".join( [k + "=" + '"' + v + '"' for k, v in ucsgenutils.iteritems(property_map)]) return "%s = %s(parent_mo_or_dn=%s, %s)\n" % ( self.tag, self.class_id, self.parent_tag, property_map_str) def _create_set_query(self): if self.class_id not in import_list: import_list.append(self.class_id) if self.parent_verb not in ("Add", "Set"): query = '%s = handle.query_dn("%s")\n' % (self.tag, self.dn) property_map = self._create_set_prop_map() for prop in property_map: query += '%s.%s = "%s"\n' % (self.tag, prop, property_map[prop]) return query else: return self._create_add_query() def _create_get_query(self): return '%s = handle.query_dn("%s")\n' % (self.tag, self.dn) def get_query(self): query = "" if self.verb == "Get": query = self._create_get_query() elif self.verb == "Add": query = self._create_add_query() elif self.verb == "Set": query = self._create_set_query() return query def process_query(self): query = "" query_ = self.get_query() if query_: query += query_ for child in self.child: query += child.process_query() if self.parent_verb == "Get" and self.verb == "Add": query += "handle.add_mo(%s, True)\n" % self.tag if self.parent_verb == "Get" and self.verb == "Set": query += "handle.set_mo(%s)\n" % self.tag return query def __str__(self): query = self.process_query() if query: query += "handle.commit()\n" return query def _process_child_elem(elem, tag, node, iter_count): call_count = iter_count for child in elem.getchildren(): if _ignore_elem(child): continue child_tag = tag + '_' + str(call_count) child_node = Node(elem=child, tag=child_tag, parent_dn=node.dn, parent_tag=node.tag, parent_verb=node.verb) node.child.append(child_node) call_count += 1 ret_obj = _process_child_elem(child, tag, child_node, call_count) call_count = ret_obj["iter_count"] return {"node": node, "iter_count": call_count} def _generate_inner_nodes(elem, tag, parent_dn, parent_tag, parent_verb): class_id = ucsgenutils.word_u(elem.tag) if not ucscoreutils.is_valid_class_id(class_id): return node = Node(elem, tag, parent_dn, parent_tag, parent_verb) ret_obj = _process_child_elem(elem, tag, node, 1) return ret_obj["node"] def _generate_outer_nodes(elem): top_nodes = [] if elem.tag != "topRoot": return top_nodes for child in elem.getchildren(): class_id = ucsgenutils.word_u(child.tag) if not ucscoreutils.is_valid_class_id(class_id) \ or class_id not in classid_dn_map: continue parent_nodes = [] for sub_child in child.getchildren(): if _ignore_elem(sub_child): continue parent_node = Node(elem=child, tag="obj", parent_dn=None, parent_tag=None, parent_verb=None) parent_node.verb = "Get" parent_node.dn = classid_dn_map[class_id] child_node = _generate_inner_nodes( elem=sub_child, tag="mo", parent_dn=parent_node.dn, parent_tag=parent_node.tag, parent_verb=parent_node.verb) parent_node.child.append(child_node) parent_nodes.append(parent_node) top_nodes.append(parent_nodes) return top_nodes def _generate_query(elem): query = "" top_nodes = _generate_outer_nodes(elem) for parent_nodes in top_nodes: query += "\n" for parent_node in parent_nodes: query += str(parent_node) query += "\n" return query def convert_from_backup(backup_file, output_file=None): """ converts UCS backup xml to a python script for the equivalent configuration. Args: backup_file (str): input file path for backup xml. output_file (str or None): file in which output is desired. None for stdout Example: convert_from_backup(backup_file="/home/user/backup.xml", output_file="/home/user/output.py") convert_from_backup(backup_file="/home/user/backup.xml") """ if not os.path.exists(backup_file): raise ValueError("%s does not exists." % backup_file) tree = ET.parse(backup_file) root = tree.getroot() script_output = _generate_query(root) imports_str = _generate_imports(import_list) boilerplate_start_str = """#!/usr/bin/env python from ucsmsdk.ucshandle import UcsHandle handle = UcsHandle(ip="", username="", password="") handle.login() """ boilerplate_end_str = """handle.logout()""" final_str = boilerplate_start_str + imports_str + script_output + boilerplate_end_str if output_file: _outfile = open(output_file, 'w') _outfile.write(final_str) _outfile.close() else: print(final_str)