def recurse_children(node, module): """Recurses through module levels and extracts xpaths, fully qualified type, primitive type, description, and children. Keep module name and fully qualified xpath intact, and also parse out the Cisco xpaths which are cleaner albeit less absolute. """ if not hasattr(node, 'i_children'): return {} children = (child for child in node.i_children if child.keyword in statements.data_definition_keywords) parsed_children = {} for child in children: module_name = module.arg prefixed_xpath = statements.mk_path_str(child, with_prefixes=True) no_prefix_xpath = statements.mk_path_str(child, with_prefixes=False) cisco_xpath = '%s:%s' % (module_name, no_prefix_xpath[1:]) parsed_children[cisco_xpath] = { 'module_name': module_name, 'xpath': prefixed_xpath, 'cisco_xpath': cisco_xpath, 'type': get_fq_type(child), 'primitive_type': get_primitive_type(child), 'description': get_description(child), 'children': recurse_children(child, module) } return parsed_children
def _add_yang_constraint(self, stmt, entry): yang_must = stmt.search_one('must') if yang_must is not None: entry['_constraint'] = statements.mk_path_str(yang_must) yang_when = stmt.search_one('when') if yang_when is not None: entry['_when'] = yang_when.arg
def _validate_leaf_ref(self, stmt, leafref, paths): if isinstance(leafref.i_type_spec, types.EmptyTypeSpec) is True: paths.append('null') else: validation = statements.validate_leafref_path( self._ctx, stmt, leafref.i_type_spec.path_spec, leafref.i_type_spec.path_) if validation is None: failed_validation = '%s leafref path %s is bad' % ( statements.mk_path_str(stmt), leafref.i_type_spec.path_.arg) self._logger.error(failed_validation) paths.append('Failed validation: ' + leafref.i_type_spec.path_.arg) else: paths.append(statements.mk_path_str(validation[0]))
def v_chk_leaf_mirroring(ctx, statement): """ Check that all config leaves are included in the state container """ # Skip the check if the container is not a parent of other containers if statement.search_one('container') is None: return containers = statement.search('container') # Only perform this check if this is a container that has both a config # and state container c_config, c_state = None, None for c in containers: if c.arg == 'config': c_config = c elif c.arg == 'state': c_state = c if not None in [c_config, c_state]: break if None in [c_config, c_state]: return config_elem_names = [i.arg for i in c_config.substmts if not i.arg == 'config' and i.keyword in INSTANTIATED_DATA_KEYWORDS] state_elem_names = [i.arg for i in c_state.substmts if not i.arg == 'state' and i.keyword in INSTANTIATED_DATA_KEYWORDS] for elem in config_elem_names: if not elem in state_elem_names: err_add(ctx.errors, statement.parent.pos, 'OC_OPSTATE_APPLIED_CONFIG', (elem, statements.mk_path_str(statement, False)))
def shortenNodeName(node, overridenName=None): global nodeDict global errorList global warnList xpath = statements.mk_path_str(node, False) xpath_prefix = statements.mk_path_str(node, True) if overridenName is None: name = node.i_module.i_modulename + xpath.replace('/', '_') else: name = overridenName name = name.replace('-', '_').lower() if name not in nodeDict: nodeDict[name] = xpath else: if overridenName is None: while name in nodeDict: if xpath == nodeDict[name]: break name = node.i_module.i_modulename + '_' + name name = name.replace('-', '_').lower() nodeDict[name] = xpath else: if xpath != nodeDict[name]: print("[Name collision] at ", xpath, " name: ", name, " is used, override using openapi-opid annotation") sys.exit(2) if len(name) > 150: if overridenName is None: # Generate unique hash mmhash = mmh3.hash(name, signed=False) name = node.i_module.i_modulename + str(mmhash) name = name.replace('-', '_').lower() nodeDict[name] = xpath warnList.append( "[Warn]: Using autogenerated shortened OperId for " + str(xpath_prefix) + " please provide unique manual input through openapi-opid annotation using deviation file if you want to override" ) if len(name) > 150: errorList.append( "[Error: ] OpID is too big for " + str(xpath_prefix) + " please provide unique manual input through openapi-opid annotation using deviation file" ) return name
def index_printer(stmt): global _yang_catalog_index_fd if stmt.arg is None: return skey = flatten_keyword(stmt.keyword) module = stmt.i_module rev = module.search_one('revision') org = module.search_one('organization') ns = module.search_one('namespace') revision = '' organization = '' namespace = '' if rev: revision = rev.arg if ns: namespace = ns.arg if namespace == '': (namespace, res_pf) = get_namespace_prefix(module.i_ctx, module) if org: organization = org.arg organization = normalize_org(organization, namespace) path = statements.mk_path_str(stmt, True) descr = stmt.search_one('description') dstr = '' if descr: dstr = descr.arg dstr = dstr.replace("'", r"''") subs = [] if revision == '': revision = '1970-01-01' for i in stmt.substmts: a = i.arg k = i.keyword k = flatten_keyword(k) if i.keyword not in statements.data_definition_keywords: subs.append(index_get_other(i)) else: has_children = hasattr(i, 'i_children') and len(i.i_children) > 0 if not a: a = '' else: a = index_escape_json(a) subs.append({ k: { 'value': a, 'has_children': has_children, 'children': [] } }) _yang_catalog_index_fd.write( "INSERT INTO yindex (module, revision, organization, path, statement, argument, description, properties) VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s');" % (module.arg, revision, organization, path, skey, stmt.arg, dstr, json.dumps(subs)) + "\n")
def index_printer(stmt): global _yang_catalog_index_values global _values global _ctx if stmt.arg is None: return skey = flatten_keyword(stmt.keyword) module = stmt.i_module rev = get_latest_revision(module) revision = '' path = statements.mk_path_str(stmt, True) descr = stmt.search_one('description') dstr = '' if descr: dstr = descr.arg dstr = dstr.replace("'", "''") subs = [] if rev == 'unknown': revision = '1970-01-01' else: revision = rev for i in stmt.substmts: a = i.arg k = i.keyword k = flatten_keyword(k) if i.keyword not in statements.data_definition_keywords: subs.append(index_get_other(i)) else: has_children = hasattr(i, 'i_children') and len(i.i_children) > 0 if not a: a = '' else: a = index_escape_json(a) subs.append({ k: { 'value': a, 'has_children': has_children, 'children': [] } }) vals = {} vals['module'] = module.arg vals['revision'] = revision vals['organization'] = resolve_organization(module) vals['path'] = path vals['statement'] = skey vals['argument'] = stmt.arg vals['description'] = dstr vals['properties'] = json.dumps(subs) _values['yindex'].append(vals)
def stmt_path(self): path = "/" if self.parent: path = statements.mk_path_str(self) if self.keyword == "choice": path += "#" + self.arg if self.keyword == "case": path = self.parent.path() path += ":" + self.arg return path
def produce_path_object_str(stmt): logging.debug("in produce_path_object_str with stmt %s %s", stmt.keyword, stmt.arg) global delimiter path = statements.mk_path_str(stmt) print('', delimiter) delimiter = ',' print(' "%s": {' % path) print(' "get": {') print(' "produces": [') print(' "application/vnd.yang.data+json",') print(' "application/vnd.yang.data+xml"') print(' ],') print(' "responses": {') print(' "200": {') print(' "description": "Some description",') print(' "schema": {') if stmt.keyword == "leaf": type, format = type_trans(str(stmt.search_one('type').arg)) print(' "type": "%s"' % type ) if stmt.keyword == "list": print(' "type": "array",') print(' "items": [') for s in stmt.i_children: produce_schema_str(s) print(' ]') if stmt.keyword == "leaf-list": type, format = type_trans(str(stmt.search_one('type').arg)) print(' "type": "array",') print(' "items": [') print(' "type": "%s"' % type ) print(' ]') if stmt.keyword == "container": print(' "type": "object",') print(' "properties": {') print(' "%s": {' % stmt.arg) print(' "properties": {') for s in stmt.i_children: produce_schema_str(s) print(' }') print(' }') print(' }') print(' }') print(' }') print(' }') print(' }') print(' }')
def v_chk_opstate_paths(ctx, statement): """ Check elements for compliance with the opstate structure. Called for leaves and leaf-lists. Particularly: * Skip checks for YANG list keys * Check that there is a single 'config' and 'state' container in the path * Check that elements in a 'config' container are r/w, and 'state' are ro """ pathstr = statements.mk_path_str(statement, False) # print "examining path to %s: %s" % (statement.arg, pathstr) # leaves that are list keys are exempt from this check. YANG # requires them at the top level of the list, i.e., not allowed # in a descendent container if statement.keyword == 'leaf' and hasattr(statement, 'i_is_key'): keytype = statement.search_one ('type') if keytype.arg != 'leafref': err_add(ctx.errors, statement.pos, 'OC_OPSTATE_KEY_LEAFREF', statement.arg) # print "leaf %s is a key, skipping" % statement.arg return #path_elements = [c.encode('ascii', 'ignore') for c in yangpath.split_paths(pathstr)] path_elements = yangpath.split_paths(pathstr) # count number of 'config' and 'state' elements in the path confignum = path_elements.count('config') statenum = path_elements.count('state') if confignum != 1 and statenum != 1: err_add(ctx.errors, statement.pos, 'OC_OPSTATE_CONTAINER_COUNT', (pathstr)) # for elements in a config or state container, make sure they have the # correct config property if statement.parent.keyword == 'container': # print "%s %s in container: %s (%s)" % (statement.keyword, pathstr, # str(statement.parent.arg), statement.i_config) if statement.parent.arg == 'config': if statement.i_config is False: err_add(ctx.errors, statement.pos, 'OC_OPSTATE_CONFIG_PROPERTY', (statement.arg, 'config', 'true')) elif statement.parent.arg == 'state' or statement.parent.arg == 'counters': if statement.i_config is True: err_add(ctx.errors, statement.parent.pos, 'OC_OPSTATE_CONFIG_PROPERTY', (statement.arg, 'state', 'false')) else: err_add(ctx.errors, statement.pos, 'OC_OPSTATE_CONTAINER_NAME', (statement.arg, pathstr))
def shortenNodeName(node): global nodeDict xpath = statements.mk_path_str(node, False) name = node.i_module.i_modulename + xpath.replace('/', '_') name = name.replace('-', '_').lower() if name not in nodeDict: nodeDict[name] = xpath else: while name in nodeDict: if xpath == nodeDict[name]: break name = node.i_module.i_modulename + '_' + name name = name.replace('-', '_').lower() nodeDict[name] = xpath return name
def print_node (node, module, fd, prefix, ctx, level=0): if node.keyword == 'rpc' or node.keyword == 'notification': return pathstr = statements.mk_path_str(node, True) if ctx.opts.strip_namespace: re_ns = re.compile (r'^.+:') #pathstr = re_ns.sub('/', pathstr, 0) path_components = [re_ns.sub('',comp) for comp in pathstr.split('/')] pathstr = '/'.join(path_components) # annotate the leaf nodes only if node.keyword == 'leaf-list' or (node.keyword == 'leaf' and not hasattr(node,'i_is_key')): if node.i_config == True: config = "rw" else: config = "ro" if ctx.opts.opstate_paths: base = os.path.dirname(pathstr) if ctx.opstate_paths.get(base): ctx.opstate_paths[base] += 1 else: ctx.opstate_paths[base] = 1 else: config = None pathstr = get_pathstr (pathstr, config, ctx, level) fd.write (pathstr) if ctx.opts.include_keyword: fd.write (' [%s]' % node.keyword) # fd.write (' %s' % module.i_modulename) fd.write ('\n') if hasattr(node, 'i_children'): level += 1 if ctx.opts.root_only: if level > 1: return if node.keyword in ['choice', 'case']: print_children(node.i_children, module, fd, prefix, ctx, level) else: print_children(node.i_children, module, fd, prefix, ctx, level)
def get_node_type(node): global codegenTypesToYangTypesMap xpath = statements.mk_path_str(node, True) nodetype = get_typename(node) if nodetype == 'identityref': #print("identityref ",typestring(node)) return codegenTypesToYangTypesMap["string"] if nodetype in codegenTypesToYangTypesMap: return codegenTypesToYangTypesMap[nodetype] if nodetype == 'union': return codegenTypesToYangTypesMap["string"] if "yang:date-and-time" in nodetype: return {"type": "string", "format": "date-time"} typedetails = typestring(node) typedetails2 = [] try: typedetails2 = typedetails.split("\n") except: print("typeinfo splitwrong") sys.exit(2) if typedetails2[1] in codegenTypesToYangTypesMap: return codegenTypesToYangTypesMap[typedetails2[1]] if typedetails2[1] == 'union': return codegenTypesToYangTypesMap["string"] if "yang:date-and-time" in typedetails2[1]: #print(nodetype," xpath: ", xpath) #TODO: change this to appropriate type when pyBreeze(oper codegen) starts to to support it return {"type": "string", "format": "date-time"} elif nodetype == "enumeration" or typedetails2[1] == "enumeration": return codegenTypesToYangTypesMap["string"] elif nodetype == "leafref" or typedetails2[1] == "leafref": return handle_leafref(node,xpath) elif nodetype == "empty": return {"type": "boolean", "format": "boolean"} else: print("unhandled type ", nodetype," xpath: ", xpath) sys.exit(2)
def print_node(node, module, fd, prefix, ctx, level=0): if node.keyword == 'rpc' or node.keyword == 'notification': return pathstr = statements.mk_path_str(node, True) if ctx.opts.strip_namespace: re_ns = re.compile(r'^.+:') path_components = [re_ns.sub('', comp) for comp in pathstr.split('/')] pathstr = '/'.join(path_components) # annotate the leaf nodes only if node.keyword == 'leaf-list' or \ (node.keyword == 'leaf' and not hasattr(node, 'i_is_key')): if node.i_config is True: config = "rw" else: config = "ro" if ctx.opts.opstate_paths: base = os.path.dirname(pathstr) if ctx.opstate_paths.get(base): ctx.opstate_paths[base] += 1 else: ctx.opstate_paths[base] = 1 else: config = None pathstr = get_pathstr(pathstr, config, ctx, level) fd.write(pathstr) if ctx.opts.include_keyword: fd.write(' [%s]' % node.keyword) fd.write('\n') if hasattr(node, 'i_children'): level += 1 if ctx.opts.root_only: if level > 1: return if node.keyword in ['choice', 'case']: print_children(node.i_children, module, fd, prefix, ctx, level) else: print_children(node.i_children, module, fd, prefix, ctx, level)
def check_leaf_mirroring(ctx, stmt): """Check applied configuration mirrors intended configuration. Check that each leaf in config has a corresponding leaf in state. Args: ctx: pyang.Context for the validation stmt: pyang.Statement for the parent container or list. """ # Skip the check if the container is not a parent of other containers if stmt.search_one("container") is None: return containers = stmt.search("container") # Only perform this check if this is a container that has both a config # and state container c_config, c_state = None, None for c in containers: if c.arg == "config": c_config = c elif c.arg == "state": c_state = c if None in [c_config, c_state]: return config_elem_names = [ i.arg for i in c_config.i_children if i.arg != "config" and i.keyword in INSTANTIATED_DATA_KEYWORDS ] state_elem_names = [ i.arg for i in c_state.i_children if i.arg != "state" and i.keyword in INSTANTIATED_DATA_KEYWORDS ] for elem in config_elem_names: if elem not in state_elem_names: err_add(ctx.errors, stmt.parent.pos, "OC_OPSTATE_APPLIED_CONFIG", (elem, statements.mk_path_str(stmt, False)))
def check_leaf_mirroring(ctx, stmt): """Check applied configuration mirrors intended configuration. Check that each leaf in config has a corresponding leaf in state. Args: ctx: pyang.Context for the validation stmt: pyang.Statement for the parent container or list. """ # Skip the check if the container is not a parent of other containers if stmt.search_one("container") is None: return containers = stmt.search("container") # Only perform this check if this is a container that has both a config # and state container c_config, c_state = None, None for c in containers: if c.arg == "config": c_config = c elif c.arg == "state": c_state = c if None in [c_config, c_state]: return config_elem_names = [i.arg for i in c_config.i_children if i.arg != "config" and i.keyword in INSTANTIATED_DATA_KEYWORDS] state_elem_names = [i.arg for i in c_state.i_children if i.arg != "state" and i.keyword in INSTANTIATED_DATA_KEYWORDS] for elem in config_elem_names: if elem not in state_elem_names: err_add(ctx.errors, stmt.parent.pos, "OC_OPSTATE_APPLIED_CONFIG", (elem, statements.mk_path_str(stmt, False)))
def print_node(s, module, fd, prefix, ctx, level=0): # Declare Variables pathstr = "" # sets pathstr = /ethernet-span-cfg:span-monitor-session if not ctx.opts.jstree_no_path: pathstr = statements.mk_path_str(s, False) # Generate new pathstr pathstr = module.i_modulename + pathstr # Only print pathstr if the node is a leaf if (s.keyword == 'leaf'): print(pathstr) #recursive step if hasattr(s, 'i_children'): level += 1 if s.keyword in ['choice', 'case']: print_children(s.i_children, module, fd, prefix, ctx, level) else: print_children(s.i_children, module, fd, prefix, ctx, level)
def check_opstate(ctx, stmt): """Check operational state validation rules. Args: ctx: pyang.Context for validation stmt: pyang.Statement for a leaf or leaf-list """ pathstr = statements.mk_path_str(stmt) # leaves that are list keys are exempt from this check. YANG # requires them at the top level of the list, i.e., not allowed # in a descendent container is_key = False if stmt.parent.keyword == "list" and stmt.keyword == "leaf": key_stmt = stmt.parent.search_one("key") if key_stmt is not None: if " " in key_stmt.arg: key_parts = [i for i in key_stmt.arg.split(" ")] else: key_parts = [key_stmt.arg] if stmt.arg in key_parts: is_key = True if is_key: keytype = stmt.search_one("type") if keytype.arg != "leafref": err_add(ctx.errors, stmt.pos, "OC_OPSTATE_KEY_LEAFREF", stmt.arg) keypath = keytype.search_one("path") keypathelem = yangpath.split_paths(keypath.arg) for i in range(0,len(keypathelem)): if keypathelem[i] in ["config", "state"]: if len(keypathelem[i+1:]) > 1: err_add(ctx.errors, stmt.pos, "OC_OPSTATE_KEY_LEAFREF_DIRECT", stmt.arg) return path_elements = yangpath.split_paths(pathstr) # count number of 'config' and 'state' elements in the path confignum = path_elements.count("config") statenum = path_elements.count("state") if confignum != 1 and statenum != 1: err_add(ctx.errors, stmt.pos, "OC_OPSTATE_CONTAINER_COUNT", (pathstr)) # for elements in a config or state container, make sure they have the # correct config property if stmt.parent.keyword == "container": if stmt.parent.arg == "config": if stmt.i_config is False: err_add(ctx.errors, stmt.pos, "OC_OPSTATE_CONFIG_PROPERTY", (stmt.arg, "config", "true")) elif stmt.parent.arg == "state": if stmt.i_config is True: err_add(ctx.errors, stmt.parent.pos, "OC_OPSTATE_CONFIG_PROPERTY", (stmt.arg, "state", "false")) else: valid_enclosing_state = False if stmt.i_config is False: # Allow nested containers within a state container path_elements = yangpath.split_paths(pathstr) if u"state" in path_elements: valid_enclosing_state = True if valid_enclosing_state is False: err_add(ctx.errors, stmt.pos, "OC_OPSTATE_CONTAINER_NAME", (stmt.arg, pathstr))
def _get_yang_path(self, stmt, module): return statements.mk_path_str(stmt)[1:]
def collect_child_doc(node, parent, top): """Collect documentation fields for a statement. node is a PYANG statement object, while parent is a ModuleDoc or StatementDoc object. top is the top level ModuleDoc object""" statement = StatementDoc(node.arg, node.keyword) statement.parent = parent statement.module_doc = top parent.children.append(statement) # fill in some attributes if they exist # type information type = node.search_one('type') if type is not None: # create the Type object statement.typedoc = TypeStatementDoc() collect_type_docs(type, statement.typedoc) # node description desc = node.search_one('description') if desc is not None: statement.attrs['desc'] = desc.arg # reference statement reference = node.search_one('reference') if reference is not None: statement.attrs['reference'] = reference.arg # default statement default = node.search_one('default') if default is not None: statement.attrs['default'] = default.arg # units statement units = node.search_one('units') if units is not None: statement.attrs['units'] = units.arg # schema path for the current node path = statements.mk_path_str(node, True) statement.attrs['path'] = path # id based on schema path node_id = node_to_id(statement) statement.attrs['id'] = node_id # rw or ro info if hasattr(node, 'i_config'): statement.attrs['config'] = node.i_config # for list nodes, record the keys if statement.keyword == 'list': statement.attrs['is_list'] = True keys = [] for key in node.i_key: keypath = statements.mk_path_str(key, True) keys.append((key.arg, path_to_id(keypath))) statement.attrs['keys'] = keys else: statement.attrs['is_list'] = False # note nodes that are list keys if hasattr(node, 'i_is_key'): statement.attrs['is_key'] = node.i_is_key else: statement.attrs['is_key'] = False # collect data from children, i.e., depth-first if hasattr(node, 'i_children'): for child in node.i_children: collect_child_doc(child, statement,top)
def build_payload(child, payloadDict, uriPath="", oneInstance=False, Xpath="", firstCall=False, config_false=False): global keysToLeafRefObjSet if child.i_config == False and not config_false: return # temporary chs = [ch for ch in child.i_children if ch.keyword in statements.data_definition_keywords] childJson = None if child.keyword == "container" and len(chs) > 0: if firstCall: nodeName = child.i_module.i_modulename + ':' + child.arg else: nodeName = child.arg payloadDict[nodeName] = OrderedDict() payloadDict[nodeName]["type"] = "object" payloadDict[nodeName]["properties"] = OrderedDict() childJson = payloadDict[nodeName]["properties"] elif child.keyword == "list" and len(chs) > 0: if firstCall: nodeName = child.i_module.i_modulename + ':' + child.arg else: nodeName = child.arg payloadDict[nodeName] = OrderedDict() returnJson = None # payloadDict[nodeName]["required"] = [] # for listKey in child.i_key: # payloadDict[nodeName]["required"].append(listKey.arg) # if oneInstance: # payloadDict[nodeName]["type"] = "object" # payloadDict[nodeName]["required"] = [] # payloadDict[nodeName]["properties"] = OrderedDict() # returnJson = payloadDict[nodeName]["properties"] # for listKey in child.i_key: # payloadDict[nodeName]["required"].append(listKey.arg) # else: payloadDict[nodeName]["type"] = "array" payloadDict[nodeName]["items"] = OrderedDict() payloadDict[nodeName]["items"]["type"] = "object" payloadDict[nodeName]["items"]["required"] = [] for listKey in child.i_key: payloadDict[nodeName]["items"]["required"].append(listKey.arg) payloadDict[nodeName]["items"]["properties"] = OrderedDict() returnJson = payloadDict[nodeName]["items"]["properties"] childJson = returnJson elif child.keyword == "leaf" or child.keyword == "leaf-list": if firstCall: nodeName = child.i_module.i_modulename + ':' + child.arg else: nodeName = child.arg parentXpath = statements.mk_path_str(child.parent, True) if hasattr(child, 'i_is_key') and Xpath == parentXpath: if '=' in uriPath.split('/')[-1]: return payloadDict[nodeName] = OrderedDict() typeInfo = get_node_type(child) if 'type' in typeInfo: dType = typeInfo["type"] else: dType = "string" payloadDict[nodeName]["type"] = dType if 'format' in typeInfo: payloadDict[nodeName]["format"] = typeInfo["format"] if hasattr(child, 'i_children'): for ch in child.i_children: build_payload(ch,childJson,uriPath, False, Xpath, False, config_false)
def print_node(s, module, fd, prefix, ctx, level=0): global levelcnt fontstarttag = "" fontendtag = "" status = get_status_str(s) nodetype = '' options = '' folder = False if s.i_module.i_modulename == module.i_modulename: name = s.arg else: name = s.i_module.i_prefix + ':' + s.arg pr = module.search_one('prefix') if pr is not None: prstr = pr.arg else: prstr = "" descr = s.search_one('description') descrstring = "No description" if descr is not None: descrstring = descr.arg flags = get_flags_str(s) if s.keyword == 'list': folder = True elif s.keyword == 'container': folder = True p = s.search_one('presence') if p is not None: pr_str = p.arg options = "<abbr title=\"" + pr_str + "\">Presence</abbr>" elif s.keyword == 'choice': folder = True m = s.search_one('mandatory') if m is None or m.arg == 'false': name = '(' + s.arg + ')' options = 'Choice' else: name = '(' + s.arg + ')' elif s.keyword == 'case': folder = True # fd.write(':(' + s.arg + ')') name = ':(' + s.arg + ')' elif s.keyword == 'input': folder = True elif s.keyword == 'output': folder = True elif s.keyword == 'rpc': folder = True elif s.keyword == 'notification': folder = True else: if s.keyword == 'leaf-list': options = '*' elif s.keyword == 'leaf' and not hasattr(s, 'i_is_key'): m = s.search_one('mandatory') if m is None or m.arg == 'false': options = '?' nodetype = get_typename(s) if s.keyword == 'list' and s.search_one('key') is not None: name += '[' + s.search_one('key').arg + ']' descr = s.search_one('description') if descr is not None: descrstring = ''.join([x for x in descr.arg if ord(x) < 128]) else: descrstring = "No description"; levelcnt[level] += 1 idstring = str(levelcnt[1]) for i in range(2,level+1): idstring += '-' + str(levelcnt[i]) pathstr = "" if not ctx.opts.jstree_no_path: pathstr = statements.mk_path_str(s, True) if '?' in options: fontstarttag = "<em>" fontendtag = "</em>" keyword = s.keyword if folder: # html plugin specific changes if hasattr(ctx, 'html_plugin_user'): from pyang.plugins.html import force_link name = force_link(ctx,s,module,name) fd.write("""<tr id="%s" class="a"> <td nowrap id="p4000"> <div id="p5000" class="tier%s"> <a href="#" id="p6000" onclick="toggleRows(this);return false" class="folder"> </a> <abbr title="%s">%s</abbr> </div> </td> \n""" %(idstring, level, descrstring, name)) fd.write("""<td nowrap>%s</td> <td nowrap>%s</td> <td nowrap>%s</td> <td>%s</td> <td>%s</td> <td nowrap>%s</td> </tr> \n""" %(s.keyword, nodetype, flags, options, status, pathstr)) else: if s.keyword in ['action', ('tailf-common', 'action')]: classstring = "action" typeinfo = action_params(s) typename = "parameters" keyword = "action" elif s.keyword == 'rpc' or s.keyword == 'notification': classstring = "folder" typeinfo = action_params(s) typename = "parameters" else: classstring = s.keyword typeinfo = typestring(s) typename = nodetype fd.write("""<tr id="%s" class="a"> <td nowrap> <div id=9999 class=tier%s> <a class="%s"> </a> <abbr title="%s"> %s %s %s</abbr> </div> </td> <td>%s</td> <td nowrap><abbr title="%s">%s</abbr></td> <td nowrap>%s</td> <td>%s</td> <td>%s</td> <td nowrap>%s</td</tr> \n""" %(idstring, level, classstring, descrstring, fontstarttag, name, fontendtag, keyword, typeinfo, typename, flags, options, status, pathstr)) if hasattr(s, 'i_children'): level += 1 if s.keyword in ['choice', 'case']: print_children(s.i_children, module, fd, prefix, ctx, level) else: print_children(s.i_children, module, fd, prefix, ctx, level)
def _get_yang_path(self, stmt): if stmt.parent is not None: return '%s:%s' % (self._module.arg, statements.mk_path_str(stmt)[1:]) else: return self._module.arg
def getType(node): global codegenTypesToYangTypesMap xpath = statements.mk_path_str(node, True) def resolveType(stmt, nodeType): if nodeType == "string" \ or nodeType == "instance-identifier" \ or nodeType == "identityref": return codegenTypesToYangTypesMap["string"] elif nodeType == "enumeration": enums = [] for enum in stmt.substmts: if enum.keyword == "enum": enums.append(enum.arg) return codegenTypesToYangTypesMap["string"], enums elif nodeType == "empty" or nodeType == "boolean": return {"type": "boolean", "format": "boolean"} elif nodeType == "leafref": return handle_leafref(node, xpath) elif nodeType == "union": return codegenTypesToYangTypesMap["string"] elif nodeType == "decimal64": return codegenTypesToYangTypesMap[nodeType] elif nodeType in [ 'int8', 'int16', 'int32', 'int64', 'uint8', 'uint16', 'uint32', 'uint64', 'binary', 'bits' ]: return codegenTypesToYangTypesMap[nodeType] else: print("no base type found") sys.exit(2) base_types = [ 'int8', 'int16', 'int32', 'int64', 'uint8', 'uint16', 'uint32', 'uint64', 'decimal64', 'string', 'boolean', 'enumeration', 'bits', 'binary', 'leafref', 'identityref', 'empty', 'union', 'instance-identifier' ] # Get Type of a node t = node.search_one('type') while t.arg not in base_types: # chase typedef name = t.arg if name.find(":") == -1: prefix = None else: [prefix, name] = name.split(':', 1) if prefix is None or t.i_module.i_prefix == prefix: # check local typedefs pmodule = node.i_module typedef = statements.search_typedef(t, name) else: # this is a prefixed name, check the imported modules err = [] pmodule = util.prefix_to_module(t.i_module, prefix, t.pos, err) if pmodule is None: return typedef = statements.search_typedef(pmodule, name) if typedef is None: print( "Typedef ", name, " is not found, make sure all dependent modules are present") sys.exit(2) t = typedef.search_one('type') return resolveType(t, t.arg)
def print_node(s, module, fd, prefix, ctx, level=0): fontstarttag = "" fontendtag = "" nodetype = '' options = '' folder = False if s.i_module.i_modulename == module.i_modulename: name = s.arg else: name = s.i_module.i_prefix + ':' + s.arg if s.keyword == 'list': folder = True elif s.keyword == 'container': folder = True p = s.search_one('presence') if p is not None: pr_str = p.arg options = "<abbr title=\"" + pr_str + "\">Presence</abbr>" elif s.keyword == 'choice': folder = True m = s.search_one('mandatory') if m is None or m.arg == 'false': name = '(' + s.arg + ')' options = 'Choice' else: name = '(' + s.arg + ')' elif s.keyword == 'case': folder = True # fd.write(':(' + s.arg + ')') name = ':(' + s.arg + ')' elif s.keyword == 'input': folder = True elif s.keyword == 'output': folder = True elif s.keyword == 'rpc': folder = True elif s.keyword == 'notification': folder = True else: if s.keyword == 'leaf-list': options = '*' elif s.keyword == 'leaf' and not hasattr(s, 'i_is_key'): m = s.search_one('mandatory') if m is None or m.arg == 'false': options = '?' nodetype = get_typename(s) if s.keyword == 'list' and s.search_one('key') is not None: name += '[' + s.search_one('key').arg + ']' pathstr = "" if not ctx.opts.jstree_no_path: pathstr = statements.mk_path_str(s, True) keyword = s.keyword # # Just print path string # print("%s,%s,%s" % (pathstr, s.keyword, nodetype)) if hasattr(s, 'i_children'): level += 1 if s.keyword in ['choice', 'case']: print_children(s.i_children, module, fd, prefix, ctx, level) else: print_children(s.i_children, module, fd, prefix, ctx, level)
def _produce_node_iter(stmt, last, top): # print "in produce_node_iter: %s" % stmt.keyword, stmt.arg path = statements.mk_path_str(stmt) if stmt.keyword == "leaf": type, format = type_trans(str(stmt.search_one('type').arg)) if stmt.parent.keyword == "list": print('{') print(' "type": "object",') print(' "properties": {') if type == 'enumeration': print('"%s": {' % stmt.arg) print(' "enum": [') for ch in stmt.search("type"): for enum in ch.search("enum"): if ch.search("enum")[-1] == enum: print('"%s"' % enum.arg) else: print('"%s",' % enum.arg) print(' ]') else: print('"%s": {' % stmt.arg) print(' "type": "%s"' % type) if format is not None: print(' ,"format": "%s"' % format) if stmt.parent.keyword == "list": print(' }') print(' }') close_object(stmt, top) if stmt.keyword == "leaf-list": type, format = type_trans(str(stmt.search_one('type').arg)) print('"%s": {' % stmt.arg) print(' "type": "array",') print(' "items": {') print(' "type": "%s"' % type) print(' }') close_object(stmt, top) if stmt.keyword == "list": print('"%s": {' % stmt.arg) print(' "type": "array",') print(' "items": [') if hasattr(stmt, 'i_children'): for s in stmt.i_children: _produce_node_iter(s, last, top) pass print(' ]') close_object(stmt, top) if stmt.keyword == "container": if stmt.parent.keyword == "list": print('{') print(' "type": "object",') print(' "properties": {') print('"%s": {' % stmt.arg) print(' "type": "object",') print(' "properties": {') if hasattr(stmt, 'i_children'): for s in stmt.i_children: _produce_node_iter(s, last, top) pass print(' }') if stmt.parent.keyword == "list": print(' }') print(' }') close_object(stmt, top) if stmt.keyword == "choice": # XXX: This needs more work, probably around JSON Schema 'oneOf' if hasattr(stmt, 'i_children'): for s in stmt.i_children: _produce_node_iter(s, last, top) pass if stmt.keyword == "case": # XXX: This needs more work, probably around JSON Schema 'oneOf' if hasattr(stmt, 'i_children'): for s in stmt.i_children: _produce_node_iter(s, last, top) pass
def print_node(s, module, fd, prefix, path, ctx, level=0): global levelcnt fontstarttag = "" fontendtag = "" status = get_status_str(s) nodetype = '' options = '' folder = False if s.i_module.i_modulename == module.i_modulename: name = s.arg else: name = s.i_module.i_prefix + ':' + s.arg pr = module.search_one('prefix') if pr is not None: prstr = pr.arg else: prstr = "" descr = s.search_one('description') descrstring = "No description" if descr is not None: descrstring = descr.arg flags = get_flags_str(s) if s.keyword in ('list', 'input', 'output', 'rpc', 'notification', 'action'): folder = True elif s.keyword == 'container': folder = True p = s.search_one('presence') if p is not None: pr_str = p.arg options = "<abbr title=\"" + pr_str + "\">Presence</abbr>" elif s.keyword == 'choice': folder = True m = s.search_one('mandatory') if m is None or m.arg == 'false': name = '(' + s.arg + ')' options = 'Choice' else: name = '(' + s.arg + ')' elif s.keyword == 'case': folder = True # fd.write(':(' + s.arg + ')') name = ':(' + s.arg + ')' else: if s.keyword == 'leaf-list': options = '*' elif s.keyword == 'leaf' and not hasattr(s, 'i_is_key'): m = s.search_one('mandatory') if m is None or m.arg == 'false': options = '?' nodetype = get_typename(s) if s.keyword == 'list' and s.search_one('key') is not None: name += '[' + s.search_one('key').arg + ']' descr = s.search_one('description') if descr is not None: descrstring = ''.join([x for x in descr.arg if ord(x) < 128]) else: descrstring = "No description" levelcnt[level] += 1 idstring = str(levelcnt[1]) for i in range(2, level + 1): idstring += '-' + str(levelcnt[i]) pathstr = "" if not ctx.opts.jstree_no_path: pathstr = statements.mk_path_str(s, True) if '?' in options: fontstarttag = "<em>" fontendtag = "</em>" keyword = s.keyword type_html_info = "" attr_html_info = "" element_htmnl_info = "" if folder: objectID = str(s.pos.line) + '$' + s.pos.ref print("%s: %s" % (s.keyword, objectID)) attr_html_info = """<abbr title="%s">%s</abbr>""" % (descrstring, name) classstring = s.keyword if s.keyword in ('action', 'rpc', 'notification'): type_html_info = """<td nowrap><abbr title="%s">%s</abbr></td> """ % (action_params(s), "parameters") else: type_html_info = """<td nowrap>%s</td>""" % (nodetype) element_html_info = """ <td nowrap id="p4000"> <div id="p5000" class="tier%s"> <a href="#" id="p6000" onclick="toggleRows(this);return false" class="%s"> </a> %s </div> </td>""" % (level, "folder", attr_html_info) else: attr_html_info = """<attr title="%s"> %s %s %s</abbr> """ % (descrstring, fontstarttag, name, fontendtag) if s.keyword == ('tailf-common', 'action'): type_html_info = """<td nowrap><abbr title="%s">%s</abbr></td> """ % (action_params(s), "parameters") classstring = "action" else: type_html_info = """<td nowrap><abbr title="%s">%s</abbr></td> """ % (typestring(s), nodetype) classstring = s.keyword element_html_info = """ <td nowrap> <div id=9999 class=tier%s> <a class="%s"> </a> %s </div> </td> """ % (level, classstring, attr_html_info) fd.write(""" <tr id="%s" class="a"> %s <td nowrap>%s</td> %s <td nowrap>%s</td> <td>%s</td> <td>%s</td> <td nowrap>%s</td> </tr>""" % (idstring, element_html_info, classstring, type_html_info, flags, options, status, pathstr)) if hasattr(s, 'i_children'): level += 1 chs = s.i_children if path is not None and len(path) > 0: chs = [ch for ch in chs if ch.arg == path[0]] path = path[1:] if s.keyword in ['choice', 'case']: print_children(chs, module, fd, prefix, path, ctx, level) else: print_children(chs, module, fd, prefix, path, ctx, level)
def print_node(s, module, fd, prefix, level=0): global levelcnt # fd.write("%s%s--" % (prefix[0:-1], get_status_str(s))) status = get_status_str(s) nodetype = '' options = '' folder = False if s.i_module.i_modulename == module.i_modulename: name = s.arg else: name = s.i_module.i_prefix + ':' + s.arg flags = get_flags_str(s) if s.keyword == 'list': folder = True # fd.write(flags + " " + name) elif s.keyword == 'container': folder = True p = s.search_one('presence') if p is not None: # name += '?' pr_str = p.arg options = "<abbr title=\"" + pr_str + "\">Presence</abbr>" # fd.write(flags + " " + name) elif s.keyword == 'choice': folder = True m = s.search_one('mandatory') if m is None or m.arg == 'false': # fd.write(flags + ' (' + s.arg + ')') name = '(' + s.arg + ')' options = 'Choice' else: # fd.write(flags + ' (' + s.arg + ')?') name = '(' + s.arg + ')' elif s.keyword == 'case': folder = True # fd.write(':(' + s.arg + ')') name = ':(' + s.arg + ')' elif s.keyword == 'input': folder = True elif s.keyword == 'output': folder = True elif s.keyword == 'rpc': folder = True else: if s.keyword == 'leaf-list': # name += '*' options = '*' elif s.keyword == 'leaf' and not hasattr(s, 'i_is_key'): m = s.search_one('mandatory') if m is None or m.arg == 'false': options = '?' nodetype = get_typename(s) # fd.write("%s %-*s %s" % (flags, width+1, name, get_typename(s))) if s.keyword == 'list' and s.search_one('key') is not None: # fd.write(" [%s]" % s.search_one('key').arg) name += '[' + s.search_one('key').arg + ']' descr = s.search_one('description') if descr is not None: descrstring = ''.join([x for x in descr.arg if ord(x) < 128]) else: descrstring = ""; levelcnt[level] += 1 idstring = str(levelcnt[1]) for i in range(2,level+1): idstring += '-' + str(levelcnt[i]) pathstr = statements.mk_path_str(s, True) if folder: # hypertext link to non-existing YANG HTML.... #fd.write("<tr id=\"%s\" class=\"a\"> <td id=\"p4000\"><div id=\"p5000\" class=\"tier%s\"><a id=\"p6000\" href=\"#\" onclick=\"toggleRows(this)\" class=\"folder\"></a><a title=\"%s\" target=\"src\" href=\"yang-module.shtml#%s\">%s</a></div></td> \n" %(idstring, level, descrstring, s.arg, name)) fd.write("<tr id=\"%s\" class=\"a\"> <td id=\"p4000\"><div id=\"p5000\" class=\"tier%s\"><a id=\"p6000\" href=\"#\" onclick=\"toggleRows(this)\" class=\"folder\"></a>%s</div></td> \n" %(idstring, level, name)) fd.write('<td title="I am a title">%s</td> <td>%s</td> <td>%s</td> <td>%s</td> <td>%s</td> <td>%s</td> </tr> \n' %(s.keyword, nodetype, flags, options, status, pathstr)) else: if s.keyword == ('tailf-common', 'action'): classstring = "action" typeinfo = action_params(s) typename = "parameters" else: classstring = s.keyword typeinfo = typestring(s) typename = nodetype # hypertext link to non-existing YANG HTML.... #fd.write('<tr id=\"%s\" class=\"a\"><td><div id=9999 class=tier%s> <a href =\"#\" class=\"%s\"></a><a title=\"%s\" target=\"src\" href=\"yang-module.shtml#%s\">%s</a></div> </td> <td>%s</td> <td><abbr title=\"%s\">%s</abbr></td> <td>%s</td> <td>%s</td> <td>%s</td><td>%s</td</tr> \n' %(idstring, level,classstring, descrstring, s.keyword, name,s.keyword, typeinfo, typename, flags, options, status, pathstr)) fd.write('<tr id=\"%s\" class=\"a\"><td><div id=9999 class=tier%s> <a href =\"#\" class=\"%s\"></a>%s</div> </td> <td>%s</td> <td><abbr title=\"%s\">%s</abbr></td> <td>%s</td> <td>%s</td> <td>%s</td><td>%s</td</tr> \n' %(idstring, level,classstring, name,s.keyword, typeinfo, typename, flags, options, status, pathstr)) if hasattr(s, 'i_children'): level += 1 if s.keyword in ['choice', 'case']: print_children(s.i_children, module, fd, prefix, level) else: print_children(s.i_children, module, fd, prefix, level)
def collect_child_doc(node, parent, top): """Collect documentation fields for a statement. node is a PYANG statement object, while parent is a ModuleDoc or StatementDoc object. top is the top level ModuleDoc object""" statement = StatementDoc(node.arg, node.keyword) statement.parent = parent statement.module_doc = top parent.children.append(statement) # fill in some attributes if they exist # type information type = node.search_one('type') if type is not None: # create the Type object statement.typedoc = TypeStatementDoc() collect_type_docs(type, statement.typedoc) # node description desc = node.search_one('description') if desc is not None: statement.attrs['desc'] = desc.arg # reference statement reference = node.search_one('reference') if reference is not None: statement.attrs['reference'] = reference.arg # default statement default = node.search_one('default') if default is not None: statement.attrs['default'] = default.arg # units statement units = node.search_one('units') if units is not None: statement.attrs['units'] = units.arg # schema path for the current node path = statements.mk_path_str(node, True) statement.attrs['path'] = path # id based on schema path node_id = node_to_id(statement) statement.attrs['id'] = node_id # rw or ro info if hasattr(node, 'i_config'): statement.attrs['config'] = node.i_config # for list nodes, record the keys if statement.keyword == 'list': statement.attrs['is_list'] = True keys = [] for key in node.i_key: keypath = statements.mk_path_str(key, True) keys.append((key.arg, path_to_id(keypath))) statement.attrs['keys'] = keys else: statement.attrs['is_list'] = False # note nodes that are list keys if hasattr(node, 'i_is_key'): statement.attrs['is_key'] = node.i_is_key else: statement.attrs['is_key'] = False # collect data from children, i.e., depth-first if hasattr(node, 'i_children'): for child in node.i_children: module_name = child.i_module.i_modulename if child.arg == 'frinx-documentation': if 'frinx-documentation' not in statement.attrs: statement.attrs['frinx-documentation'] = {} if child.i_module.i_prefix not in statement.attrs['frinx-documentation']: statement.attrs['frinx-documentation'][child.i_module.i_prefix] = {} frinx_device_type = child.search_one((module_name, u'frinx-docs-device-type')) frinx_device_version = child.search_one((module_name, u'frinx-docs-device-version')) frinx_device_protocol = child.search_one((module_name, u'frinx-docs-device-protocol')) frinx_reader = child.search_one((module_name, u'frinx-docs-reader')) frinx_reader_detail = child.search_one((module_name, u'frinx-docs-reader-detail')) frinx_writer = child.search_one((module_name, u'frinx-docs-writer')) frinx_writer_detail = child.search_one((module_name, u'frinx-docs-writer-detail')) statement.attrs['frinx-documentation'][child.i_module.i_prefix][ 'frinx-docs-type'] = frinx_device_type.arg statement.attrs['frinx-documentation'][child.i_module.i_prefix][ 'frinx-docs-version'] = frinx_device_version.arg statement.attrs['frinx-documentation'][child.i_module.i_prefix][ 'frinx-docs-protocol'] = frinx_device_protocol.arg if frinx_reader is not None: statement.attrs['frinx-documentation'][child.i_module.i_prefix][ 'frinx-docs-reader'] = frinx_reader.arg if frinx_reader_detail is not None: statement.attrs['frinx-documentation'][child.i_module.i_prefix][ 'frinx-docs-reader-detail'] = escape_html(frinx_reader_detail.arg) if frinx_writer is not None: statement.attrs['frinx-documentation'][child.i_module.i_prefix][ 'frinx-docs-writer'] = frinx_writer.arg if frinx_writer_detail is not None: # Substitution used here is to make Chunk readable again as it had to be "escaped" in yang model. statement.attrs['frinx-documentation'][child.i_module.i_prefix][ 'frinx-docs-writer-detail'] = escape_html(re.sub("/%/", "%", frinx_writer_detail.arg)) elif child.arg == 'usecase-tag': frinx_usecase = child.search_one((module_name, u'frinx-usecase')) if frinx_usecase is not None: if 'frinx-usecase' not in statement.attrs.keys(): statement.attrs['frinx-usecase'] = [] statement.attrs['frinx-usecase'].append(frinx_usecase.arg) else: collect_child_doc(child, statement, top)
def walk_child(child): global XpathToBodyTagDict # if child.i_config == False: # pdb.set_trace() # return # temporary actXpath = statements.mk_path_str(child, True) metadata = [] pathstr = mk_path_refine(child, metadata) if actXpath in keysToLeafRefObjSet: return if child.keyword == "list": listMetaData = copy.deepcopy(metadata) walk_child_for_list_base(child,actXpath,pathstr, listMetaData) if child.keyword in ["list", "container", "leaf", "leaf-list"]: payload = OrderedDict() add_swagger_tag(child.i_module) build_payload(child, payload, pathstr, True, actXpath, True) if len(payload) == 0 and child.i_config == True: return if child.keyword == "leaf" or child.keyword == "leaf-list": if hasattr(child, 'i_is_key'): if child.i_leafref is not None: listKeyPath = statements.mk_path_str(child.i_leafref_ptr[0], True) if listKeyPath not in keysToLeafRefObjSet: keysToLeafRefObjSet.add(listKeyPath) return defName = shortenNodeName(child,actXpath) if child.i_config == False: payload_get = OrderedDict() build_payload(child, payload_get, pathstr, True, actXpath, True, True) if len(payload_get) == 0: return defName_get = "get" + '_' + defName swaggerDict["definitions"][defName_get] = OrderedDict() swaggerDict["definitions"][defName_get]["type"] = "object" swaggerDict["definitions"][defName_get]["properties"] = copy.deepcopy(payload_get) swagger_it(child, defName_get, pathstr, payload_get, metadata, "get", defName_get) else: swaggerDict["definitions"][defName] = OrderedDict() swaggerDict["definitions"][defName]["type"] = "object" swaggerDict["definitions"][defName]["properties"] = copy.deepcopy(payload) for verb in verbs: if verb == "get": payload_get = OrderedDict() build_payload(child, payload_get, pathstr, True, actXpath, True, True) if len(payload_get) == 0: continue defName_get = "get" + '_' + defName swaggerDict["definitions"][defName_get] = OrderedDict() swaggerDict["definitions"][defName_get]["type"] = "object" swaggerDict["definitions"][defName_get]["properties"] = copy.deepcopy(payload_get) swagger_it(child, defName_get, pathstr, payload_get, metadata, verb, defName_get) continue if verb == "post" and child.keyword == "list": continue swagger_it(child, defName, pathstr, payload, metadata, verb) if hasattr(child, 'i_children'): for ch in child.i_children: walk_child(ch)
def print_node(s, module, fd, prefix, ctx, level=0): global levelcnt fontstarttag = "" fontendtag = "" status = get_status_str(s) nodetype = '' options = '' folder = False if s.i_module.i_modulename == module.i_modulename: name = s.arg else: name = s.i_module.i_prefix + ':' + s.arg pr = module.search_one('prefix') if pr is not None: prstr = pr.arg else: prstr = "" descr = s.search_one('description') descrstring = "No description" if descr is not None: descrstring = descr.arg flags = get_flags_str(s) if s.keyword == 'list': folder = True elif s.keyword == 'container': folder = True p = s.search_one('presence') if p is not None: pr_str = p.arg options = "<abbr title=\"" + pr_str + "\">Presence</abbr>" elif s.keyword == 'choice': folder = True m = s.search_one('mandatory') if m is None or m.arg == 'false': name = '(' + s.arg + ')' options = 'Choice' else: name = '(' + s.arg + ')' elif s.keyword == 'case': folder = True # fd.write(':(' + s.arg + ')') name = ':(' + s.arg + ')' elif s.keyword == 'input': folder = True elif s.keyword == 'output': folder = True elif s.keyword == 'rpc': folder = True elif s.keyword == 'notification': folder = True else: if s.keyword == 'leaf-list': options = '*' elif s.keyword == 'leaf' and not hasattr(s, 'i_is_key'): m = s.search_one('mandatory') if m is None or m.arg == 'false': options = '?' nodetype = get_typename(s) if s.keyword == 'list' and s.search_one('key') is not None: name += '[' + s.search_one('key').arg + ']' descr = s.search_one('description') if descr is not None: descrstring = ''.join([x for x in descr.arg if ord(x) < 128]) else: descrstring = "No description" levelcnt[level] += 1 idstring = str(levelcnt[1]) for i in range(2, level + 1): idstring += '-' + str(levelcnt[i]) pathstr = statements.mk_path_str(s, True) if not ctx.opts.jstree_no_path: if ctx.opts.strip_namespace: re_ns = re.compile(r'^.+:') path_components = [ re_ns.sub('', comp) for comp in pathstr.split('/') ] pathstr = '/'.join(path_components) else: # append the path to the description popup descrstring = descrstring + "\n\npath: " + pathstr pathstr = "" if '?' in options: fontstarttag = "<em>" fontendtag = "</em>" keyword = s.keyword if folder: # html plugin specific changes if hasattr(ctx, 'html_plugin_user'): from pyang.plugins.html import force_link name = force_link(ctx, s, module, name) fd.write("""<tr id="%s" class="a"> <td nowrap id="p4000"> <div id="p5000" style="margin-left:%sem;"> <a href="#" id="p6000" onclick="toggleRows(this);return false" class="folder"> </a> <abbr title="%s">%s</abbr> </div> </td> \n""" % (idstring, (level * 1.5 - 1.5), descrstring, name)) fd.write("""<td nowrap>%s</td> <td nowrap>%s</td> <td nowrap>%s</td> <td>%s</td> <td>%s</td> <td nowrap>%s</td> </tr> \n""" % (s.keyword, nodetype, flags, options, status, pathstr)) else: if s.keyword in ['action', ('tailf-common', 'action')]: classstring = "action" typeinfo = action_params(s) typename = "parameters" keyword = "action" elif s.keyword == 'rpc' or s.keyword == 'notification': classstring = "folder" typeinfo = action_params(s) typename = "parameters" else: classstring = s.keyword typeinfo = typestring(s) typename = nodetype fd.write("""<tr id="%s" class="a"> <td nowrap> <div id=9999 style="margin-left: %sem;"> <a class="%s"> </a> <abbr title="%s"> %s %s %s</abbr> </div> </td> <td>%s</td> <td nowrap><abbr title="%s">%s</abbr></td> <td nowrap>%s</td> <td>%s</td> <td>%s</td> <td nowrap>%s</td</tr> \n""" % (idstring, (level * 1.5 - 1.5), classstring, descrstring, fontstarttag, name, fontendtag, keyword, typeinfo, typename, flags, options, status, pathstr)) if hasattr(s, 'i_children'): level += 1 if s.keyword in ['choice', 'case']: print_children(s.i_children, module, fd, prefix, ctx, level) else: print_children(s.i_children, module, fd, prefix, ctx, level)
def get_node(s, module, prefix, ctx): child = {} child['status'] = get_status_str(s) options = '' if s.i_module.i_modulename == module.i_modulename: name = s.arg else: name = s.i_module.i_prefix + ':' + s.arg child['name'] = name pr = module.search_one('prefix') if pr is not None: child['prefix'] = pr.arg else: child['prefix'] = "" descr = s.search_one('description') child['description'] = "No description" if descr is not None: child['description'] = json_escape(descr.arg) child['flags'] = get_flags(s) if s.keyword == 'list': pass elif s.keyword == 'container': p = s.search_one('presence') if p is not None: child['presence'] = p.arg options = "Presence" elif s.keyword == 'choice': m = s.search_one('mandatory') if m is None or m.arg == 'false': child['name'] = '(' + s.arg + ')' options = 'Choice' else: child['name'] = '(' + s.arg + ')' elif s.keyword == 'case': child['name'] = ':(' + s.arg + ')' elif s.keyword == 'input': pass elif s.keyword == 'output': pass elif s.keyword == 'rpc': pass elif s.keyword == 'notification': pass else: if s.keyword == 'leaf-list': options = '*' elif s.keyword == 'leaf' and not hasattr(s, 'i_is_key'): m = s.search_one('mandatory') if m is None or m.arg == 'false': options = '?' child['type'] = get_typename(s) if s.keyword == 'list' and s.search_one('key') is not None: child['list_key'] = s.search_one('key').arg child['path'] = statements.mk_path_str(s, True) child['schema_type'] = s.keyword child['options'] = options if s.keyword == ('tailf-common', 'action'): child['class'] = "action" child['type_info'] = action_params(s) child['schema_type'] = "action" elif s.keyword == 'rpc' or s.keyword == 'notification': child['class'] = "folder" child['type_info'] = action_params(s) else: child['class'] = s.keyword child['type_info'] = typestring(s) if hasattr(s, 'i_children'): if s.keyword in ['choice', 'case']: child['children'] = get_children(s.i_children, module, prefix, ctx) else: child['children'] = get_children(s.i_children, module, prefix, ctx) return child
def print_node(s, module, fd, prefix, level=0): global levelcnt # fd.write("%s%s--" % (prefix[0:-1], get_status_str(s))) status = get_status_str(s) nodetype = '' options = '' folder = False if s.i_module.i_modulename == module.i_modulename: name = s.arg else: name = s.i_module.i_prefix + ':' + s.arg flags = get_flags_str(s) if s.keyword == 'list': folder = True # fd.write(flags + " " + name) elif s.keyword == 'container': folder = True p = s.search_one('presence') if p is not None: # name += '?' pr_str = p.arg options = "<abbr title=\"" + pr_str + "\">Presence</abbr>" # fd.write(flags + " " + name) elif s.keyword == 'choice': folder = True m = s.search_one('mandatory') if m is None or m.arg == 'false': # fd.write(flags + ' (' + s.arg + ')') name = '(' + s.arg + ')' options = 'Choice' else: # fd.write(flags + ' (' + s.arg + ')?') name = '(' + s.arg + ')' elif s.keyword == 'case': folder = True # fd.write(':(' + s.arg + ')') name = ':(' + s.arg + ')' elif s.keyword == 'input': folder = True elif s.keyword == 'output': folder = True elif s.keyword == 'rpc': folder = True else: if s.keyword == 'leaf-list': # name += '*' options = '*' elif s.keyword == 'leaf' and not hasattr(s, 'i_is_key'): m = s.search_one('mandatory') if m is None or m.arg == 'false': options = '?' nodetype = get_typename(s) # fd.write("%s %-*s %s" % (flags, width+1, name, get_typename(s))) if s.keyword == 'list' and s.search_one('key') is not None: # fd.write(" [%s]" % s.search_one('key').arg) name += '[' + s.search_one('key').arg + ']' descr = s.search_one('description') if descr is not None: descrstring = ''.join([x for x in descr.arg if ord(x) < 128]) else: descrstring = "" levelcnt[level] += 1 idstring = str(levelcnt[1]) for i in range(2, level + 1): idstring += '-' + str(levelcnt[i]) pathstr = statements.mk_path_str(s, True) if folder: # hypertext link to non-existing YANG HTML.... #fd.write("<tr id=\"%s\" class=\"a\"> <td id=\"p4000\"><div id=\"p5000\" class=\"tier%s\"><a id=\"p6000\" href=\"#\" onclick=\"toggleRows(this)\" class=\"folder\"></a><a title=\"%s\" target=\"src\" href=\"yang-module.shtml#%s\">%s</a></div></td> \n" %(idstring, level, descrstring, s.arg, name)) fd.write( "<tr id=\"%s\" class=\"a\"> <td id=\"p4000\"><div id=\"p5000\" class=\"tier%s\"><a id=\"p6000\" href=\"#\" onclick=\"toggleRows(this)\" class=\"folder\"></a>%s</div></td> \n" % (idstring, level, name)) fd.write( '<td title="I am a title">%s</td> <td>%s</td> <td>%s</td> <td>%s</td> <td>%s</td> <td>%s</td> </tr> \n' % (s.keyword, nodetype, flags, options, status, pathstr)) else: if s.keyword == ('tailf-common', 'action'): classstring = "action" typeinfo = action_params(s) typename = "parameters" else: classstring = s.keyword typeinfo = typestring(s) typename = nodetype # hypertext link to non-existing YANG HTML.... #fd.write('<tr id=\"%s\" class=\"a\"><td><div id=9999 class=tier%s> <a href =\"#\" class=\"%s\"></a><a title=\"%s\" target=\"src\" href=\"yang-module.shtml#%s\">%s</a></div> </td> <td>%s</td> <td><abbr title=\"%s\">%s</abbr></td> <td>%s</td> <td>%s</td> <td>%s</td><td>%s</td</tr> \n' %(idstring, level,classstring, descrstring, s.keyword, name,s.keyword, typeinfo, typename, flags, options, status, pathstr)) fd.write( '<tr id=\"%s\" class=\"a\"><td><div id=9999 class=tier%s> <a href =\"#\" class=\"%s\"></a>%s</div> </td> <td>%s</td> <td><abbr title=\"%s\">%s</abbr></td> <td>%s</td> <td>%s</td> <td>%s</td><td>%s</td</tr> \n' % (idstring, level, classstring, name, s.keyword, typeinfo, typename, flags, options, status, pathstr)) if hasattr(s, 'i_children'): level += 1 if s.keyword in ['choice', 'case']: print_children(s.i_children, module, fd, prefix, level) else: print_children(s.i_children, module, fd, prefix, level)
def generate_visitor(self, stmt, module=False): def pkg(class_name): return self.java_class_visitor.package \ + (('.' + util.camelize(self.n2)) if not module else '') \ + '.' + class_name def if_none_then_null(val): return ('"' + val + '"') if val is not None else 'null' method_visit = JavaMethod(return_type='void', name='visit') method_visit.add_javadoc('Auto-generated module traverse algorithm') method_visit.add_parameter('io.netconfessor.NodeSet', 'nodes') method_visit.add_modifier('public') method_visit.add_dependency('io.netconfessor.Element') this_config = util.is_config(stmt) stmt_id = util.camelize(stmt.arg) stmt_class = util.normalize(stmt.arg) method_collect = None # module visitor collects into NodeSet, children into corresponding java object if module: method_collect = JavaMethod(return_type='io.netconfessor.NodeSet', name='collectConfig') method_collect.add_modifier('public') method_collect.add_line('NodeSet nodes = new NodeSet();') elif this_config: method_collect = JavaMethod(return_type=self.package + '.' + self.n, name='collectConfig') if stmt.keyword in {'list', 'leaf-list'}: method_collect.add_parameter(param_type=pkg(stmt_class), param_name=stmt_id) # method_collect.add_line('%s %s = getNext%s();' % (stmt_class, stmt_id, stmt_class)) method_collect.add_line('if (%s == null) {' % stmt_id) method_collect.add_line(' return null;') method_collect.add_line('}') else: method_collect.add_line('%s %s = new %s();' % (stmt_class, stmt_id, stmt_class)) method_collect.add_modifier('public') method_setup_all = JavaMethod(return_type='void', name='setup') method_setup_all.add_modifier('public') for s in util.search(stmt, context.yangelement_stmts): config = util.is_config(s) xpath = statements.mk_path_str(s, True) keyword = s.keyword id = util.camelize(s.arg) visitee_name = util.normalize(s.arg) visitee = util.escape_conflicts(pkg(visitee_name)) visitor_id = util.visitor_class(id) visitee_full = pkg(visitee_name) if keyword in {'container'}: method_name = 'on' + visitee_name next_visitor = util.visitor_class(visitee_name) visit_method = JavaMethod( return_type='void', # pkg(next_visitor), name=method_name) visit_method.add_parameter(visitee_full, keyword) visit_method.add_modifier('public') visit_method.add_modifier('abstract') self.java_class_visitor.add_method(visit_method) field_visitor = JavaValue() field_visitor.add_modifier('private') field_visitor.add_modifier(next_visitor) field_visitor.set_name(util.visitor_class(id)) self.java_class_visitor.add_field(field_visitor) if config: method_collect.add_line('if (%s != null) {' % visitor_id) method_collect.add_line(' %s %s = %s.collectConfig();' % (visitee, id, visitor_id)) method_collect.add_line(' if (%s != null) {' % id) if module: method_collect.add_line(' nodes.add(%s);' % id) else: method_collect.add_line(' %s.add%s(%s);' % (stmt_id, visitee_name, id)) method_collect.add_line(' }') method_collect.add_line('}') method_visit.add_line('') method_visit.add_line('final Element %s = nodes.getFirstChild("%s");' % (id, s.arg)) method_visit.add_line('if (%s != null) {' % id) method_visit.add_line(' %s((%s)%s);' % (method_name, visitee, id)) method_visit.add_line(' if (%s != null) {' % visitor_id) method_visit.add_line(' if (%s.hasChildren()) {' % id) method_visit.add_line(' %s.visit(%s.getChildren());' % (visitor_id, id)) method_visit.add_line(' }') method_visit.add_line(' }') method_visit.add_line('}') method_visit.add_dependency(pkg(next_visitor)) method_setup = JavaMethod(return_type=pkg(next_visitor), name='setup' + visitee_name) method_setup.add_modifier('public') method_setup.add_modifier('abstract') method_setup.add_parameter(param_type='io.netconfessor.YangData', param_name='data') desc_stmt = util.search_one(s, 'description') desc = if_none_then_null(desc_stmt.arg if desc_stmt is not None else None) method_setup_all.add_line('%s = setup%s(new YangData("%s", "%s", %s, %s, YangDataType.%s));' % (visitor_id, visitee_name, s.arg, xpath, util.yang_string_to_jstring(desc), 'true' if config else 'false', util.camelize(s.keyword))) method_setup_all.add_line('if (%s != null) {' % visitor_id) method_setup_all.add_line(' %s.setup();' % visitor_id) method_setup_all.add_line('}') method_setup_all.add_dependency('io.netconfessor.YangData') method_setup_all.add_dependency('io.netconfessor.YangDataType') self.java_class_visitor.add_field(method_setup) elif keyword in {'list'}: next_method_name = 'onNext' + visitee_name entry_visitor = util.visitor_class(visitee_name) visit_method = JavaMethod(return_type='void', # pkg(entry_visitor), name=next_method_name) visit_method.add_modifier('public') visit_method.add_modifier('abstract') visit_method.add_parameter(visitee_full, 'item') self.java_class_visitor.add_method(visit_method) start_method_name = 'onStart' + visitee + 'List' visit_method = JavaMethod(return_type='void', name=start_method_name) visit_method.add_modifier('protected') self.java_class_visitor.add_method(visit_method) stop_method_name = 'onStop' + visitee + 'List' visit_method = JavaMethod(return_type='void', name=stop_method_name) visit_method.add_modifier('protected') self.java_class_visitor.add_method(visit_method) if config: collect_get_next_name = 'getNext' + visitee_name method_collect.add_line('%s %s;' % (util.escape_conflicts(visitee, visitee_name), id)) method_collect.add_line('while((%s = %s()) != null) {' % (id, collect_get_next_name)) if module: method_collect.add_line(' nodes.add(%s);' % id) else: method_collect.add_line(' %s.removeNonKeysIfMarkedToDelete();' % id) method_collect.add_line(' %s.add%s(%s);' % (stmt_id, visitee_name, id)) method_collect.add_line('}') collect_get_next = JavaMethod(return_type=visitee_full, name=collect_get_next_name) collect_get_next.add_modifier('abstract') collect_get_next.add_modifier('protected') self.java_class_visitor.add_method(collect_get_next) method_visit.add_line('') method_visit.add_line('%s();' % start_method_name) method_visit.add_line('for (Element node : nodes.getChildren("%s")) {' % (s.arg)) method_visit.add_line(' %s((%s)node);' % (next_method_name, visitee)) method_visit.add_line(' if (%s != null) {' % visitor_id) method_visit.add_line(' if (node.hasChildren()) {') method_visit.add_line(' %s.visit(node.getChildren());' % visitor_id) method_visit.add_line(' }') method_visit.add_line(' }') method_visit.add_line('}') method_visit.add_line('%s();' % stop_method_name) method_setup = JavaMethod(return_type=pkg(entry_visitor), name='setup' + visitee_name) method_setup.add_modifier('public') method_setup.add_modifier('abstract') method_setup.add_parameter(param_type='io.netconfessor.YangData', param_name='data') self.java_class_visitor.add_field(method_setup) desc_stmt = util.search_one(s, 'description') desc = if_none_then_null(desc_stmt.arg if desc_stmt is not None else None) method_setup_all.add_line('%s = setup%s(new YangData("%s", "%s", %s, %s, YangDataType.%s));' % (visitor_id, visitee_name, s.arg, xpath, util.yang_string_to_jstring(desc), 'true' if config else 'false', util.camelize(s.keyword))) method_setup_all.add_line('if (%s != null) {' % visitor_id) method_setup_all.add_line(' %s.setup();' % visitor_id) method_setup_all.add_line('}') method_setup_all.add_dependency('io.netconfessor.YangData') method_setup_all.add_dependency('io.netconfessor.YangDataType') field_visitor = JavaValue() field_visitor.add_modifier('private') field_visitor.add_modifier(entry_visitor) field_visitor.set_name(util.visitor_class(id)) self.java_class_visitor.add_field(field_visitor) elif keyword in {'leaf'}: method_name = 'on' + visitee visit_method = JavaMethod(return_type='void', name=method_name) visit_method.add_modifier('public') visit_method.add_modifier('abstract') visit_method.add_parameter(visitee_full, keyword) self.java_class_visitor.add_method(visit_method) jnc, primitive = util.get_types(s, self.ctx) type_reference = util.escape_conflicts(visitee, visitee_name) base_type = util.get_base_type(s) is_enum = base_type.arg == 'enumeration' type_class = util.escape_conflicts(jnc, visitee_name) if config: get_method = JavaMethod(name='get' + visitee) get_method.set_return_type(visitee, visitee_name) get_method.add_modifier('public') get_method.add_modifier('abstract') self.java_class_visitor.add_method(get_method) method_collect.add_line('%s %s = get%s();' % (visitee_name, id, visitee_name)) method_collect.add_line('if (%s != null) {' % id) method_collect.add_line(' %s.add%s(%s);' % (stmt_id, visitee_name, id)) method_collect.add_line('}') method_visit.add_line('') method_visit.add_line('final Element %s = nodes.getFirstChild("%s");' % (id, s.arg)) method_visit.add_line('if (%s != null) {' % id) method_visit.add_line(' %s((%s)%s);' % (method_name, type_reference, id)) method_visit.add_line('}') method_setup = JavaMethod(return_type='void', name='setup' + visitee_name) method_setup.add_modifier('public') method_setup.add_modifier('abstract') yang_data_type = 'io.netconfessor.EnumYangData' if is_enum else 'io.netconfessor.LeafYangData' method_setup.add_parameter_generic(param_type=yang_data_type, generic_type=jnc, param_name='data', this_class_name=visitee_full) desc_stmt = util.search_one(s, 'description') desc = if_none_then_null(desc_stmt.arg if desc_stmt is not None else None) if is_enum: method_setup_all.add_line('setup%s(new EnumYangData<>(' '"%s", "%s", %s, %s, YangDataType.%s, "%s", s -> new %s(s), %s.enums()));' % (visitee_name, s.arg, xpath, util.yang_string_to_jstring(desc), 'true' if config else 'false', util.camelize(s.keyword), jnc, type_class, type_class)) else: method_setup_all.add_line('setup%s(new LeafYangData<>(' '"%s", "%s", %s, %s, YangDataType.%s, "%s", s -> new %s(s)));' % (visitee_name, s.arg, xpath, util.yang_string_to_jstring(desc), 'true' if config else 'false', util.camelize(s.keyword), jnc, type_class)) method_setup_all.add_dependency(jnc) method_setup_all.add_dependency(yang_data_type) method_setup_all.add_dependency('io.netconfessor.YangDataType') self.java_class_visitor.add_field(method_setup) if module: method_collect.add_javadoc('Retrieve all config values in registered visitors') method_collect.add_javadoc('Before send to device you need sync result with older nodeset (empty allowed)') method_collect.add_line('return nodes;') elif this_config: method_collect.add_javadoc('Retrieve all config values in registered visitors') method_collect.add_line('if (%s.hasChildren()) {' % stmt_id) method_collect.add_line(' return %s;' % stmt_id) method_collect.add_line('} else {') method_collect.add_line(' return null;') method_collect.add_line('}') self.java_class_visitor.add_method(method_setup_all) self.java_class_visitor.add_method(method_collect) self.java_class_visitor.add_method(method_visit)
def walk_child(child): global XpathToBodyTagDict customName = None actXpath = statements.mk_path_str(child, True) metadata = [] keyNodesInPath = [] paramsList = [] pathstr = mk_path_refine(child, metadata, keyNodesInPath, False, paramsList) if actXpath in keysToLeafRefObjSet: return if child.keyword == "rpc": add_swagger_tag(child.i_module) handle_rpc(child, actXpath, pathstr) return if child.keyword in ["list", "container", "leaf", "leaf-list"]: payload = OrderedDict() jsonPayload = OrderedDict() add_swagger_tag(child.i_module) build_payload(child, payload, pathstr, True, actXpath, True, False, [], jsonPayload) if len(payload) == 0 and child.i_config == True: return if child.keyword == "leaf" or child.keyword == "leaf-list": if hasattr(child, 'i_is_key'): if child.i_leafref is not None: listKeyPath = statements.mk_path_str( child.i_leafref_ptr[0], True) if listKeyPath not in keysToLeafRefObjSet: keysToLeafRefObjSet.add(listKeyPath) return customName = getOpId(child) defName = shortenNodeName(child, customName) if child.i_config == False: payload_get = OrderedDict() json_payload_get = OrderedDict() build_payload(child, payload_get, pathstr, True, actXpath, True, True, [], json_payload_get) if len(payload_get) == 0: return defName_get = "get" + '_' + defName swaggerDict["definitions"][defName_get] = OrderedDict() swaggerDict["definitions"][defName_get]["type"] = "object" swaggerDict["definitions"][defName_get][ "properties"] = copy.deepcopy(payload_get) swagger_it(child, defName_get, pathstr, payload_get, metadata, "get", defName_get, paramsList, json_payload_get) else: swaggerDict["definitions"][defName] = OrderedDict() swaggerDict["definitions"][defName]["type"] = "object" swaggerDict["definitions"][defName]["properties"] = copy.deepcopy( payload) for verb in verbs: if child.keyword == "leaf-list": metadata_leaf_list = [] keyNodesInPath_leaf_list = [] paramsLeafList = [] pathstr_leaf_list = mk_path_refine( child, metadata_leaf_list, keyNodesInPath_leaf_list, True, paramsLeafList) if verb == "get": payload_get = OrderedDict() json_payload_get = OrderedDict() build_payload(child, payload_get, pathstr, True, actXpath, True, True, [], json_payload_get) if len(payload_get) == 0: continue defName_get = "get" + '_' + defName swaggerDict["definitions"][defName_get] = OrderedDict() swaggerDict["definitions"][defName_get]["type"] = "object" swaggerDict["definitions"][defName_get][ "properties"] = copy.deepcopy(payload_get) swagger_it(child, defName_get, pathstr, payload_get, metadata, verb, defName_get, paramsList, json_payload_get) if child.keyword == "leaf-list": defName_get_leaf_list = "get" + '_llist_' + defName swagger_it(child, defName_get, pathstr_leaf_list, payload_get, metadata_leaf_list, verb, defName_get_leaf_list, paramsLeafList, json_payload_get) continue if verb == "post" and child.keyword == "list": continue if verb == "delete" and child.keyword == "container": # Check to see if any of the child is part of # key list, if so skip delete operation if isUriKeyInPayload(child, keyNodesInPath): continue swagger_it(child, defName, pathstr, payload, metadata, verb, False, paramsList, jsonPayload) if verb == "delete" and child.keyword == "leaf-list": defName_del_leaf_list = "del" + '_llist_' + defName swagger_it(child, defName, pathstr_leaf_list, payload, metadata_leaf_list, verb, defName_del_leaf_list, paramsLeafList, jsonPayload) if child.keyword == "list": listMetaData = copy.deepcopy(metadata) listparamsList = copy.deepcopy(paramsList) walk_child_for_list_base(child, actXpath, pathstr, listMetaData, defName, listparamsList) if hasattr(child, 'i_children'): for ch in child.i_children: walk_child(ch)
def collect_child_doc(node, parent, top): """Collect documentation fields for a statement. node is a PYANG statement object, while parent is a ModuleDoc or StatementDoc object. top is the top level ModuleDoc object""" statement = StatementDoc(node.arg, node.keyword) statement.parent = parent statement.module_doc = top parent.children.append(statement) # fill in some attributes if they exist # type information type = node.search_one('type') if type is not None: # create the Type object statement.typedoc = TypeStatementDoc() collect_type_docs(type, statement.typedoc) # node description desc = node.search_one('description') if desc is not None: statement.attrs['desc'] = desc.arg # reference statement reference = node.search_one('reference') if reference is not None: statement.attrs['reference'] = reference.arg # default statement default = node.search_one('default') if default is not None: statement.attrs['default'] = default.arg # units statement units = node.search_one('units') if units is not None: statement.attrs['units'] = units.arg # schema path for the current node path = statements.mk_path_str(node, True) statement.attrs['path'] = path # id based on schema path node_id = node_to_id(statement) statement.attrs['id'] = node_id # rw or ro info if hasattr(node, 'i_config'): statement.attrs['config'] = node.i_config # for list nodes, record the keys if statement.keyword == 'list': statement.attrs['is_list'] = True keys = [] for key in node.i_key: keypath = statements.mk_path_str(key, True) keys.append((key.arg, path_to_id(keypath))) statement.attrs['keys'] = keys else: statement.attrs['is_list'] = False # note nodes that are list keys if hasattr(node, 'i_is_key'): statement.attrs['is_key'] = node.i_is_key else: statement.attrs['is_key'] = False # collect data from children, i.e., depth-first if hasattr(node, 'i_children'): for child in node.i_children: collect_child_doc(child, statement, top)
def print_node(s, module, fd, prefix, path, ctx, level=0, exdata=None): global levelcnt status = get_status_str(s) nodetype = '' options = '' folder = False ignored_node = False if s.i_module.i_modulename == module.i_modulename: name = s.arg else: name = s.i_module.i_prefix + ':' + s.arg pr = module.search_one('prefix') if pr is not None: prstr = pr.arg else: prstr = "" descr = s.search_one('description') descrstring = "No description" if descr is not None: descrstring = descr.arg flags = get_flags_str(s) if s.keyword == 'list': folder = True elif s.keyword == 'container': folder = True p = s.search_one('presence') if p is not None: pr_str = p.arg options = "!" elif s.keyword == 'choice': folder = True m = s.search_one('mandatory') if m is None or m.arg == 'false': name = '(' + s.arg + ')' options = 'Choice' else: name = '(' + s.arg + ')' # ignored_node = True elif s.keyword == 'case': folder = True # fd.write(':(' + s.arg + ')') name = ':(' + s.arg + ')' # ignored_node = True elif s.keyword == 'input': folder = True elif s.keyword == 'output': folder = True elif s.keyword == 'rpc': folder = True elif s.keyword == 'notification': folder = True else: if s.keyword == 'leaf-list': options = '*' elif s.keyword == 'leaf' and not hasattr(s, 'i_is_key'): m = s.search_one('mandatory') if m is None or m.arg == 'false': options = '?' nodetype = get_typename(s) if s.keyword == 'list' and s.search_one('key') is not None: name += '[' + s.search_one('key').arg + ']' descr = s.search_one('description') if descr is not None: descrstring = ''.join([x for x in descr.arg if ord(x) < 128]) else: descrstring = "" levelcnt[level] += 1 idstring = str(levelcnt[1]) for i in range(2, level + 1): idstring += '-' + str(levelcnt[i]) pathstr = "" if not ctx.opts.excel_no_path: pathstr = statements.mk_path_str(s, True) keyword = s.keyword if not ignored_node: # print level if folder: # print ("print_node1: ", idstring, level, descrstring, name) # print ("print_node2: ", s.keyword, nodetype, flags, options, status, pathstr) # print (str(name), str(s.keyword), str(nodetype), str(flags), str(pathstr), str(status), str(descrstring)) if exdata: data = [{ "skip": level, "value": str(name), "tooltip": str(descrstring) }, str(s.keyword), "-", str(flags), str(options), str(pathstr)] exdata.append(data) else: if s.keyword in ['action', ('tailf-common', 'action')]: classstring = "action" typeinfo = action_params(s) typename = "parameters" keyword = "action" elif s.keyword == 'rpc' or s.keyword == 'notification': classstring = "folder" typeinfo = action_params(s) typename = "parameters" else: classstring = s.keyword typeinfo = typestring(s) typename = nodetype # print (str(name), str(classstring), str(typeinfo), str(flags), str(pathstr), str(status), str(descrstring)) # print ("print_node3: ", idstring, level, classstring, descrstring, name, keyword, typeinfo, typename, flags, options, status, pathstr) if exdata: # typ = str(typeinfo).splitlines() # typ_tooltip = ' '.join(typ[1:]) # typ = typ[0] typ = typename typ_tooltip = str(typeinfo) data = [{ "skip": level, "value": str(name), "tooltip": str(descrstring) }, str(classstring), { "value": typ, "tooltip": typ_tooltip }, str(flags), str(options), str(pathstr)] exdata.append(data) if hasattr(s, 'i_children'): level += 1 chs = s.i_children if path is not None and len(path) > 0: chs = [ch for ch in chs if ch.arg == path[0]] path = path[1:] if s.keyword in ['choice', 'case']: print_children(chs, module, fd, prefix, path, ctx, level, exdata=exdata) else: print_children(chs, module, fd, prefix, path, ctx, level, exdata=exdata)
def check_opstate(ctx, stmt): """Check operational state validation rules. Args: ctx: pyang.Context for validation stmt: pyang.Statement for a leaf or leaf-list """ pathstr = statements.mk_path_str(stmt) # leaves that are list keys are exempt from this check. YANG # requires them at the top level of the list, i.e., not allowed # in a descendent container is_key = False if stmt.parent.keyword == "list" and stmt.keyword == "leaf": key_stmt = stmt.parent.search_one("key") if key_stmt is not None: if " " in key_stmt.arg: key_parts = [unicode(i) for i in key_stmt.arg.split(" ")] else: key_parts = [unicode(key_stmt.arg)] if stmt.arg in key_parts: is_key = True if is_key: keytype = stmt.search_one("type") if keytype.arg != "leafref": err_add(ctx.errors, stmt.pos, "OC_OPSTATE_KEY_LEAFREF", stmt.arg) return path_elements = yangpath.split_paths(pathstr) # count number of 'config' and 'state' elements in the path confignum = path_elements.count("config") statenum = path_elements.count("state") if confignum != 1 and statenum != 1: err_add(ctx.errors, stmt.pos, "OC_OPSTATE_CONTAINER_COUNT", (pathstr)) # for elements in a config or state container, make sure they have the # correct config property if stmt.parent.keyword == "container": if stmt.parent.arg == "config": if stmt.i_config is False: err_add(ctx.errors, stmt.pos, "OC_OPSTATE_CONFIG_PROPERTY", (stmt.arg, "config", "true")) elif stmt.parent.arg == "state": if stmt.i_config is True: err_add(ctx.errors, stmt.parent.pos, "OC_OPSTATE_CONFIG_PROPERTY", (stmt.arg, "state", "false")) else: valid_enclosing_state = False if stmt.i_config is False: # Allow nested containers within a state container path_elements = yangpath.split_paths(pathstr) if u"state" in path_elements: valid_enclosing_state = True if valid_enclosing_state is False: err_add(ctx.errors, stmt.pos, "OC_OPSTATE_CONTAINER_NAME", (stmt.arg, pathstr))