示例#1
0
文件: conduits.py 项目: fossabot/noc
 def init_plugin(self):
     super(ConduitsPlugin, self).init_plugin()
     self.add_view("api_plugin_%s_get_neighbors" % self.name,
                   self.api_get_neighbors,
                   url="^(?P<id>[0-9a-f]{24})/plugin/%s/get_neighbors/$" %
                   self.name,
                   method=["GET"])
     self.add_view(
         "api_plugin_%s_create_ducts" % self.name,
         self.api_create_ducts,
         url="^(?P<id>[0-9a-f]{24})/plugin/%s/$" % self.name,
         method=["POST"],
         validate={
             "ducts":
             DictListParameter(
                 attrs={
                     "target":
                     DocumentParameter(Object),
                     "project_distance":
                     FloatParameter(),
                     "conduits":
                     DictListParameter(
                         attrs={
                             "id": DocumentParameter(Object,
                                                     required=False),
                             "n": IntParameter(),
                             "x": IntParameter(),
                             "y": IntParameter(),
                             "status": BooleanParameter()
                         })
                 })
         })
     #
     self.conduits_model = ObjectModel.objects.filter(
         name=self.CONDUITS_MODEL).first()
示例#2
0
def test_dictlist_parameter():
    assert DictListParameter().clean([{
        "1": 2
    }, {
        "2": 3,
        "4": 1
    }]) == [{
        "1": 2
    }, {
        "2": 3,
        "4": 1
    }]
    assert DictListParameter(attrs={
        "i": IntParameter(),
        "s": StringParameter()
    }).clean([{
        "i": 10,
        "s": "ten"
    }, {
        "i": "5",
        "s": "five"
    }]) == [{
        "i": 10,
        "s": "ten"
    }, {
        "i": 5,
        "s": "five"
    }]
    assert DictListParameter(attrs={
        "i": IntParameter(),
        "s": StringParameter()
    },
                             convert=True).clean({
                                 "i": "10",
                                 "s": "ten"
                             }) == [{
                                 "i": 10,
                                 "s": "ten"
                             }]
示例#3
0
from noc.core.clickhouse.connect import ClickhouseClient
from noc.core.clickhouse.error import ClickhouseError
from noc.sa.models.profile import Profile
from ..base import NBIAPI

Request = DictParameter(
    attrs={
        "from":
        DateTimeShiftParameter(required=True),
        "to":
        DateTimeShiftParameter(required=True),
        "metrics":
        DictListParameter(
            attrs={
                "object": StringParameter(required=True),
                "interfaces": StringListParameter(required=False),
                "metric_types": StringListParameter(required=True),
            },
            required=True,
        ),
    })

S_INTERFACE = "interface"


class ObjectMetricsAPI(NBIAPI):
    name = "objectmetrics"

    @authenticated
    @tornado.gen.coroutine
    def post(self):
        code, result = yield self.executor.submit(self.handler)
示例#4
0
文件: test_base.py 项目: nbashev/noc
def test_dictlist_parameter(raw, config, expected):
    assert DictListParameter(**config).clean(raw) == expected
