def get_remote_port_by_local(self, object, port): """ Try to guess remote port from free-form description :param object: :param port: :return: """ self.debug("Remote port local: %s" % port) # Try ifindex if is_int(port): i = Interface.objects.filter( managed_object=object.id, ifindex=int(port)).first() if i: return i.name # Try interface name try: n_port = object.profile.convert_interface_name(port) i = Interface.objects.filter( managed_object=object.id, name=n_port).first() if i: return n_port for p in object.profile.get_interface_names(n_port): i = Interface.objects.filter( managed_object=object.id, name=p).first() if i: return p except InterfaceTypeError: pass # Unable to decode self.info("Unable to decode local subtype port id %s at %s" % ( port, object)) return port
def convert_link(cls, kb_entry, link, text=None): if text is None: text = link if link.startswith("KB") and is_int(link[2:]): return u"<a href='/kb/view/%s/'>%s</a>" % (link[2:], text) elif link.startswith("TT"): tt = {"tt": link[2:]} tt_url = config.get("tt", "url", tt) % tt return u"<a href='%s'>%s</a>" % (tt_url, text) elif link.startswith("attach:"): if text == link: text = link[7:] link = link[7:] return u"<a href='/kb/view/%d/attachment/%s/'>%s</a>" % ( kb_entry.id, link, text) elif link.startswith("attachment:"): if text == link: text = link[11:] link = link[11:] return u"<a href='/kb/%d/attachment/%s/'>%s</a>" % (kb_entry.id, link, text) else: try: le = kb_entry.__class__.objects.get(subject=link) return u"<a href='/kb/view/%s/'>%s</a>" % (le.id, text) except kb_entry.__class__.DoesNotExist: return u"<a href='%s'>%s</a>" % (link, text)
def is_static(svc): if ":" not in svc: return False p = svc.split(":") if len(p) != 2: return False return is_ipv4(p[0]) and is_int(p[1])
def get_psu(self): r = defaultdict(list) k_map = {"state": "state", "partinfo": "partinfo"} try: v = self.cli("show power detail") except self.CLISyntaxError: return {} slot = 1 number = None for block in self.rx_power_split.split(v): if is_int(block): if int(block.strip()) < number: slot += 1 number = int(block.strip()) continue d = parse_kv(k_map, block) if d.get("state") in ["Empty", "Powered Off", None ] or "partinfo" not in d: continue partinfo = d["partinfo"].split() r[slot] += [{ "type": "PSU", "number": number, "description": "".join(partinfo[:-2]), "vendor": "EXTREME", "part_no": partinfo[-1], "serial": partinfo[-2], }] return r
def execute(self): r = [] for v in parse_table(self.cli("show vlan", cached=True), max_width=80): if not is_int(v[0]): continue r += [{"vlan_id": v[0], "name": v[1]}] return r
def get_interface_by_local(self, port, object): """ Try to guess remote port from free-form description :param object: :param port: :return: """ self.logger.debug("Searching port by local: %s:%s", object.name, port) # Try ifindex if is_int(port): i = self.get_interface_by_ifindex(port, object) if i: return i # Try interface name try: n_port = object.get_profile().convert_interface_name(port) i = Interface.objects.filter(managed_object=object.id, name=n_port).first() if i: return i for p in object.get_profile().get_interface_names(n_port): i = Interface.objects.filter(managed_object=object.id, name=p).first() if i: return i except InterfaceTypeError: pass # Unable to decode self.logger.info("Unable to decode local subtype port id %s at %s", port, object) return None
def get_Q(self, request, query): """ Prepare Q statement for query """ def get_q(f): if f == "uuid": if is_uuid(query): return f else: return None if "__" not in f: return "%s__%s" % (f, self.query_condition) else: return f qfx = [get_q(f) for f in self.query_fields] qfx = [x for x in qfx if x] q = reduce(lambda x, y: x | Q(**{get_q(y): query}), qfx[1:], Q(**{qfx[0]: query})) if self.int_query_fields and is_int(query): v = int(query) for f in self.int_query_fields: q |= Q(**{f: v}) return q
def convert_interface_name(self, s): """ >>> Profile().convert_interface_name("19") 'vlan 19' """ if is_int(s): return "vlan %s" % s return s
def get_interface_names(self, name): r = [] if name.startswith("1:"): r += [name[2:]] else: if is_int(name): r += ["1:%s" % name] return r
def parse_bind_zone(self, data): """ Parse bind-style zone and return records applicable to ZoneFile (fqdn, type, content, ttl, prio) """ # Wipe out comments data = data.replace("\t", " ") data = self.strip_oneline_comments(data, ";") data = self.merge_enclosed(data) ttl = None zone = None rr = [] for l in data.splitlines(): if l.startswith("$TTL "): ttl = int(l[5:].strip()) continue if l.startswith("$ORIGIN "): zone = l[8:].strip() continue if not rr: # Wait for SOA match = self.rx_soa.match(l) if match: z = match.group("zone") if z and z != "@": zone = z rr += [["", "SOA", " ".join(match.groups()[-7:]), None, None]] else: parts = l.split() if parts[0] == "IN" or parts[0] in self.RR_TYPES: # missed name parts = [""] + parts if parts[1] == "IN": # Remove IN parts = [parts[0]] + parts[2:] # Normalize name name = parts[0] if name == "@" or not name: name = zone elif not name.endswith("."): name = name + "." + zone # Process value t = parts[1] v = parts[2:] rttl = None if len(v) > 1 and is_int(v[0]): rprio = int(v[0]) v = v[1:] else: rprio = None value = " ".join(v) if t in ("CNAME", "PTR"): value = self.from_idna(value) rr += [[self.from_idna(name), t, value, rttl, rprio]] if zone.endswith("."): zone = zone[:-1] return self.from_idna(zone), rr
def execute(self): interfaces = [] lldp = self.get_lldp() ctp = self.get_ctp() for i in parse_table(self.cli("show interface switchport")): iface = { "name": i[0], "type": "physical", "enabled_protocols": [], "subinterfaces": [{ "name": i[0], "enabled_afi": ["BRIDGE"], "untagged_vlan": i[1] }] } if i[0] in lldp: iface["enabled_protocols"] += ["LLDP"] if i[0] in ctp: iface["enabled_protocols"] += ["CTP"] interfaces += [iface] for v in parse_table(self.cli("show vlan"), max_width=80): if not is_int(v[0]): continue vlan_id = v[0] ports = self.expand_rangelist(v[2]) for i in interfaces: if i["subinterfaces"][0]["untagged_vlan"] == vlan_id: continue if (int(i["name"]) in ports): if "tagged_vlans" in i["subinterfaces"][0]: i["subinterfaces"][0]["tagged_vlans"] += [vlan_id] else: i["subinterfaces"][0]["tagged_vlans"] = [vlan_id] mac = self.scripts.get_chassis_id()[0]["first_chassis_mac"] match = self.rx_ipif.search(self.cli("show ip interface")) ip = match.group("ip") mask = match.group("mask") ip_address = "%s/%s" % (ip, IPv4.netmask_to_len(mask)) iface = { "name": "mgmt", "type": "SVI", "mac": mac, "subinterfaces": [{ "name": "mgmt", "enabled_afi": ["BRIDGE"], "vlan_ids": match.group("vlan_id"), "ipv4_addresses": [ip_address], "enabled_afi": ["IPv4"], "mac": mac }] } interfaces += [iface] return [{"interfaces": interfaces}]
def has_bfd_snmp(self): """ Check box has bfd enabled """ # bfdAdminStatus bfd = self.snmp.get("1.3.6.1.4.1.2636.5.3.1.1.1.1.0") if is_int(bfd) and int(bfd) == 1: # enabled(1) return True return False
def execute_platform_snmp(self, caps): np = 0 # jnxRpmResSumSent for v, r in self.snmp.getnext("1.3.6.1.4.1.2636.3.50.1.2.1.2", bulk=False): tests = v.split(".") if tests[-1] == "1": # currentTest(1) np += 1 if np > 0: caps["Juniper | RPM | Probes"] = np # jnxPPPoEMajorInterfaceCount pppoe = self.snmp.get("1.3.6.1.4.1.2636.3.67.1.1.3.1.0") if is_int(pppoe) and int(pppoe) > 0: caps["BRAS | PPPoE"] = True # jnxL2tpStatsTotalTunnels l2tp = self.snmp.get("1.3.6.1.4.1.2636.3.49.1.1.1.1.1.0") if is_int(l2tp) and int(l2tp) > 0: caps["BRAS | L2TP"] = True
def get_type(self, name): name = name.upper() n = name.split() if is_int(n[-1]): number = n[-1] name = " ".join(n[:-1]) else: number = None return self.TYPE_MAP.get(name), number
def parse_create_vlan(self, tokens): """ create vlan 306 tag 306 create vlan tag tag 306 """ tag = self.next_item(tokens, "tag") if tag and is_int(tag): name = self.next_item(tokens, "vlan") vid = int(tag) self.get_vlan_fact(vid).name = name self.vlan_ids[tag] = vid self.vlan_ids[name] = vid else: if len(tokens) == 5 and tokens[3] == "tag" and is_int(tokens[4]): name = self.next_item(tokens, "vlan") vid = int(tokens[4]) self.get_vlan_fact(vid).name = name self.vlan_ids[tag] = vid self.vlan_ids[name] = vid
def _get(model, fields, o_id): for f in fields: try: return model.objects.get(**{f: o_id}) except model.DoesNotExist: pass if is_int(id): try: return model.objects.get(id=id) except model.DoesNotExist: pass return None
def table_search_Q(cls, table, query): q = [] for f in CustomField.objects.filter(is_active=True, table=table, is_searchable=True): if f.type == "str": q += [{"%s__icontains" % f.name: query}] elif f.type == "int": if is_int(query): q += [{f.name: int(query)}] if q: return reduce(lambda x, y: x | models.Q(**y), q, models.Q(**q[0])) else: return None
def is_ignored_interface(self, i): if i.lower() in self.ignored_interfaces: return True if i.startswith("flood to vlan"): return True if i.startswith("VPLS"): return True if i.startswith("seq_no:"): return True if is_int(i): # 10.27.0.80, 1204773146 return True return False
def convert_interface_name(self, s): """ >>> Profile().convert_interface_name_cisco("gi1/0/1") 'Gi 1/0/1' >>> Profile().convert_interface_name_cisco("gi1/0/1?") 'Gi 1/0/1' """ match = self.rx_eltex_interface_name.match(s) if is_int(s): return "Vl %s" % s elif match: return "%s %s" % (match.group("type").capitalize(), match.group("number")) else: raise InterfaceTypeError("Invalid interface '%s'" % s)
def execute_cli(self, interface=None): # @todo without stack slot (Members | Ids) # show ports transceiver information r = [] if interface is not None: ifaces = [interface.split(":")] elif self.has_capability("Stack | Member Ids"): ifaces = [(s_id, None) for s_id in self.capabilities["Stack | Member Ids"].split(" | ")] else: ifaces = [(None, None)] for slot, port in ifaces: cmd = "debug hal show optic-info ddmi " if port is not None: cmd += "slot %s, port %s" % (slot, port) elif slot is not None: cmd += "slot %s" % slot try: v = self.cli(cmd) except self.CLISyntaxError: return [] for block in self.rx_trans_split.split(v): if is_int(block): port = block.strip() continue if self.rx_no_trans.match(block) or not port: continue d = parse_kv(self.k_map, block) if slot is not None: port = "%s:%s" % (slot, port) if not d: continue r += [{ "interface": port, "temp_c": self.normalize_output(d.get("temp_c")), "voltage_v": self.normalize_output(d.get("voltage_v")), "current_ma": self.normalize_output(d.get("current_ma")), "optical_rx_dbm": self.normalize_output(d.get("optical_rx_dbm")), "optical_tx_dbm": self.normalize_output(d.get("optical_tx_dbm")) }] return r
def get_object(self, object_name): """ Resolve object by name or by id """ from noc.sa.models.managedobject import ManagedObject from django.db.models import Q if object_name.endswith(".json") and os.path.isfile(object_name): return JSONObject(object_name) q = Q(name=object_name) if is_int(object_name): q = Q(id=int(object_name)) | q try: return ManagedObject.objects.get(q) except ManagedObject.DoesNotExist: self.die("Object is not found: %s" % object_name)
def resolve_addresses(self, addr_list, default_port): """ Parses string and returns a list of (ip,port) :param addr_list: Comma-separared list of addresses in form: * ip * ip:port * interface * interface:port :param default_port: :return: """ r = [] for x in addr_list.split(","): x = x.strip() if not x: continue if ":" in x: # Implicit port notation x, port = x.split(":", 1) if is_int(port): port = int(port) else: import socket try: port = socket.getservbyname(port) except socket.error: raise Exception("Invalid port: %s" % port) else: port = int(default_port) if port <= 0 or port > 65535: raise Exception("Invalid port: %s" % port) if is_ipv4(x): r += [(x, port)] continue if USE_NETIFACES: # Can resolve interface names try: a = netifaces.ifaddresses(x) except ValueError: raise Exception("Invalid interface '%s'" % x) try: x = a[2][0]["addr"] except (IndexError, KeyError): raise Exception("No ip address for interface: '%s' found" % x) r += [(x, port)] continue raise Exception("Cannot resolve address '%s'" % x) return r
def get_Q(self, request, query): """ Prepare Q statement for query """ def get_q(f): if "__" not in f: return "%s__%s" % (f, self.query_condition) else: return f q = reduce(lambda x, y: x | Q(**{get_q(y): query}), self.query_fields[1:], Q(**{get_q(self.query_fields[0]): query})) if self.int_query_fields and is_int(query): v = int(query) for f in self.int_query_fields: q |= Q(**{f: v}) return q
def execute(self, interface=None, vlan=None, mac=None): cmd = self.cli("show mac-address-table") # if mac is not None: # cmd += " address %s" % mac if interface is not None: cmd += " port %s" % interface if vlan is not None: cmd += " vlan %s" % vlan r = [] t = parse_table(cmd, footer="^show mac-address-table") for i in t: if is_int(i[0]): r += [{ "vlan_id": i[0], "mac": i[1], "interfaces": [self.profile.convert_interface_name(i[4])], "type": "D" if i[2] == "learned" else "S", }] return r
def __iter__(self): g = super(RouterOSTokenizer, self).__iter__() context = None context_fed = False n_item = 0 for tokens in g: if tokens[0].startswith("/"): # New context if context and not context_fed: yield context context = tokens context_fed = False n_item = 0 continue if tokens[0] == "set" and len(tokens) > 1: # Process set instruction if (tokens[1] == "[" and len(tokens) > 4 and tokens[2] == "find" and tokens[4] == "]"): # set [ find key=value ] ... item = tokens[3].split("=", 1)[1] for ct in self.iter_context(context + (item, ), tokens[5:]): yield ct elif is_int(tokens[1]): # set 0 ... for ct in self.iter_context(context + (tokens[1], ), tokens[2:]): yield ct else: # set XXX for ct in self.iter_context(context, tokens[1:]): yield ct context_fed = True if tokens[0] == "add" and len(tokens) > 1: # Process add instruction for ct in self.iter_context(context + (str(n_item), ), tokens[1:]): yield ct context_fed = True n_item += 1 # Yield last context if not already yielded if context and not context_fed: yield context
def resolve_expression(cls, s): """ Resolve expression to a list of object. Expression must be string or list. Elements must be one of: * string starting with @ - treated as selector name * string containing numbers - treated as object's id * string - managed object name. * string - IPv4 or IPv6 address - management address Raises ManagedObject.DoesNotExists if object is not found. Raises ManagedObjectSelector.DoesNotExists if selector is not found :param cls: :param s: :return: """ from .managedobject import ManagedObject if type(s) in (int, long, str, unicode): s = [s] if type(s) != list: raise ValueError("list required") objects = set() for so in s: if not isinstance(so, six.string_types): so = str(so) if so.startswith("@"): # Selector expression: @<selector name> o = ManagedObjectSelector.objects.get(name=so[1:]) objects |= set(o.managed_objects) else: # Search by name q = Q(name=so) if is_int(so): # Search by id q |= Q(id=int(so)) if is_ipv4(so) or is_ipv6(so): q |= Q(address=so) o = ManagedObject.objects.get(q) objects.add(o) return list(objects)
def get_managed_object(self, o_id): """ Get ManagedObject by id or name :param o_id: Object's id or name :return: ManagedObject :rtype: ManagedObject """ from noc.sa.models.managedobject import ManagedObject # Try to get object by id if is_int(o_id): try: return ManagedObject.objects.get(id=int(o_id)) except ManagedObject.DoesNotExist: pass # Try to get object by name try: return ManagedObject.objects.get(name=o_id) except ManagedObject.DoesNotExist: return None
def get_user(self, u_id): """ Get User by id or name :param u_id: Object's id or name :return: ManagedObject :rtype: ManagedObject """ from noc.aaa.models.user import User # Try to get object by id if is_int(u_id): try: return User.objects.get(id=int(u_id)) except User.DoesNotExist: pass # Try to get object by name try: return User.objects.get(username=u_id) except User.DoesNotExist: return None
def expand_interface_range(self, s): """ Convert interface range expression to a list of interfaces "Gi 1/1-3,Gi 1/7" -> ["Gi 1/1", "Gi 1/2", "Gi 1/3", "Gi 1/7"] "1:1-3" -> ["1:1", "1:2", "1:3"] "1:1-1:3" -> ["1:1", "1:2", "1:3"] :param s: Comma-separated list :return: """ r = set() for x in s.split(","): x = x.strip() if not x: continue if "-" in x: # Expand range f, t = [y.strip() for y in x.split("-")] # Detect common prefix match = self.rx_detect_sep.match(f) if not match: raise ValueError(x) prefix = match.group(1) # Detect range boundaries start = int(f[len(prefix):]) if is_int(t): stop = int(t) # Just integer else: if not t.startswith(prefix): raise ValueError(x) stop = int(t[len(prefix):]) # Prefixed if start > stop: raise ValueError(x) for i in range(start, stop + 1): r.add(prefix + str(i)) else: r.add(x) return sorted(r)
def get_local_iface(self): r = {} names = {x: y for y, x in six.iteritems(self.scripts.get_ifindexes())} # Get LocalPort Table for v in self.snmp.get_tables([ mib["LLDP-MIB::lldpLocPortNum"], mib["LLDP-MIB::lldpLocPortIdSubtype"], mib["LLDP-MIB::lldpLocPortId"], mib["LLDP-MIB::lldpLocPortDesc"], ]): if is_int(v[3]): if int(v[3]) not in names: continue iface_name = names[int(v[3])] else: iface_name = v[3] if iface_name.endswith(".0"): iface_name = iface_name[:-2] r[v[0]] = { "local_interface": iface_name, "local_interface_subtype": v[2] } return r