Example #1
0
File: beef.py Project: 0pt1on/noc
 def handle_collect(self, storage, path, spec, force, objects, *args,
                    **options):
     # Get spec data
     sp = Spec.get_by_name(spec)
     if not sp:
         self.die("Invalid spec: '%s'" % spec)
     # Spec data
     req = sp.get_spec_request()
     # Get effective list of managed objects
     mos = set()
     for ox in objects:
         for mo in ManagedObjectSelector.get_objects_from_expression(ox):
             mos.add(mo)
     # Collect beefs
     for mo in mos:
         self.print("Collecting beef from %s" % mo.name)
         if mo.profile.name != sp.profile.name:
             self.print("  Profile mismatch. Skipping")
             continue
         if mo.object_profile.beef_policy == "D" and not force:
             self.print("  Collection disabled by policy. Skipping")
             continue
         if not mo.object_profile.beef_storage and not storage:
             self.print("  Beef storage is not configured. Skipping")
             continue
         if not mo.object_profile.beef_path_template and not force:
             self.print("  Beef path template is not configured. Skipping")
             continue
         elif not mo.object_profile.beef_path_template and force:
             self.print(
                 "  Beef path template is not configured. But force set. Generate path"
             )
             path = self.DEFAULT_BEEF_PATH_TEMPLATE.format(mo)
         else:
             path = mo.object_profile.beef_path_template.render_subject(
                 object=mo, spec=sp, datetime=datetime)
         storage = mo.object_profile.beef_storage or self.get_storage(
             storage, beef=True)
         if not path:
             self.print("  Beef path is empty. Skipping")
             continue
         try:
             bdata = mo.scripts.get_beef(spec=req)
         except Exception as e:
             self.print("Failed collect beef on %s: %s" % (mo.name, e))
             continue
         beef = Beef.from_json(bdata)
         self.print("  Saving to %s:%s" % (storage.name, path))
         try:
             cdata, udata = beef.save(storage, path)
             if cdata == udata:
                 self.print("  %d bytes written" % cdata)
             else:
                 self.print(
                     "  %d bytes written (%d uncompressed. Ratio %.2f/1)" %
                     (cdata, udata, float(udata) / float(cdata)))
         except IOError as e:
             self.print("  Failed to save: %s" % e)
         self.print("  Done")
Example #2
0
File: beef.py Project: nbashev/noc
    def handle_collect(self,
                       storage,
                       path,
                       spec,
                       force,
                       objects,
                       description=None,
                       *args,
                       **options):
        connect()
        from noc.sa.models.managedobjectselector import ManagedObjectSelector
        from noc.dev.models.spec import Spec

        class FakeSpec(object):
            def __init__(self, name):
                self.name = name
                self.uuid = "4ec10fd8-3a33-4f23-b96e-91e3967c3b1b"

        # Get spec data
        if ":" in spec:
            path, file = smart_text(os.path.dirname(spec)), smart_text(
                os.path.basename(spec))
            spec_data = open_fs(path).open(file)
            sp = Spec.from_json(spec_data.read())
            sp.quiz = FakeSpec("Ad-Hoc")
            sp.profile = FakeSpec("Generic.Host")
        else:
            sp = Spec.get_by_name(spec)
        if not sp:
            self.die("Invalid spec: '%s'" % spec)
        # Spec data
        req = sp.get_spec_request()
        # Get effective list of managed objects
        mos = set()
        for ox in objects:
            for mo in ManagedObjectSelector.get_objects_from_expression(ox):
                mos.add(mo)
        # Collect beefs
        for mo in mos:
            self.print("Collecting beef from %s" % mo.name)
            if ":" in spec:
                sp.profile = mo.profile
            if mo.profile.name != sp.profile.name:
                self.print("  Profile mismatch. Skipping")
                continue
            if mo.object_profile.beef_policy == "D" and not force:
                self.print("  Collection disabled by policy. Skipping")
                continue
            if not mo.object_profile.beef_storage and not storage:
                self.print("  Beef storage is not configured. Skipping")
                continue
            if not mo.object_profile.beef_path_template and not force:
                self.print("  Beef path template is not configured. Skipping")
                continue
            elif not mo.object_profile.beef_path_template and force:
                self.print(
                    "  Beef path template is not configured. But force set. Generate path"
                )
                path = smart_text(self.DEFAULT_BEEF_PATH_TEMPLATE.format(mo))
            else:
                path = smart_text(
                    mo.object_profile.beef_path_template.render_subject(
                        object=mo, spec=sp, datetime=datetime))
            storage = mo.object_profile.beef_storage or self.get_storage(
                storage, beef=True)
            if not path:
                self.print("  Beef path is empty. Skipping")
                continue
            try:
                bdata = mo.scripts.get_beef(spec=req)
            except Exception as e:
                self.print("Failed collect beef on %s: %s" % (mo.name, e))
                continue
            beef = Beef.from_json(bdata)
            if description:
                beef.description = description
            self.print("  Saving to %s:%s" % (storage.name, path))
            try:
                cdata, udata = beef.save(storage, path)
                if cdata == udata:
                    self.print("  %d bytes written" % cdata)
                else:
                    self.print(
                        "  %d bytes written (%d uncompressed. Ratio %.2f/1)" %
                        (cdata, udata, float(udata) / float(cdata)))
            except IOError as e:
                self.print("  Failed to save: %s" % e)
            self.print("  Done")
Example #3
0
    def update_spec(self, name, script):
        """
        Update named spec
        :param name: Spec name
        :param script: BaseScript instance
        :return:
        """
        from noc.dev.models.quiz import Quiz
        from noc.dev.models.spec import Spec, SpecAnswer
        from noc.sa.models.profile import Profile

        self.print("Updating spec: %s" % name)
        spec = Spec.get_by_name(name)
        changed = False
        if not spec:
            self.print("   Spec not found. Creating")
            # Get Ad-Hoc quiz
            quiz = Quiz.get_by_name("Ad-Hoc")
            if not quiz:
                self.print("   'Ad-Hoc' quiz not found. Skipping")
                return
            # Create Ad-Hoc spec for profile
            spec = Spec(
                name,
                description="Auto-generated Ad-Hoc spec for %s profile" %
                script.profile.name,
                revision=1,
                quiz=quiz,
                author="NOC",
                profile=Profile.get_by_name(script.profile.name),
                changes=[],
                answers=[])
            changed = True
        # Fetch commands from spans
        cli_svc = {"beef_cli", "cli", "telnet", "ssh"}
        commands = set()
        for sd in get_spans():
            row = sd.split("\t")
            if row[6] not in cli_svc:
                continue
            commands.add(row[12].decode("string_escape").strip())
        # Update specs
        s_name = "cli_%s" % script.name.rsplit(".", 1)[-1]
        names = set()
        for ans in spec.answers:
            if ((ans.name == s_name or ans.name.startswith(s_name + "."))
                    and ans.type == "cli"):
                names.add(ans.name)
                if ans.value in commands:
                    # Already recorded
                    commands.remove(ans.value)
        if commands:
            # New commands left
            max_n = 0
            for n in names:
                if "." in n:
                    nn = int(n.rsplit(".", 1)[-1])
                    if nn > max_n:
                        max_n = nn
            #
            ntpl = "%s.%%d" % s_name
            for nn, cmd in enumerate(sorted(commands)):
                spec.answers += [
                    SpecAnswer(name=ntpl % (nn + 1), type="cli", value=cmd)
                ]
            changed = True
        if changed:
            spec.save()