示例#5
0
class ProbeApplication(ExtDocApplication):
    """
    PMProbe application
    """
    title = "Probe"
    menu = "Setup | Probes"
    model = Probe
    query_fields = ["name"]

    REFRESH_CHUNK = config.getint("pm", "expired_refresh_chunk")
    REFRESH_TIMEOUT = config.getint("pm", "expired_refresh_timeout")

    @view(url="^(?P<name>[^/]+)/(?P<instance>\d+)/config/$",
          method=["GET"],
          validate={"last": DateTimeParameter(required=False)},
          access="config",
          api=True)
    def api_config(self, request, name, instance, last=None):
        """
        Get full probe configuration
        """
        probe = self.get_object_or_404(Probe, name=name)
        if not probe.user or request.user.id != probe.user.id:
            return self.response_forbidden()
        instance = int(instance)
        if instance >= probe.n_instances:
            return self.response_not_found("Invalid instance")
        probe_id = str(probe.id)
        now = datetime.datetime.now()
        # Refresh expired congfigs
        t0 = time.time()
        nr = 0
        dt = 0
        stopped = False
        for pc in ProbeConfig.objects.filter(probe_id=probe_id,
                                             instance_id=instance,
                                             expire__lt=now):
            pc.refresh()
            nr += 1
            if nr % self.REFRESH_CHUNK:
                # Check execution time
                dt = time.time() - t0
                if dt > self.REFRESH_TIMEOUT:
                    self.logger.info(
                        "%d configs has been refreshed in %s seconds. Giving up",
                        nr, dt)
                    stopped = True
                    break
        if nr and not stopped:
            self.logger.info("%d configs has been refreshed in %s seconds.",
                             nr, dt)
        # Get configs
        q = {"probe_id": probe_id, "instance_id": instance}
        if last:
            fmt = "%Y-%m-%dT%H:%M:%S.%f" if "." in last else "%Y-%m-%dT%H:%M:%S"
            last = datetime.datetime.strptime(last, fmt)
            q["changed"] = {"$gte": last}
        config = [{
            "uuid":
            pc["uuid"],
            "handler":
            pc["handler"],
            "interval":
            pc["interval"],
            "metrics": [{
                "metric": m["metric"],
                "metric_type": m["metric_type"],
                "thresholds": m["thresholds"],
                "convert": m["convert"],
                "scale": m["scale"],
                "collectors": {
                    "policy":
                    m["collectors"]["policy"],
                    "write_concern":
                    m["collectors"]["write_concern"],
                    "collectors": [{
                        "proto": c["proto"],
                        "address": c["address"],
                        "port": c["port"]
                    } for c in m["collectors"]["collectors"]]
                }
            } for m in pc["metrics"]],
            "config":
            pc["config"],
            "managed_object":
            pc.get("managed_object", None),
            "changed":
            pc["changed"].isoformat(),
            "expire":
            pc["expire"].isoformat()
        } for pc in ProbeConfig._get_collection().find(q)]
        if config:
            expire = min(c["expire"] for c in config)
            # Wipe out deleted configs
            deleted = [
                c["uuid"] for c in config if c["changed"] == c["expire"]
            ]
            if deleted:
                ProbeConfig.objects.filter(uuid__in=deleted).delete()
        else:
            expire = None
        return {
            "now": now.isoformat(),
            "last": last.isoformat() if last else None,
            "expire": expire,
            "config": config
        }

    @view(url="^(?P<name>[^/]+)/(?P<instance>\d+)/feed/$",
          method=["POST"],
          validate={
              "thresholds":
              DictListParameter(
                  attrs={
                      "managed_object": IntParameter(),
                      "metric": StringParameter(),
                      "metric_type": StringParameter(),
                      "ts": IntParameter(),
                      "value": FloatParameter(),
                      "old_state": StringParameter(),
                      "new_state": StringParameter()
                  })
          },
          access="config",
          api=True)
    def api_fmfeed(self, request, name, instance, thresholds):
        if thresholds:
            cnt = itertools.count()
            batch = NewEvent._get_collection().initialize_unordered_bulk_op()
            for t in thresholds:
                seq = struct.pack("!II", int(time.time()),
                                  cnt.next() & 0xFFFFFFFFL)
                batch.insert({
                    "timestamp":
                    datetime.datetime.fromtimestamp(t["ts"]),
                    "managed_object":
                    t["managed_object"],
                    "raw_vars": {
                        "source": "system",
                        "metric": t["metric"],
                        "metric_type": t["metric_type"],
                        "value": str(t["value"]),
                        "old_state": t["old_state"],
                        "new_state": t["new_state"]
                    },
                    "seq":
                    Binary(seq)
                })
            batch.execute(0)
示例#6
0
from noc.sa.interfaces.base import DictListParameter, ObjectIdParameter, BooleanParameter
from noc.core.bi.decorator import bi_sync
from noc.ip.models.prefixprofile import PrefixProfile
from noc.ip.models.addressprofile import AddressProfile
from noc.vc.models.vpnprofile import VPNProfile
from noc.main.models.extstorage import ExtStorage
from noc.main.models.template import Template
from noc.core.datastream.decorator import datastream
from noc.cm.models.objectvalidationpolicy import ObjectValidationPolicy
from .authprofile import AuthProfile
from .capsprofile import CapsProfile

m_valid = DictListParameter(
    attrs={
        "metric_type": ObjectIdParameter(required=True),
        "enable_box": BooleanParameter(default=False),
        "enable_periodic": BooleanParameter(default=True),
        "is_stored": BooleanParameter(default=True),
        "threshold_profile": ObjectIdParameter(required=False),
    })

id_lock = Lock()


