class Supplier(Document): meta = { "collection": "noc.suppliers", "indexes": ["name"], "strict": False, "auto_create_index": False } name = StringField() description = StringField() is_affilated = BooleanField(default=False) profile = PlainReferenceField(SupplierProfile) state = PlainReferenceField(State) # Integration with external NRI and TT systems # Reference to remote system object has been imported from remote_system = PlainReferenceField(RemoteSystem) # Object id in remote system remote_id = StringField() # Object id in BI bi_id = LongField(unique=True) tags = ListField(StringField()) _id_cache = cachetools.TTLCache(maxsize=100, ttl=60) def __unicode__(self): return self.name @classmethod @cachetools.cachedmethod(operator.attrgetter("_id_cache"), lock=lambda _: id_lock) def get_by_id(cls, id): return Supplier.objects.filter(id=id).first()
class VPN(Document): meta = { "collection": "vpns", "strict": False, "auto_create_index": False } name = StringField(unique=True) profile = PlainReferenceField(VPNProfile) description = StringField() state = PlainReferenceField(State) # Link to parent overlay parent = PlainReferenceField("self") project = ForeignKeyField(Project) route_target = ListField(EmbeddedDocumentField(RouteTargetItem)) tags = ListField(StringField()) # Integration with external NRI and TT systems # Reference to remote system object has been imported from remote_system = PlainReferenceField(RemoteSystem) # Object id in remote system remote_id = StringField() # Object id in BI bi_id = LongField(unique=True) # @todo: last_seen # @todo: expired _id_cache = cachetools.TTLCache(maxsize=100, ttl=60) _bi_id_cache = cachetools.TTLCache(maxsize=100, ttl=60) def __unicode__(self): return self.name @classmethod @cachetools.cachedmethod(operator.attrgetter("_id_cache"), lock=lambda _: id_lock) def get_by_id(cls, id): return VPN.objects.filter(id=id).first() @classmethod @cachetools.cachedmethod(operator.attrgetter("_bi_id_cache"), lock=lambda _: id_lock) def get_by_bi_id(cls, id): return VPN.objects.filter(bi_id=id).first() def clean(self): super(VPN, self).clean() if self.id and "parent" in self._changed_fields and self.has_loop: raise ValidationError("Creating VPN loop") @property def has_loop(self): """ Check if object creates loop """ if not self.id: return False p = self.parent while p: if p.id == self.id: return True p = p.parent return False
class SubscriberProfile(Document): meta = { "collection": "noc.subscriberprofiles", "strict": False, "auto_create_index": False } name = StringField(unique=True) description = StringField() style = ForeignKeyField(Style, required=False) workflow = PlainReferenceField(Workflow) # FontAwesome glyph glyph = StringField() tags = ListField(StringField()) # Alarm weight weight = IntField(default=0) # Integration with external NRI and TT systems # Reference to remote system object has been imported from remote_system = PlainReferenceField(RemoteSystem) # Object id in remote system remote_id = StringField() # Object id in BI bi_id = LongField(unique=True) _id_cache = cachetools.TTLCache(maxsize=100, ttl=60) def __unicode__(self): return self.name @classmethod @cachetools.cachedmethod(operator.attrgetter("_id_cache"), lock=lambda _: id_lock) def get_by_id(cls, id): return SubscriberProfile.objects.filter(id=id).first()
class SubInterface(Document): meta = { "collection": "noc.subinterfaces", "allow_inheritance": False, "indexes": [ ("managed_object", "ifindex"), ("managed_object", "vlan_ids"), "interface", "managed_object", "untagged_vlan", "tagged_vlans", "enabled_afi" ] } interface = PlainReferenceField(Interface) managed_object = ForeignKeyField(ManagedObject) forwarding_instance = PlainReferenceField( ForwardingInstance, required=False) name = StringField() description = StringField(required=False) profile = PlainReferenceField(InterfaceProfile, default=InterfaceProfile.get_default_profile) mtu = IntField(required=False) mac = StringField(required=False) vlan_ids = ListField(IntField(), default=[]) enabled_afi = ListField(StringField( choices=[(x, x) for x in SUBINTERFACE_AFI] ), default=[]) ipv4_addresses = ListField(StringField(), default=[]) ipv6_addresses = ListField(StringField(), default=[]) iso_addresses = ListField(StringField(), default=[]) vpi = IntField(required=False) vci = IntField(required=False) enabled_protocols = ListField(StringField( choices=[(x, x) for x in SUBINTERFACE_PROTOCOLS] ), default=[]) untagged_vlan = IntField(required=False) tagged_vlans = ListField(IntField(), default=[]) # ip_unnumbered_subinterface ifindex = IntField(required=False) # Tunnel services tunnel_type = StringField( choices=[(x, x) for x in TUNNEL_TYPES], required=False) tunnel_local_address = StringField(required=False) tunnel_remote_address = StringField(required=False) project = ForeignKeyField(Project) def __unicode__(self): return "%s %s" % (self.interface.managed_object.name, self.name) @property def effective_vc_domain(self): return self.interface.effective_vc_domain def get_profile(self): if self.profile: return self.profile else: return self.interface.profile
class ResourceGroup(Document): """ Technology Abstraction to restrict ResourceGroup links """ meta = { "collection": "resourcegroups", "strict": False, "auto_create_index": False } # Group | Name name = StringField() technology = PlainReferenceField(Technology) parent = PlainReferenceField("inv.ResourceGroup") description = StringField() # @todo: FM integration # Integration with external NRI and TT systems # Reference to remote system object has been imported from remote_system = PlainReferenceField(RemoteSystem) # Object id in remote system remote_id = StringField() # Object id in BI bi_id = LongField(unique=True) # Tags tags = ListField(StringField()) _id_cache = cachetools.TTLCache(maxsize=100, ttl=60) _bi_id_cache = cachetools.TTLCache(maxsize=100, ttl=60) def __unicode__(self): return "%s (%s)" % (self.name, self.technology.name) @classmethod @cachetools.cachedmethod(operator.attrgetter("_id_cache"), lock=lambda _: id_lock) def get_by_id(cls, id): return ResourceGroup.objects.filter(id=id).first() @classmethod @cachetools.cachedmethod(operator.attrgetter("_bi_id_cache"), lock=lambda _: id_lock) def get_by_bi_id(cls, id): return ResourceGroup.objects.filter(bi_id=id).first() def iter_changed_datastream(self): if config.datastream.enable_resourcegroup: yield "resourcegroup", self.id @property def has_children(self): return bool( ResourceGroup.objects.filter(parent=self.id).only("id").first())
class AddressProfile(Document): meta = { "collection": "addressprofiles", "strict": False, "auto_create_index": False } name = StringField(unique=True) description = StringField() # Address workflow workflow = PlainReferenceField(Workflow) style = ForeignKeyField(Style) # Template.subject to render Address.name name_template = ForeignKeyField(Template) # Template.subject to render Address.fqdn fqdn_template = ForeignKeyField(Template) # Send seen event to prefix seen_propagation_policy = StringField(choices=[("E", "Enable"), ("D", "Disable")], default="D") # tags = ListField(StringField()) # Integration with external NRI and TT systems # Reference to remote system object has been imported from remote_system = PlainReferenceField(RemoteSystem) # Object id in remote system remote_id = StringField() # Object id in BI bi_id = LongField(unique=True) _id_cache = cachetools.TTLCache(maxsize=100, ttl=60) _name_cache = cachetools.TTLCache(maxsize=100, ttl=60) _bi_id_cache = cachetools.TTLCache(maxsize=100, ttl=60) def __unicode__(self): return self.name @classmethod @cachetools.cachedmethod(operator.attrgetter("_id_cache"), lock=lambda _: id_lock) def get_by_id(cls, id): return AddressProfile.objects.filter(id=id).first() @classmethod @cachetools.cachedmethod(operator.attrgetter("_name_cache"), lock=lambda _: id_lock) def get_by_name(cls, name): return AddressProfile.objects.filter(name=name).first() @classmethod @cachetools.cachedmethod(operator.attrgetter("_bi_id_cache"), lock=lambda _: id_lock) def get_by_bi_id(cls, id): return AddressProfile.objects.filter(bi_id=id).first()
class VPNProfile(Document): meta = { "collection": "vpnprofiles", "strict": False, "auto_create_index": False } name = StringField(unique=True) description = StringField() type = StringField(choices=[("vrf", "VRF"), ("vxlan", "VxLAN"), ("vpls", "VPLS"), ("vll", "VLL"), ("evpn", "EVPN"), ("ipsec", "IPSec"), ("gre", "GRE"), ("ipip", "IP-IP")], default="vrf") workflow = PlainReferenceField(Workflow) # Template.subject to render VPN/VRF.name name_template = ForeignKeyField(Template) # style = ForeignKeyField(Style) # For vrf type -- default prefix profile # Used to create AFI root prefixes default_prefix_profile = PlainReferenceField("ip.PrefixProfile") # tags = ListField(StringField()) # Integration with external NRI and TT systems # Reference to remote system object has been imported from remote_system = PlainReferenceField(RemoteSystem) # Object id in remote system remote_id = StringField() # Object id in BI bi_id = LongField(unique=True) _id_cache = cachetools.TTLCache(maxsize=100, ttl=60) _bi_id_cache = cachetools.TTLCache(maxsize=100, ttl=60) def __unicode__(self): return self.name @classmethod @cachetools.cachedmethod(operator.attrgetter("_id_cache"), lock=lambda _: id_lock) def get_by_id(cls, id): return VPNProfile.objects.filter(id=id).first() @classmethod @cachetools.cachedmethod(operator.attrgetter("_bi_id_cache"), lock=lambda _: id_lock) def get_by_bi_id(cls, id): return VPNProfile.objects.filter(bi_id=id).first() def clean(self): if self.type == "vrf" and not self.default_prefix_profile: raise ValidationError( "default_prefix_profile must be set for vrf type")
class FirmwarePolicy(Document): meta = { "collection": "noc.firmwarepolicy", "strict": False, "auto_create_index": False, "indexes": ["platform", "firmware"] } # Platform (Matched with get_version) platform = PlainReferenceField(Platform) # description = StringField() # object_profile = ForeignKeyField(ManagedObjectProfile) # firmware = PlainReferenceField(Firmware) status = StringField( choices=[(FS_RECOMMENDED, "Recommended"), ( FS_ACCEPTABLE, "Acceptable"), (FS_NOT_RECOMMENDED, "Not recommended"), (FS_DENIED, "Denied")]) # management = ListField(EmbeddedDocumentField(ManagementPolicy)) @classmethod def get_status(cls, platform, version): if not platform or not version: return None fp = FirmwarePolicy.objects.filter(platform=platform.id, firmware=version.id).first() if fp: return fp.status else: return None @classmethod def get_recommended_version(cls, platform): if not platform: return None fp = FirmwarePolicy.objects.filter(platform=platform.id, status=FS_RECOMMENDED).first() if fp: return fp.firmware.version versions = [] for fp in FirmwarePolicy.objects.filter(platform=platform.id, status=FS_ACCEPTABLE): versions += [fp.firmware.version] if versions: # Get latest acceptable version return sorted(versions, key=lambda x: split_alnum(x.name))[-1] else: return None
class Change(Document): meta = { "collection": "noc.changes", "strict": False, "auto_create_index": False } document = PlainReferenceField(NormativeDocument)
class AllocationGroup(Document): meta = { "collection": "allocationgroups", "strict": False, "auto_create_index": False } name = StringField(unique=True) description = StringField() tags = ListField(StringField()) # Integration with external NRI and TT systems # Reference to remote system object has been imported from remote_system = PlainReferenceField(RemoteSystem) # Object id in remote system remote_id = StringField() # Object id in BI bi_id = LongField(unique=True) _id_cache = cachetools.TTLCache(maxsize=100, ttl=60) _bi_id_cache = cachetools.TTLCache(maxsize=100, ttl=60) def __unicode__(self): return self.name @classmethod @cachetools.cachedmethod(operator.attrgetter("_id_cache"), lock=lambda _: id_lock) def get_by_id(cls, id): return AllocationGroup.objects.filter(id=id).first() @classmethod @cachetools.cachedmethod(operator.attrgetter("_bi_id_cache"), lock=lambda _: id_lock) def get_by_bi_id(cls, id): return AllocationGroup.objects.filter(bi_id=id).first()
class Street(Document): meta = { "collection": "noc.streets", "strict": False, "auto_create_index": False, "indexes": ["parent", "data"] } # parent = PlainReferenceField(Division) # Normalized name name = StringField() # street/town/city, etc short_name = StringField() # is_active = BooleanField(default=True) # Additional data # Depends on importer data = DictField() # start_date = DateTimeField() end_date = DateTimeField() def __unicode__(self): if self.short_name: return "%s, %s" % (self.name, self.short_name) else: return self.name @property def full_path(self): if not self.parent: return "" r = [self.parent.full_path, unicode(self)] return " | ".join(r)
class CoveredObject(Document): meta = { "collection": "noc.coveredobjects", "allow_inheritance": False, "indexes": ["coverage", "object"] } coverage = PlainReferenceField(Coverage) # Coverage preference. # The more is the better # Zero means coverage is explicitly disabled for ordering preference = IntField(default=100) object = PlainReferenceField(Object) def __unicode__(self): return u"%s %s" % (self.coverage.name, self.object.name or self.object.id)
class VLANTranslation(EmbeddedDocument): filter = ForeignKeyField(VCFilter) rule = StringField(choices=[ # Rewrite tag to parent vlan's ("map", "map"), # Append parent tag as S-VLAN ("push", "push") ], default="push") parent_vlan = PlainReferenceField("vc.VLAN")
class ObjectConnectionItem(EmbeddedDocument): _meta = {"strict": False, "auto_create_index": False} # Object reference object = PlainReferenceField(Object) # Connection name name = StringField() def __unicode__(self): return "%s: %s" % (unicode(self.object), self.name)
class VLANProfile(Document): meta = { "collection": "vlanprofiles", "strict": False, "auto_create_index": False } name = StringField(unique=True) description = StringField() # VLAN is management VLAN enable_management = BooleanField(default=False) # VLAN is multicast VLAN enable_multicast = BooleanField(default=False) # VLAN should be automatically provisioned enable_provisioning = BooleanField(default=False) # VLAN workflow workflow = PlainReferenceField(Workflow) style = ForeignKeyField(Style) tags = ListField(StringField()) # Integration with external NRI and TT systems # Reference to remote system object has been imported from remote_system = PlainReferenceField(RemoteSystem) # Object id in remote system remote_id = StringField() # Object id in BI bi_id = LongField(unique=True) _id_cache = cachetools.TTLCache(maxsize=100, ttl=60) _bi_id_cache = cachetools.TTLCache(maxsize=100, ttl=60) def __unicode__(self): return self.name @classmethod @cachetools.cachedmethod(operator.attrgetter("_id_cache"), lock=lambda _: id_lock) def get_by_id(cls, id): return VLANProfile.objects.filter(id=id).first() @classmethod @cachetools.cachedmethod(operator.attrgetter("_bi_id_cache"), lock=lambda _: id_lock) def get_by_bi_id(cls, id): return VLANProfile.objects.filter(bi_id=id).first()
class ObjectConnectionItem(EmbeddedDocument): _meta = { "allow_inheritance": False } # Object reference object = PlainReferenceField(Object) # Connection name name = StringField() def __unicode__(self): return "%s: %s" % (unicode(self.object), self.name)
class CoveredBuilding(Document): meta = { "collection": "noc.coveredbuildings", "strict": False, "auto_create_index": False, "indexes": ["building", "coverage"] } coverage = PlainReferenceField(Coverage) # Coverage preference. # The more is the better # Zero means coverage is explicitly disabled for ordering preference = IntField(default=100) building = PlainReferenceField(Building) entrance = StringField(required=False) # Covered homes homes = IntField() def __unicode__(self): return u"%s %s" % (self.coverage.name, self.building.primary_address.display_ru())
class ActionCommands(Document): meta = { "collection": "noc.actioncommands", "strict": False, "auto_create_index": False, "json_collection": "sa.actioncommands", "json_depends_on": ["sa.actions", "sa.profile"], "json_unique_fields": ["name"] } name = StringField(unique=True) uuid = UUIDField(unique=True) action = ReferenceField(Action) description = StringField() profile = PlainReferenceField(Profile) config_mode = BooleanField(default=False) match = ListField(EmbeddedDocumentField(PlatformMatch)) commands = StringField() preference = IntField(default=1000) timeout = IntField(default=60) def __unicode__(self): return self.name def get_json_path(self): p = [quote_safe_path(n.strip()) for n in self.name.split("|")] return os.path.join(*p) + ".json" @property def json_data(self): r = { "name": self.name, "$collection": self._meta["json_collection"], "uuid": self.uuid, "action__name": self.action.name, "description": self.description, "profile__name": self.profile.name, "config_mode": self.config_mode, "match": [c.json_data for c in self.match], "commands": self.commands, "preference": self.preference, "timeout": self.timeout } return r def to_json(self): return to_json(self.json_data, order=[ "name", "$collection", "uuid", "action__name", "description", "profile__name", "config_mode", "preference", "match", "commands", "timeout" ])
class AlarmClassConfig(Document): """ Alarm class """ meta = {"collection": "noc.alarmclassconfigs", "allow_inheritance": False} alarm_class = PlainReferenceField(AlarmClass, unique=True) notification_delay = IntField(required=False) control_time0 = IntField(required=False) control_time1 = IntField(required=False) control_timeN = IntField(required=False) def __unicode__(self): return self.alarm_class.name
class ObjectModelConnection(EmbeddedDocument): meta = {"strict": False, "auto_create_index": False} name = StringField() description = StringField() type = PlainReferenceField(ConnectionType) direction = StringField(choices=[ "i", # Inner slot "o", # Outer slot "s" # Connection ]) gender = StringField(choices=["s", "m", "f"]) group = StringField(required=False) cross = StringField(required=False) protocols = ListField(StringField(), required=False) internal_name = StringField(required=False) def __unicode__(self): return self.name def __eq__(self, other): return (self.name == other.name and self.description == other.description and self.type.id == other.type.id and self.direction == other.direction and self.gender == other.gender and self.group == other.group and self.cross == other.cross and self.protocols == other.protocols and self.internal_name == other.internal_name) @property def json_data(self): r = { "name": self.name, "description": self.description, "type__name": self.type.name, "direction": self.direction, "gender": self.gender, } if self.group: r["group"] = self.group if self.cross: r["cross"] = self.cross if self.protocols: r["protocols"] = self.protocols if self.internal_name: r["internal_name"] = self.internal_name return r
class SLAProbe(Document): meta = { "collection": "noc.sla_probes", "strict": False, "auto_create_index": False, "indexes": [ "managed_object" ] } managed_object = ForeignKeyField(ManagedObject) # Probe name (<managed object>, <group>, <name> triple must be unique name = StringField() # Probe profile profile = PlainReferenceField(SLAProfile) # Probe group group = StringField() # Optional description description = StringField() # Probe type type = StringField(choices=[(x, x) for x in PROBE_TYPES]) # IP address or URL, depending on type target = StringField() # Hardware timestamps hw_timestamp = BooleanField(default=False) # Optional tags tags = ListField(StringField()) _id_cache = cachetools.TTLCache(maxsize=100, ttl=60) _target_cache = cachetools.TTLCache(maxsize=100, ttl=60) def __unicode__(self): return u"%s: %s" % (self.managed_object.name, self.name) @classmethod @cachetools.cachedmethod(operator.attrgetter("_id_cache"), lock=lambda _: id_lock) def get_by_id(cls, id): return SLAProbe.objects.filter(id=id).first() @cachetools.cachedmethod(operator.attrgetter("_target_cache"), lock=lambda _: id_lock) def get_target(self): mo = ManagedObject.objects.filter(address=self.target)[:1] if mo: return mo[0] else: return None
class ModelMapping(Document): meta = { "collection": "noc.modelmappings", "strict": False, "auto_create_index": False } # Vendor, as returned by get_inventory vendor = StringField() # Part number, as returned by get_inventory part_no = StringField() # Serial number ranges, if applicable from_serial = StringField() to_serial = StringField() # model = PlainReferenceField(ObjectModel) # is_active = BooleanField(default=True) description = StringField(required=False)
class PhoneNumberProfile(Document): meta = { "collection": "noc.phonenumberprofiles", "strict": False, "auto_create_index": False } name = StringField(unique=True) description = StringField() style = ForeignKeyField(Style) workflow = PlainReferenceField(Workflow) _id_cache = cachetools.TTLCache(maxsize=100, ttl=60) def __unicode__(self): return self.name @classmethod @cachetools.cachedmethod(operator.attrgetter("_id_cache"), lock=lambda _: id_lock) def get_by_id(cls, id): return PhoneNumberProfile.objects.filter(id=id).first()
class ASProfile(Document): meta = { "collection": "asprofiles", "strict": False, "auto_create_index": False } name = StringField(unique=True) description = StringField() style = ForeignKeyField(Style, required=False) enable_discovery_prefix_whois_route = BooleanField(default=False) prefix_profile_whois_route = PlainReferenceField("ip.PrefixProfile") _id_cache = cachetools.TTLCache(maxsize=100, ttl=60) def __unicode__(self): return self.name @classmethod @cachetools.cachedmethod(operator.attrgetter("_id_cache"), lock=lambda _: id_lock) def get_by_id(cls, id): return ASProfile.objects.filter(id=id).first()
class MetricType(Document): meta = { "collection": "noc.metrictypes", "strict": False, "auto_create_index": False, "json_collection": "pm.metrictypes", "json_depends_on": [ "pm.metricscopes" ], "json_unique_fields": ["name"] } # Metric type name, i.e. Interface | Load | In name = StringField(unique=True) # Global ID uuid = UUIDField(binary=True) # Metric scope reference scope = PlainReferenceField(MetricScope) # Database field name field_name = StringField() # Database field type field_type = StringField( choices=[ ("UInt8", "UInt8"), ("Int8", "Int8"), ("UInt16", "UInt16"), ("Int16", "Int16"), ("UInt32", "UInt32"), ("Int32", "Int32"), ("UInt64", "UInt64"), ("Int64", "Int64"), ("Float32", "Float32"), ("Float64", "Float64"), ("String", "String") ] ) # Text description description = StringField(required=False) # Measure name, like 'kbit/s' # Compatible to Grafana measure = StringField() # Optional required capability required_capability = PlainReferenceField(Capability) # Object id in BI, used for counter context hashing bi_id = LongField(unique=True) # category = ObjectIdField() _id_cache = cachetools.TTLCache(maxsize=100, ttl=60) _name_cache = cachetools.TTLCache(maxsize=100, ttl=60) _bi_id_cache = cachetools.TTLCache(maxsize=100, ttl=60) def __unicode__(self): return self.name @property def json_data(self): r = { "name": self.name, "$collection": self._meta["json_collection"], "uuid": self.uuid, "scope__name": self.scope.name, "field_name": self.field_name, "field_type": self.field_type, "description": self.description, "measure": self.measure } if self.required_capability: r["required_capability__name"] = self.required_capability.name return r def to_json(self): return to_json( self.json_data, order=[ "name", "$collection", "uuid", "scope__name", "field_name", "field_type", "description", "measure", "vector_tag"]) def get_json_path(self): p = [quote_safe_path(n.strip()) for n in self.name.split("|")] return os.path.join(*p) + ".json" @classmethod @cachetools.cachedmethod(operator.attrgetter("_id_cache"), lock=lambda _: id_lock) def get_by_id(cls, id): return MetricType.objects.filter(id=id).first() @classmethod @cachetools.cachedmethod(operator.attrgetter("_name_cache"), lock=lambda _: id_lock) def get_by_name(cls, name): return MetricType.objects.filter(name=name).first() @classmethod @cachetools.cachedmethod(operator.attrgetter("_bi_id_cache"), lock=lambda _: id_lock) def get_by_bi_id(cls, id): return MetricType.objects.filter(bi_id=id).first() def on_save(self): call_later( "noc.core.clickhouse.ensure.ensure_all_pm_scopes", scheduler="scheduler", delay=30 ) def clean_value(self, value): return getattr(self, "clean_%s" % self.field_type)(value) @staticmethod def clean_UInt8(value): try: v = int(value) except ValueError: raise if v < 0 or v > 255: raise ValueError("Value out of range") return v @staticmethod def clean_Int8(value): try: v = int(value) except ValueError: raise if v < -127 or v > 127: raise ValueError("Value out of range") return v @staticmethod def clean_UInt16(value): try: v = int(value) except ValueError: raise if v < 0 or v > 65535: raise ValueError("Value out of range") return v @staticmethod def clean_Int16(value): try: v = int(value) except ValueError: raise if v < -32767 or v > 32767: raise ValueError("Value out of range") return v @staticmethod def clean_UInt32(value): try: v = int(value) except ValueError: raise if v < 0 or v > 4294967295: raise ValueError("Value out of range") return v @staticmethod def clean_Int32(value): try: v = int(value) except ValueError: raise if v < -2147483647 or v > 2147483647: raise ValueError("Value out of range") return v @staticmethod def clean_UInt64(value): try: v = int(value) except ValueError: raise if v < 0 or v > 18446744073709551615: raise ValueError("Value out of range") return v @staticmethod def clean_Int64(value): try: v = int(value) except ValueError: raise if v < -9223372036854775807 or v > 9223372036854775807: raise ValueError("Value out of range") return v @staticmethod def clean_Float32(value): return float(value) @staticmethod def clean_Float64(value): return float(value) @staticmethod def clean_String(value): return str(value)
class PrefixProfile(Document): meta = { "collection": "prefixprofiles", "strict": False, "auto_create_index": False } name = StringField(unique=True) description = StringField() # Enable nested Address discovery # via ARP cache enable_ip_discovery = BooleanField(default=False) # Enable nested Addresses discovery # via active PING probes enable_ip_ping_discovery = BooleanField(default=False) # Enable nested prefix prefix discovery enable_prefix_discovery = BooleanField(default=False) # Prefix workflow workflow = PlainReferenceField(Workflow) style = ForeignKeyField(Style) # Template.subject to render Prefix.name name_template = ForeignKeyField(Template) # Discovery policies prefix_discovery_policy = StringField( choices=[ ("E", "Enable"), ("D", "Disable") ], default="D" ) address_discovery_policy = StringField( choices=[ ("E", "Enable"), ("D", "Disable") ], default="D" ) # Send seen event to parent seen_propagation_policy = StringField( choices=[ ("P", "Propagate"), ("E", "Enable"), ("D", "Disable") ], default="P" ) # tags = ListField(StringField()) # Integration with external NRI and TT systems # Reference to remote system object has been imported from remote_system = PlainReferenceField(RemoteSystem) # Object id in remote system remote_id = StringField() # Object id in BI bi_id = LongField(unique=True) _id_cache = cachetools.TTLCache(maxsize=100, ttl=60) _bi_id_cache = cachetools.TTLCache(maxsize=100, ttl=60) def __unicode__(self): return self.name @classmethod @cachetools.cachedmethod(operator.attrgetter("_id_cache"), lock=lambda _: id_lock) def get_by_id(cls, id): return PrefixProfile.objects.filter(id=id).first() @classmethod @cachetools.cachedmethod(operator.attrgetter("_bi_id_cache"), lock=lambda _: id_lock) def get_by_bi_id(cls, id): return PrefixProfile.objects.filter(bi_id=id).first()
class NetworkSegmentProfile(Document): meta = { "collection": "noc.networksegmentprofiles", "strict": False, "auto_create_index": False } name = StringField(unique=True) description = StringField(required=False) # segment discovery interval discovery_interval = IntField(default=86400) # Segment style style = ForeignKeyField(Style, required=False) # Restrict MAC discovery to management vlan mac_restrict_to_management_vlan = BooleanField(default=False) # Management vlan, to restrict MAC search for MAC topology discovery management_vlan = IntField(required=False, min_value=1, max_value=4095) # MVR VLAN multicast_vlan = IntField(required=False, min_value=1, max_value=4095) # Detect lost redundancy condition enable_lost_redundancy = BooleanField(default=False) # Horizontal transit policy horizontal_transit_policy = StringField( choices=[ ("E", "Always Enable"), ("C", "Calculate"), ("D", "Disable") ], default="D" ) # Default profile for autocreated children segments # (i.e. during autosegmentation) # Copy this segment profile otherwise autocreated_profile = PlainReferenceField("self") # List of enabled topology method # in order of preference (most preferable first) topology_methods = ListField(EmbeddedDocumentField(SegmentTopologySettings)) # Enable VLAN discovery for appropriative management objects enable_vlan = BooleanField(default=False) # Default VLAN profile for discovered VLANs default_vlan_profile = PlainReferenceField("vc.VLANProfile") # Integration with external NRI and TT systems # Reference to remote system object has been imported from remote_system = PlainReferenceField(RemoteSystem) # Object id in remote system remote_id = StringField() # Object id in BI bi_id = LongField(unique=True) _id_cache = cachetools.TTLCache(maxsize=100, ttl=60) _bi_id_cache = cachetools.TTLCache(maxsize=100, ttl=60) def __unicode__(self): return self.name @classmethod @cachetools.cachedmethod(operator.attrgetter("_id_cache"), lock=lambda _: id_lock) def get_by_id(cls, id): return NetworkSegmentProfile.objects.filter(id=id).first() @classmethod @cachetools.cachedmethod(operator.attrgetter("_bi_id_cache"), lock=lambda _: id_lock) def get_by_bi_id(cls, id): return NetworkSegmentProfile.objects.filter(bi_id=id).first() def on_save(self): if hasattr(self, "_changed_fields") and "discovery_interval" in self._changed_fields: from .networksegment import NetworkSegment for ns in NetworkSegment.objects.filter(profile=self.id): ns.ensure_discovery_jobs() def get_topology_methods(self): ml = getattr(self, "_topology_methods", None) if not ml: ml = [m.method for m in self.topology_methods if m.is_active and m not in ("custom", "handler")] self._topology_methods = ml return ml def is_preferable_method(self, m1, m2): """ Returns True if m1 topology discovery method is preferable over m2 """ if m1 == m2: # Method can refine itself return True try: methods = self.get_topology_methods() i1 = methods.index(m1) i2 = methods.index(m2) except ValueError: return False return i1 <= i2
class ActiveEvent(Document): """ Event in the Active state """ meta = { "collection": "noc.events.active", "strict": False, "auto_create_index": False, "indexes": [ "timestamp", "discriminator", "alarms", ("timestamp", "event_class", "managed_object"), { "fields": ["expires"], "expireAfterSeconds": 0 } ] } status = "A" # Fields timestamp = DateTimeField(required=True) managed_object = ForeignKeyField(ManagedObject, required=True) event_class = PlainReferenceField(EventClass, required=True) start_timestamp = DateTimeField(required=True) repeats = IntField(required=True) source = StringField() raw_vars = RawDictField() resolved_vars = RawDictField() vars = DictField() log = ListField(EmbeddedDocumentField(EventLog)) discriminator = StringField(required=False) alarms = ListField(ObjectIdField()) expires = DateTimeField(required=False) def __unicode__(self): return u"%s" % self.id @classmethod @cachedmethod(key="activeevent-%s", lock=lambda _: id_lock, ttl=900) def get_by_id(cls, event_id): return ActiveEvent.objects.filter(id=event_id).first() def mark_as_new(self, message=None): """ Move to new queue for reclassification @todo: Rename method to *reclassify* """ from noc.core.nsq.pub import nsq_pub # if message is None: # message = "Reclassification requested" # log = self.log + [EventLog(timestamp=datetime.datetime.now(), # from_status="A", to_status="N", # message=message)] data = {"source": self.source} data.update(self.raw_vars) msg = { "id": str(self.id), "ts": time.mktime(self.timestamp.timetuple()), "object": self.managed_object.id, "data": data } nsq_pub("events.%s" % self.managed_object.pool.name, msg) self.delete() def mark_as_failed(self, version, traceback): """ Move event into noc.events.failed """ message = "Failed to classify on NOC version %s" % version log = self.log + [ EventLog(timestamp=datetime.datetime.now(), from_status="N", to_status="F", message=message) ] e = FailedEvent(id=self.id, timestamp=self.timestamp, managed_object=self.managed_object, source=self.source, raw_vars=self.raw_vars, version=version, traceback=traceback, log=log) e.save() self.delete() return e def mark_as_archived(self, message): log = self.log + [ EventLog(timestamp=datetime.datetime.now(), from_status="A", to_status="S", message=message) ] e = ArchivedEvent(id=self.id, timestamp=self.timestamp, managed_object=self.managed_object, event_class=self.event_class, start_timestamp=self.start_timestamp, repeats=self.repeats, raw_vars=self.raw_vars, resolved_vars=self.resolved_vars, vars=self.vars, log=log, alarms=self.alarms) e.save() self.delete() return e def drop(self): """ Mark event to be dropped. Only for use from event trigger pyrule. All further operations on event may lead to unpredictable results. Event actually deleted by noc-classifier """ self.id = None @property def to_drop(self): """ Check event marked to be dropped """ return self.id is None def log_message(self, message): self.log += [ EventLog(timestamp=datetime.datetime.now(), from_status=self.status, to_status=self.status, message=message) ] self.save() def log_suppression(self, timestamp): """ Increate repeat count and update timestamp, if required """ self.repeats += 1 if timestamp > self.timestamp: self.timestamp = timestamp self.save() @property def duration(self): """ Logged event duration in seconds """ return total_seconds(self.timestamp - self.start_timestamp) def get_template_vars(self): """ Prepare template variables """ vars = self.vars.copy() vars.update({"event": self}) return vars @property def subject(self): ctx = Context(self.get_template_vars()) s = Template(self.event_class.subject_template).render(ctx) if len(s) >= 255: s = s[:125] + " ... " + s[-125:] return s @property def body(self): ctx = Context(self.get_template_vars()) s = Template(self.event_class.body_template).render(ctx) return s @property def managed_object_id(self): """ Hack to return managed_object.id without SQL lookup """ o = self._data["managed_object"] if hasattr(o, "id"): return o.id return o def contribute_to_alarm(self, alarm): if alarm.id in self.alarms: return self._get_collection().update_one({ "_id": self.id, }, { "$set": { "expires": None, }, "$push": { "alarms": alarm.id } }) self.alarms.append(alarm.id) self.expires = None def do_not_dispose(self): """ Skip dispose :return: """ self._do_not_dispose = True @property def to_dispose(self): if not self.event_class: return True if hasattr(self, "_do_not_dispose"): return False return len(self.event_class.disposition) > 0
class Change(Document): meta = { "collection": "noc.changes", "allow_inheritance": False } document = PlainReferenceField(NormativeDocument)
class EventClassificationRule(Document): """ Classification rules """ meta = { "collection": "noc.eventclassificationrules", "strict": False, "auto_create_index": False, "json_collection": "fm.eventclassificationrules", "json_depends_on": ["fm.eventclasses"] } name = fields.StringField(required=True, unique=True) uuid = fields.UUIDField(binary=True) description = fields.StringField(required=False) event_class = PlainReferenceField(EventClass, required=True) preference = fields.IntField(required=True, default=1000) patterns = fields.ListField( fields.EmbeddedDocumentField(EventClassificationPattern)) datasources = fields.ListField(fields.EmbeddedDocumentField(DataSource)) vars = fields.ListField( fields.EmbeddedDocumentField(EventClassificationRuleVar)) # category = fields.ObjectIdField() def __unicode__(self): return self.name def save(self, *args, **kwargs): c_name = " | ".join(self.name.split(" | ")[:-1]) c = EventClassificationRuleCategory.objects.filter(name=c_name).first() if not c: c = EventClassificationRuleCategory(name=c_name) c.save() self.category = c.id super(EventClassificationRule, self).save(*args, **kwargs) @property def short_name(self): return self.name.split(" | ")[-1] def to_json(self): r = ["{"] r += [" \"name\": \"%s\"," % jq(self.name)] r += [ " \"$collection\": \"%s\"," % jq(self._meta["json_collection"]) ] r += [" \"uuid\": \"%s\"," % self.uuid] if self.description: r += [" \"description\": \"%s\"," % jq(self.description)] r += [" \"event_class__name\": \"%s\"," % jq(self.event_class.name)] r += [" \"preference\": %d," % self.preference] # Dump datasources if self.datasources: r += [" \"datasources\": ["] jds = [] for ds in self.datasources: x = [" \"name\": \"%s\"" % jq(ds.name)] x += [" \"datasource\": \"%s\"" % jq(ds.datasource)] ss = [] for k in sorted(ds.search): ss += [ " \"%s\": \"%s\"" % (jq(k), jq(ds.search[k])) ] x += [" \"search\": {"] x += [",\n".join(ss)] x += [" }"] jds += [" {", ",\n".join(x), " }"] r += [",\n\n".join(jds)] r += [" ],"] # Dump vars if self.vars: r += [" \"vars\": ["] vars = [] for v in self.vars: vd = [" {"] vd += [" \"name\": \"%s\"," % jq(v.name)] vd += [" \"value\": \"%s\"" % jq(v.value)] vd += [" }"] vars += ["\n".join(vd)] r += [",\n\n".join(vars)] r += [" ],"] # Dump patterns r += [" \"patterns\": ["] patterns = [] for p in self.patterns: pt = [] pt += [" {"] pt += [" \"key_re\": \"%s\"," % jq(p.key_re)] pt += [" \"value_re\": \"%s\"" % jq(p.value_re)] pt += [" }"] patterns += ["\n".join(pt)] r += [",\n".join(patterns)] r += [" ]"] r += ["}"] return "\n".join(r) def get_json_path(self): p = [quote_safe_path(n.strip()) for n in self.name.split("|")] return os.path.join(*p) + ".json"