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")
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")
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()