@on_init
@on_save
@bi_sync
@datastream
@on_delete_check(check=[
    ("sa.ManagedObject", "object_profile"),
    ("sa.ManagedObjectProfile", "cpe_profile"),
    ("sa.ManagedObjectSelector", "filter_object_profile"),
示例#7
0
class ValidationPolicySettingsApplication(ExtDocApplication):
    """
    ValidationPolicySettings application
    """

    title = _("Validation Policy Settings")
    model = ValidationPolicySettings

    MODEL_SCOPES = {
        "sa.ManagedObject": 2,
        "sa.ManagedObjectProfile": 2,
        "inv.Interface": 2,
        "inv.InterfaceProfile": 2,
    }

    @view(
        "^(?P<model_id>[^/]+)/(?P<object_id>[^/]+)/settings/$",
        method=["GET"],
        access="read",
        api=True,
    )
    def api_get_settings(self, request, model_id, object_id):
        if model_id not in self.MODEL_SCOPES:
            return self.response_not_found("Invalid model")
        o = ValidationPolicySettings.objects.filter(
            model_id=model_id, object_id=object_id).first()
        if o:
            # Policy settings
            return [{
                "policy": str(p.policy.id),
                "policy__label": p.policy.name,
                "is_active": p.is_active,
            } for p in o.policies]
        else:
            return {}

    @view(
        "^(?P<model_id>[^/]+)/(?P<object_id>[^/]+)/settings/$",
        method=["POST"],
        access="read",
        api=True,
        validate={
            "policies":
            DictListParameter(
                attrs={
                    "policy": DocumentParameter(ValidationPolicy),
                    "is_active": BooleanParameter(),
                })
        },
    )
    def api_save_settings(self, request, model_id, object_id, policies):
        def save_settings(o):
            o.save()
            return self.response({"status": True}, self.OK)

        o = ValidationPolicySettings.objects.filter(
            model_id=model_id, object_id=object_id).first()
        seen = set()
        ps = []
        for p in policies:
            if p["policy"].id in seen:
                continue
            ps += [
                ValidationPolicyItem(policy=p["policy"],
                                     is_active=p["is_active"])
            ]
            seen.add(p["policy"].id)
        if o:
            o.policies = ps
        else:
            o = ValidationPolicySettings(model_id=model_id,
                                         object_id=object_id,
                                         policies=ps)
        self.submit_slow_op(request, save_settings, o)
示例#8
0
    StringListParameter,
    IntParameter,
    ListOfParameter,
    ListParameter,
)
from noc.pm.models.metrictype import MetricType
from ..base import NBIAPI


Request = DictParameter(
    attrs={
        "bi_id": IntParameter(required=True),
        "metrics": DictListParameter(
            attrs={
                "metric_type": StringParameter(required=True),
                "path": StringListParameter(required=True),
                "values": ListOfParameter(ListParameter(), required=True),
            },
            required=True,
        ),
    }
)


class TelemetryAPI(NBIAPI):
    name = "telemetry"

    @authenticated
    @tornado.gen.coroutine
    def post(self):
        code, result = yield self.executor.submit(self.handler)
        self.set_status(code)
示例#9
0
文件: views.py 项目: nbashev/noc
class WorkflowApplication(ExtDocApplication):
    """
    Workflow application
    """

    title = _("Workflows")
    menu = [_("Setup"), _("Workflow")]
    model = Workflow

    NEW_ID = "000000000000000000000000"

    @view(r"^(?P<id>[0-9a-f]{24})/config/",
          method=["GET"],
          access="write",
          api=True)
    def api_get_config(self, request, id):
        wf = self.get_object_or_404(Workflow, id=id)
        r = {
            "id": str(wf.id),
            "name": wf.name,
            "is_active": wf.is_active,
            "description": wf.description,
            "states": [],
            "transitions": [],
        }
        for state in State.objects.filter(workflow=wf.id):
            sr = {
                "id": str(state.id),
                "name": state.name,
                "description": state.description,
                "is_default": state.is_default,
                "is_productive": state.is_productive,
                "update_last_seen": state.update_last_seen,
                "ttl": state.ttl,
                "update_expired": state.update_expired,
                "on_enter_handlers": state.on_enter_handlers,
                "job_handler": state.job_handler,
                "on_leave_handlers": state.on_leave_handlers,
                "bi_id": str(state.bi_id) if state.bi_id else None,
                "x": state.x,
                "y": state.y,
            }
            r["states"] += [sr]
        for t in Transition.objects.filter(workflow=wf.id):
            tr = {
                "id": str(t.id),
                "from_state": t.from_state.name,
                "to_state": t.to_state.name,
                "is_active": t.is_active,
                "event": t.event,
                "label": t.label,
                "description": t.description,
                "enable_manual": t.enable_manual,
                "handlers": t.handlers,
                "vertices": [{
                    "x": v.x,
                    "y": v.y
                } for v in t.vertices],
                "bi_id": str(t.bi_id) if t.bi_id else None,
            }
            r["transitions"] += [tr]
        return r

    @view(
        r"^(?P<id>[0-9a-f]{24})/config/",
        method=["POST"],
        access="write",
        api=True,
        validate={
            "name":
            StringParameter(),
            "description":
            StringParameter(default=""),
            "is_active":
            BooleanParameter(default=False),
            "states":
            DictListParameter(
                attrs={
                    "id": StringParameter(default=""),
                    "name": StringParameter(),
                    "description": StringParameter(default=""),
                    "is_default": BooleanParameter(default=False),
                    "is_productive": BooleanParameter(default=False),
                    "update_last_seen": BooleanParameter(default=False),
                    "ttl": IntParameter(default=0),
                    "update_expired": BooleanParameter(default=False),
                    "on_enter_handlers": StringListParameter(),
                    "job_handler": StringParameter(required=False),
                    "on_leave_handlers": StringListParameter(),
                    "x": IntParameter(),
                    "y": IntParameter(),
                }),
            "transitions":
            DictListParameter(
                attrs={
                    "id":
                    StringParameter(default=""),
                    "from_state":
                    StringParameter(),
                    "to_state":
                    StringParameter(),
                    "is_active":
                    BooleanParameter(default=False),
                    "event":
                    StringParameter(),
                    "label":
                    StringParameter(),
                    "description":
                    StringParameter(default=""),
                    "enable_manual":
                    BooleanParameter(),
                    "handlers":
                    StringListParameter(),
                    "vertices":
                    DictListParameter(attrs={
                        "x": IntParameter(),
                        "y": IntParameter()
                    }),
                }),
        },
    )
    def api_save_config(self, request, id, name, description, states,
                        transitions, **kwargs):
        if id == self.NEW_ID:
            wf = Workflow()
        else:
            wf = self.get_object_or_404(Workflow, id=id)
        # Update workflow
        wf.name = name
        wf.description = description
        wf.save()
        # Get current state
        current_states = {}  # str(id) -> state
        for st in State.objects.filter(workflow=wf.id):
            current_states[str(st.id)] = st
        # Synchronize states
        seen_states = set()
        state_names = {}  # name -> state
        for s in states:
            state = None
            if s["id"]:
                # Existing state
                seen_states.add(s["id"])
                state = current_states.get(s["id"])
            if not hasattr(s, "workflow"):
                s["workflow"] = wf.id
            # Update state attributes
            if not state:
                state = State()
                changed = True
            else:
                changed = False
            for k in s:
                if k in ("id", "bi_id"):
                    continue
                if getattr(state, k) != s[k]:
                    setattr(state, k, s[k])
                    changed = True
            if changed:
                state.save()
            state_names[state.name] = state
        # Get current transitions
        current_transitions = {}  # str(id) -> transition
        for ct in Transition.objects.filter(workflow=wf.id):
            current_transitions[str(ct.id)] = ct
        # Synchronize transitions
        seen_transitions = set()
        for t in transitions:
            transition = None
            if t["id"]:
                # Existing transitions
                seen_transitions.add(t["id"])
                transition = current_transitions.get(t["id"])
            # Update transition attributes
            if not transition:
                transition = Transition(workflow=wf)
                changed = True
            else:
                changed = False
            for k in t:
                if k in ("id", "bi_id"):
                    continue
                elif k in ("from_state", "to_state"):
                    t[k] = state_names[t[k]]
                elif k == "vertices":
                    t[k] = [
                        TransitionVertex(x=vx["x"], y=vx["y"]) for vx in t[k]
                    ]
                old = getattr(transition, k)
                if old != t[k]:
                    setattr(transition, k, t[k])
                    changed = True
            if changed:
                transition.save()
        # Delete hanging transitions
        for tid in set(current_transitions) - seen_transitions:
            current_transitions[tid].delete()
        # Delete hanging state
        for sid in set(current_states) - seen_states:
            current_states[sid].delete()

    rx_clone_name = re.compile(r"\(Copy #(\d+)\)$")

    @view(r"^(?P<id>[0-9a-f]{24})/clone/",
          method=["POST"],
          access="write",
          api=True)
    def api_clone(self, request, id):
        wf = self.get_object_or_404(Workflow, id=id)
        # Get all clone names
        m = 0
        for d in Workflow._get_collection().find(
            {
                "name": {
                    "$regex": re.compile(
                        r"^%s\(Copy #\d+\)$" % re.escape(wf.name))
                }
            },
            {
                "_id": 0,
                "name": 1
            },
        ):
            match = self.rx_clone_name.search(d["name"])
            if match:
                n = int(match.group(1))
                if n > m:
                    m = n
        # Generate name
        name = "%s (Copy #%d)" % (wf.name, m + 1)
        # Clone workflow
        new_wf = deepcopy(wf)
        new_wf.name = name
        new_wf.id = None
        new_wf.bi_id = None
        new_wf.save()
        # Clone states
        smap = {}  # old id -> new state
        for state in State.objects.filter(workflow=wf.id):
            new_state = deepcopy(state)
            new_state.workflow = new_wf
            new_state.id = None
            new_state.bi_id = None
            new_state.save()
            smap[state.id] = new_state
        # Clone transitions
        for transition in Transition.objects.filter(workflow=wf.id):
            new_transition = deepcopy(transition)
            new_transition.workflow = new_wf
            new_transition.from_state = smap[transition.from_state.id]
            new_transition.to_state = smap[transition.to_state.id]
            new_transition.id = None
            new_transition.bi_id = None
            new_transition.save()
        #
        return {"id": str(new_wf.id)}
示例#10
0
from noc.sa.interfaces.base import DictListParameter, DictParameter, IntParameter, StringParameter
from noc.core.perf import metrics
from noc.core.translation import ugettext as _

# Access items validations
I_VALID = DictListParameter(
    attrs={
        "group":
        DictParameter(
            attrs={
                "id": IntParameter(required=True),
                "name": StringParameter(required=False)
            },
            required=False,
        ),
        "user":
        DictParameter(
            attrs={
                "id": IntParameter(required=True),
                "name": StringParameter(required=False)
            },
            required=False,
        ),
        "level":
        IntParameter(min_value=-1, max_value=3, default=-1),
    })

ds_lock = threading.Lock()
model_lock = threading.Lock()

示例#11
0
class MapApplication(ExtApplication):
    """
    inv.net application
    """

    title = _("Network Map")
    menu = _("Network Map")
    glyph = "globe"

    implied_permissions = {"launch": ["inv:networksegment:lookup"]}

    # Object statuses
    ST_UNKNOWN = 0  # Object state is unknown
    ST_OK = 1  # Object is OK
    ST_ALARM = 2  # Object is reachable, Active alarms
    ST_UNREACH = 3  # Object is unreachable due to other's object failure
    ST_DOWN = 4  # Object is down
    ST_MAINTENANCE = 32  # Maintenance bit

    @view(r"^(?P<id>[0-9a-f]{24})/data/$",
          method=["GET"],
          access="read",
          api=True)
    def api_data(self, request, id):
        def q_mo(d):
            x = d.copy()
            if x["type"] == "managedobject":
                del x["mo"]
                x["external"] = x["id"] not in mos if is_view else x.get(
                    "role") != "segment"
            elif d["type"] == "cloud":
                del x["link"]
                x["external"] = False
            return x

        # Find segment
        segment = self.get_object_or_404(NetworkSegment, id=id)
        if segment.managed_objects.count() > segment.max_objects:
            # Too many objects
            return {
                "id": str(segment.id),
                "name": segment.name,
                "error": _("Too many objects")
            }
        # if we set selector in segment
        is_view = segment.selector
        if is_view:
            mos = segment.selector.managed_objects.values_list("id", flat=True)
        # Load settings
        settings = MapSettings.objects.filter(segment=id).first()
        node_hints = {}
        link_hints = {}
        if settings:
            self.logger.info("Using stored positions")
            for n in settings.nodes:
                node_hints[n.id] = {
                    "type": n.type,
                    "id": n.id,
                    "x": n.x,
                    "y": n.y
                }
            for ll in settings.links:
                link_hints[ll.id] = {
                    "connector":
                    ll.connector if len(ll.vertices) else "normal",
                    "vertices": [{
                        "x": v.x,
                        "y": v.y
                    } for v in ll.vertices],
                }
        else:
            self.logger.info("Generating positions")
        # Generate topology
        topology = SegmentTopology(
            segment,
            node_hints,
            link_hints,
            force_spring=request.GET.get("force") == "spring")
        topology.layout()
        # Build output
        r = {
            "id": str(segment.id),
            "max_links": int(segment.max_shown_downlinks),
            "name": segment.name,
            "caps": list(topology.caps),
            "nodes": [q_mo(x) for x in topology.G.nodes.values()],
            "links": [topology.G[u][v] for u, v in topology.G.edges()],
        }
        # Parent info
        if segment.parent:
            r["parent"] = {
                "id": str(segment.parent.id),
                "name": segment.parent.name
            }
        # Save settings
        if not settings:
            self.logger.debug("Saving first-time layout")
            MapSettings.load_json({
                "id":
                str(segment.id),
                "nodes":
                [{
                    "type": n["type"],
                    "id": n["id"],
                    "x": n["x"],
                    "y": n["y"]
                } for n in r["nodes"]
                 if n.get("x") is not None and n.get("y") is not None],
                "links": [{
                    "type": n["type"],
                    "id": n["id"],
                    "vertices": n.get("vertices", []),
                    "connector": n.get("connector", "normal"),
                } for n in r["links"]],
            })
        return r

    @view(r"^(?P<id>[0-9a-f]{24})/data/$",
          method=["POST"],
          access="write",
          api=True)
    def api_save(self, request, id):
        self.get_object_or_404(NetworkSegment, id=id)
        data = self.deserialize(request.body)
        data["id"] = id
        MapSettings.load_json(data, request.user.username)
        return {"status": True}

    @view(url=r"^(?P<id>[0-9a-f]{24})/info/segment/$",
          method=["GET"],
          access="read",
          api=True)
    def api_info_segment(self, request, id):
        segment = self.get_object_or_404(NetworkSegment, id=id)
        r = {
            "name": segment.name,
            "description": segment.description,
            "objects": segment.managed_objects.count(),
        }
        return r

    @view(
        url=r"^(?P<id>[0-9a-f]{24})/info/managedobject/(?P<mo_id>\d+)/$",
        method=["GET"],
        access="read",
        api=True,
    )
    def api_info_managedobject(self, request, id, mo_id):
        segment = self.get_object_or_404(NetworkSegment, id=id)
        object = self.get_object_or_404(ManagedObject, id=int(mo_id))
        s = {1: "telnet", 2: "ssh", 3: "http", 4: "https"}[object.scheme]
        r = {
            "id": object.id,
            "name": object.name,
            "description": object.description,
            "address": object.address,
            "platform": object.platform.full_name if object.platform else "",
            "profile": object.profile.name,
            "external": object.segment.id != segment.id,
            "external_segment": {
                "id": str(object.segment.id),
                "name": object.segment.name
            },
            "caps": object.get_caps(),
            "console_url": "%s://%s/" % (s, object.address),
        }
        return r

    @view(
        url=r"^(?P<id>[0-9a-f]{24})/info/link/(?P<link_id>[0-9a-f]{24})/$",
        method=["GET"],
        access="read",
        api=True,
    )
    def api_info_link(self, request, id, link_id):
        def q(s):
            if isinstance(s, str):
                s = s.encode("utf-8")
            return s

        self.get_object_or_404(NetworkSegment, id=id)
        link = self.get_object_or_404(Link, id=link_id)
        r = {
            "id": str(link.id),
            "name": link.name or None,
            "description": link.description or None,
            "objects": [],
            "method": link.discovery_method,
        }
        o = defaultdict(list)
        for i in link.interfaces:
            o[i.managed_object] += [i]
        for mo in sorted(o, key=lambda x: x.name):
            r["objects"] += [{
                "id":
                mo.id,
                "name":
                mo.name,
                "interfaces": [{
                    "name": i.name,
                    "description": i.description or None,
                    "status": i.status
                } for i in sorted(o[mo], key=lambda x: alnum_key(x.name))],
            }]
        # Get link bandwidth
        mo_in = defaultdict(float)
        mo_out = defaultdict(float)
        mos = [ManagedObject.get_by_id(mo["id"]) for mo in r["objects"]]
        metric_map, last_ts = get_interface_metrics(list(o))
        for mo in o:
            if mo not in metric_map:
                continue
            for i in o[mo]:
                if i.name not in metric_map[mo]:
                    continue
                mo_in[mo] += metric_map[mo][i.name]["Interface | Load | In"]
                mo_out[mo] += metric_map[mo][i.name]["Interface | Load | Out"]
        if len(mos) == 2:
            mo1, mo2 = mos
            r["utilisation"] = [
                int(max(mo_in[mo1], mo_out[mo2])),
                int(max(mo_in[mo2], mo_out[mo1])),
            ]
        else:
            mv = list(mo_in.values()) + list(mo_out.values())
            if mv:
                r["utilisation"] = [int(max(mv))]
            else:
                r["utilisation"] = 0
        return r

    @view(
        url=r"^(?P<id>[0-9a-f]{24})/info/cloud/(?P<link_id>[0-9a-f]{24})/$",
        method=["GET"],
        access="read",
        api=True,
    )
    def api_info_cloud(self, request, id, link_id):
        self.get_object_or_404(NetworkSegment, id=id)
        link = self.get_object_or_404(Link, id=link_id)
        r = {
            "id": str(link.id),
            "name": link.name or None,
            "description": link.description or None,
            "objects": [],
            "method": link.discovery_method,
        }
        o = defaultdict(list)
        for i in link.interfaces:
            o[i.managed_object] += [i]
        for mo in sorted(o, key=lambda x: x.name):
            r["objects"] += [{
                "id":
                mo.id,
                "name":
                mo.name,
                "interfaces": [{
                    "name": i.name,
                    "description": i.description or None,
                    "status": i.status
                } for i in sorted(o[mo], key=lambda x: alnum_key(x.name))],
            }]
        return r

    @view(
        url=r"^objects_statuses/$",
        method=["POST"],
        access="read",
        api=True,
        validate={"objects": ListOfParameter(IntParameter())},
    )
    def api_objects_statuses(self, request, objects: List[int]):
        def get_alarms(objects: List[int]) -> Set[int]:
            """
            Returns a set of objects with alarms
            """
            alarms: Set[int] = set()
            coll = ActiveAlarm._get_collection()
            while objects:
                chunk, objects = objects[:500], objects[500:]
                a = coll.aggregate([
                    {
                        "$match": {
                            "managed_object": {
                                "$in": chunk
                            }
                        }
                    },
                    {
                        "$group": {
                            "_id": "$managed_object",
                            "count": {
                                "$sum": 1
                            }
                        }
                    },
                ])
                alarms.update(d["_id"] for d in a)
            return alarms

        def get_maintenance(objects: List[int]) -> Set[int]:
            """
            Returns a set of objects currently in maintenance
            :param objects:
            :return:
            """
            now = datetime.datetime.now()
            so = set(objects)
            mnt_objects = set()
            pipeline = [
                {
                    "$match": {
                        "affected_objects.object": {
                            "$in": list(so)
                        }
                    }
                },
                {
                    "$unwind": "$affected_objects"
                },
                {
                    "$lookup": {
                        "from":
                        "noc.maintenance",
                        "as":
                        "m",
                        "let": {
                            "maintenance": "_id"
                        },
                        "pipeline": [{
                            "$match": {
                                "m.is_completed": False,
                                "m.start": {
                                    "$lte": now
                                },
                                "m.stop": {
                                    "gte": now
                                },
                            },
                        }],
                    },
                },
                {
                    "$project": {
                        "_id": 0,
                        "object": "$affected_objects.object",
                    }
                },
                {
                    "$group": {
                        "_id": "$object"
                    }
                },
            ]
            mnt_objects |= so & {
                x["_id"]
                for x in AffectedObjects._get_collection().aggregate(pipeline)
            }
            return mnt_objects

        # Mark all as unknown
        r = {o: self.ST_UNKNOWN for o in objects}
        sr = ObjectStatus.get_statuses(objects)
        sa = get_alarms(objects)
        mo = get_maintenance(objects)
        for o in sr:
            if sr[o]:
                # Check for alarms
                if o in sa:
                    r[o] = self.ST_ALARM
                else:
                    r[o] = self.ST_OK
            else:
                r[o] = self.ST_DOWN
            if o in mo:
                r[o] |= self.ST_MAINTENANCE
        return r

    @classmethod
    @cachedmethod(key="managedobject-name-to-id-%s", lock=lambda _: tags_lock)
    def managedobject_name_to_id(cls, name):
        r = ManagedObject.objects.filter(name=name).values_list("id")
        if r:
            return r[0][0]
        return None

    @classmethod
    @cachedmethod(key="interface-tags-to-id-%s-%s", lock=lambda _: tags_lock)
    def interface_tags_to_id(cls, object_name, interface_name):
        mo = cls.managedobject_name_to_id(object_name)
        i = Interface._get_collection().find_one({
            "managed_object": mo,
            "name": interface_name
        })
        if i:
            return i["_id"]
        return None

    @view(
        url=r"^metrics/$",
        method=["POST"],
        access="read",
        api=True,
        validate={
            "metrics":
            DictListParameter(
                attrs={
                    "id": StringParameter(),
                    "metric": StringParameter(),
                    "tags": DictParameter(),
                })
        },
    )
    def api_metrics(self, request, metrics):
        def q(s):
            if isinstance(s, str):
                s = s.encode("utf-8")
            return s

        def qt(t):
            return "|".join(["%s=%s" % (v, t[v]) for v in sorted(t)])

        # Build query
        tag_id = {}  # object, interface -> id
        if_ids = {}  # id -> port id
        mlst = []  # (metric, object, interface)
        for m in metrics:
            if "object" in m["tags"] and "interface" in m["tags"]:
                if not m["tags"]["object"]:
                    continue
                try:
                    if_ids[self.interface_tags_to_id(
                        m["tags"]["object"], m["tags"]["interface"])] = m["id"]
                    object = ManagedObject.objects.get(
                        name=m["tags"]["object"])
                    tag_id[object, m["tags"]["interface"]] = m["id"]
                    mlst += [(m["metric"], object, m["tags"]["interface"])]
                except KeyError:
                    pass
        # @todo: Get last values from cache
        if not mlst:
            return {}

        r = {}
        # Apply interface statuses
        for d in Interface._get_collection().find(
            {"_id": {
                "$in": list(if_ids)
            }}, {
                "_id": 1,
                "admin_status": 1,
                "oper_status": 1
            }):
            r[if_ids[d["_id"]]] = {
                "admin_status": d.get("admin_status", True),
                "oper_status": d.get("oper_status", True),
            }
        metric_map, last_ts = get_interface_metrics([m[1] for m in mlst])
        # Apply metrics
        for rq_mo, rq_iface in tag_id:
            pid = tag_id.get((rq_mo, rq_iface))
            if not pid:
                continue
            if pid not in r:
                r[pid] = {}
            if rq_mo not in metric_map:
                continue
            if rq_iface not in metric_map[rq_mo]:
                continue
            r[pid]["Interface | Load | In"] = metric_map[rq_mo][rq_iface][
                "Interface | Load | In"]
            r[pid]["Interface | Load | Out"] = metric_map[rq_mo][rq_iface][
                "Interface | Load | Out"]

        return r

    @view(r"^(?P<id>[0-9a-f]{24})/data/$",
          method=["DELETE"],
          access="write",
          api=True)
    def api_reset(self, request, id):
        self.get_object_or_404(NetworkSegment, id=id)
        MapSettings.objects.filter(segment=id).delete()
        return {"status": True}

    @view(
        url=r"^stp/status/$",
        method=["POST"],
        access="read",
        api=True,
        validate={"objects": ListOfParameter(IntParameter())},
    )
    def api_objects_stp_status(self, request, objects):
        def get_stp_status(object_id):
            roots = set()
            blocked = set()
            object = ManagedObject.get_by_id(object_id)
            sr = object.scripts.get_spanning_tree()
            for instance in sr["instances"]:
                ro = DiscoveryID.find_object(instance["root_id"])
                if ro:
                    roots.add(ro)
                for i in instance["interfaces"]:
                    if i["state"] == "discarding" and i["role"] == "alternate":
                        iface = object.get_interface(i["interface"])
                        if iface:
                            link = iface.link
                            if link:
                                blocked.add(str(link.id))
            return object_id, roots, blocked

        r = {"roots": [], "blocked": []}
        futures = []
        with ThreadPoolExecutor(max_workers=10) as executor:
            for o in objects:
                futures += [executor.submit(get_stp_status, o)]
            for future in as_completed(futures):
                try:
                    obj, roots, blocked = future.result()
                    for ro in roots:
                        if ro.id not in r["roots"]:
                            r["roots"] += [ro.id]
                    r["blocked"] += blocked
                except Exception as e:
                    self.logger.error("[stp] Exception: %s", e)
        return r
示例#12
0
from noc.core.datastream.decorator import datastream
from .authprofile import AuthProfile
from .capsprofile import CapsProfile


m_valid = DictListParameter(attrs={
    "metric_type": ObjectIdParameter(required=True),
    "enable_box": BooleanParameter(default=False),
    "enable_periodic": BooleanParameter(default=True),
    "is_stored": BooleanParameter(default=True),
    "window_type": StringParameter(
        choices=["m", "t"],
        default="m"),
    "window": IntParameter(default=1),
    "window_function": StringParameter(choices=[x[0] for x in wf_choices], default="last"),
    "window_config": StringParameter(default=""),
    "window_related": BooleanParameter(default=False),
    "low_error": IntParameter(required=False),
    "high_error": IntParameter(required=False),
    "low_warn": IntParameter(required=False),
    "high_warn": IntParameter(required=False),
    "low_error_weight": IntParameter(default=10),
    "low_warn_weight": IntParameter(default=1),
    "high_warn_weight": IntParameter(default=1),
    "high_error_weight": IntParameter(default=10),
    "threshold_profile": ObjectIdParameter(required=False)
})

id_lock = Lock()


@on_init
示例#13
0
文件: views.py 项目: fossabot/noc
class MetricSettingsApplication(ExtDocApplication):
    """
    MetricSettings application
    """
    title = "Metric Settings"
    model = MetricSettings

    @view("^(?P<model_id>[^/]+)/(?P<object_id>[^/]+)/settings/$",
          method=["GET"],
          access="read",
          api=True)
    def api_get_settings(self, request, model_id, object_id):
        o = MetricSettings.objects.filter(model_id=model_id,
                                          object_id=object_id).first()
        if o:
            return [{
                "metric_set": str(ms.metric_set.id),
                "metric_set__label": ms.metric_set.name,
                "is_active": ms.is_active
            } for ms in o.metric_sets]
        else:
            return []

    @view("^(?P<model_id>[^/]+)/(?P<object_id>[^/]+)/settings/$",
          method=["POST"],
          access="read",
          api=True,
          validate={
              "metric_sets":
              DictListParameter(
                  attrs={
                      "metric_set": DocumentParameter(MetricSet),
                      "is_active": BooleanParameter()
                  })
          })
    def api_save_settings(self, request, model_id, object_id, metric_sets):
        def save_settings(o):
            o.save()
            return self.response({"status": True}, self.OK)

        o = MetricSettings.objects.filter(model_id=model_id,
                                          object_id=object_id).first()
        seen = set()
        mset = []
        for ms in metric_sets:
            if ms["metric_set"].id in seen:
                continue
            mset += [
                MetricSettingsItem(metric_set=ms["metric_set"],
                                   is_active=ms["is_active"])
            ]
            seen.add(ms["metric_set"].id)
        if o:
            o.metric_sets = mset
        else:
            o = MetricSettings(model_id=model_id,
                               object_id=object_id,
                               metric_sets=mset)
        self.submit_slow_op(request, save_settings, o)

    @view("^(?P<model_id>[^/]+)/(?P<object_id>[^/]+)/effective/trace/$",
          method=["GET"],
          access="read",
          api=True)
    def api_trace_effective(self, request, model_id, object_id):
        o = MetricSettings(model_id=model_id, object_id=object_id).get_object()
        if not o:
            return self.response_not_found()
        r = []
        for es in MetricSettings.get_effective_settings(o,
                                                        trace=True,
                                                        recursive=True):
            for m in es.metrics:
                r += [{
                    "metric": m.metric or None,
                    "metric_type": m.metric_type.name,
                    "is_active": es.is_active,
                    "probe": es.probe.name if es.probe else None,
                    "interval": es.interval if es.interval else None,
                    "thresholds": m.thresholds,
                    "handler": es.handler,
                    "config": es.config,
                    "errors": es.errors,
                    "traces": es.traces
                }]
        return r