def close(self): if not self._hints[0]: return # Not open open_sync_rpc("activator", pool=self._pool, calling_service=CALLING_SERVICE, hints=self._hints).close_session(self._id)
def check_login(self, user, password, super_password): self.logger.debug("Checking %s/%s/%s", user, password, super_password) self.logger.info( "Checking %s/%s/%s", safe_shadow(user), safe_shadow(password), safe_shadow(super_password), ) try: r = open_sync_rpc( "activator", pool=self.object.pool.name, calling_service="discovery").script( "%s.login" % self.object.profile.name, { "cli_protocol": "ssh" if self.object.scheme == SSH else "telnet", "address": self.object.address, "user": user, "password": password, "super_password": super_password, "path": None, "raise_privileges": self.object.to_raise_privileges, "access_preference": self.object.get_access_preference(), }, ) self.logger.info("Result: %s, %s", r, r["message"]) return bool(r["result"]), r["message"] # bool(False) == bool(None) except RPCError as e: self.logger.debug("RPC Error: %s", e) return False, ""
def api_upload(self, request): left = {} # name -> data for f in request.FILES: left[f] = request.FILES[f] errors = {} while len(left): n = len(left) for name in left.keys(): try: svc = open_sync_rpc("mib") r = svc.compile(left[name].read()) if r.get("status"): del left[name] if name in errors: del errors[name] else: errors[name] = r["msg"] except RPCError as e: errors[name] = str(e) if len(left) == n: # Failed to upload anything, stopping break r = { "success": len(left) == 0, "errors": errors } return r
def __call__(self, name, args, timeout=None): # Call SAE for credentials data = open_sync_rpc("sae", calling_service=CALLING_SERVICE).get_credentials( self._object_id) self._pool = data["pool"] # Get activator hints self._get_hints() # Call activator return open_sync_rpc("activator", pool=data["pool"], calling_service=CALLING_SERVICE, hints=self._hints).script( "%s.%s" % (data["profile"], name), data["credentials"], data["capabilities"], data["version"], args, timeout, self._id, self._idle_timeout)
def api_text(self, request, id): mib = self.get_object_or_404(MIB, id=id) try: svc = open_sync_rpc("mib") r = svc.get_text(mib.name) if r.get("status"): return r["data"] except RPCError: pass return ""
def handle(self, rpc, arguments, pretty, hints, *args, **options): service, method = rpc[0].split(".", 1) try: client = open_sync_rpc(service, calling_service="cli", hints=hints) method = getattr(client, method) result = method(*arguments) except RPCError as e: self.die("RPC Error: %s" % e) if pretty: self.stdout.write(pprint.pformat(result) + "\n") else: self.stdout.write(str(result) + "\n")
def check_https_get(self, param): """ Perform HTTPS GET check. Param can be URL path or :<port>/<path> """ url = "https://%s%s" % (self.object.address, param) try: return open_sync_rpc("activator", pool=self.object.pool.name, calling_service="discovery").http_get(url) except RPCError as e: self.logger.error("RPC Error: %s", e) return None
def http_get(self, url): """ Perform HTTP request. May be overridden for testing :param url: Request URL :return: """ self.logger.info("HTTP Request: %s", url) try: return open_sync_rpc( "activator", pool=self.pool, calling_service=self.calling_service ).http_get(url, True) except RPCError as e: self.logger.error("RPC Error: %s", e) return None
def snmp_v2c_get(self, param): """ Perform SNMP v2c request. May be overridden for testing :param param: :return: """ self.logger.info("SNMP v2c GET: %s", param) try: return open_sync_rpc( "activator", pool=self.pool, calling_service=self.calling_service ).snmp_v2c_get(self.address, self.snmp_community, param) except RPCError as e: self.logger.error("RPC Error: %s", e) return None
def __call__(self, **kwargs): smap = getattr(SessionContext._sessions, "smap", None) if smap: session = smap.get(self.object_id) if session: # Session call return session(self.name, kwargs) # Direct call return open_sync_rpc( "sae", calling_service=config.script.calling_service).script( self.object_id, self.name, kwargs, None # params # timeout )
def check_oid(self, oid, community, version="snmp_v2c_get"): """ Perform SNMP v2c GET. Param is OID or symbolic name """ self.logger.info("Trying community '%s': %s, version: %s", community, oid, version) try: r = open_sync_rpc( "activator", pool=self.object.pool.name, calling_service="discovery").__getattr__(version)( self.object.address, community, oid) self.logger.info("Result: %s", r) return r is not None except RPCError as e: self.logger.debug("RPC Error: %s", e) return False
def api_change_credentials(self, request): """ Change user's credentials if allowed by current backend """ credentials = dict((str(k), v) for k, v in six.iteritems(request.POST)) credentials["user"] = request.user.username client = open_sync_rpc("login", calling_service="web") try: r = client.change_credentials(credentials) except RPCError as e: return self.render_json({"status": False, "error": str(e)}) if r: return self.render_json({"status": True}) else: return self.render_json({ "status": False, "error": _("Failed to change credentials") })
def check_snmp_v2c_get(self, param): """ Perform SNMP v2c GET. Param is OID or symbolic name """ if hasattr(self.object, "_suggest_snmp") and self.object._suggest_snmp: # Use guessed community # as defined one may be invalid snmp_ro = self.object._suggest_snmp[0] if not self.snmp_version_def: self.snmp_version_def = self.object._suggest_snmp[2] else: # @todo caps for version snmp_ro = self.object.credentials.snmp_ro if not self.snmp_version_def: self.snmp_version_def = "snmp_v2c_get" caps = self.object.get_caps() if caps.get("SNMP | v2c") is False: self.snmp_version_def = "snmp_v1_get" if not snmp_ro: self.logger.error("No SNMP credentials. Ignoring") raise NOCError(msg="No SNMP credentials") try: param = mib[param] except KeyError: self.logger.error("Cannot resolve OID '%s'. Ignoring", param) return None self.logger.info("Use %s for request", self.snmp_version_def) try: return open_sync_rpc("activator", pool=self.object.pool.name, calling_service="discovery").__getattr__( self.snmp_version_def)( self.object.address, snmp_ro, param) except RPCError as e: self.logger.error("RPC Error: %s", e) return None
class Command(BaseCommand): help = "MIB manipulation tool" rx_oid = re.compile(r"^\d+(\.\d+)+") svc = open_sync_rpc("mib") def add_arguments(self, parser): parser.add_argument("--local", action="store_true", help="Not use mib service for import") subparsers = parser.add_subparsers(dest="cmd") # get get_parser = subparsers.add_parser("get") get_parser.add_argument("oids", nargs=argparse.REMAINDER, help="SNMP OIDs") # lookup lookup_parser = subparsers.add_parser("lookup") lookup_parser.add_argument("oids", nargs=argparse.REMAINDER, help="SNMP OIDs") # Make collection-ready MIB make_collection_parser = subparsers.add_parser("make-collection") make_collection_parser.add_argument("-o", "--output", dest="output", default="") make_collection_parser.add_argument("-b", "--bump", dest="bump", action="store_true", default=False) make_collection_parser.add_argument(dest="mib_name", nargs=1, help="MIB Name") # Make cmib "Make compiled MIB for SA and PM scripts" make_cmib_parser = subparsers.add_parser("make-cmib") make_cmib_parser.add_argument("-o", "--output", dest="output", default="") make_cmib_parser.add_argument(dest="mib_name", nargs=1, help="MIB Name") # import import_parser = subparsers.add_parser("import") import_parser.add_argument("paths", nargs=argparse.REMAINDER, help="Path to MIB files") def handle(self, cmd, *args, **options): if options.get("local"): self.svc = MIBAPI(ServiceStub(), None, None) connect() return getattr(self, "handle_%s" % cmd.replace("-", "_"))(*args, **options) def handle_lookup(self, oids, *args, **kwargs): for oid in oids: self.lookup_mib(oid) def lookup_mib(self, v): try: r = self.svc.lookup(v) if r.get("status"): self.print("%s = %s" % (r["name"], r["oid"])) else: self.print("%s: Not found" % v) except RPCError as e: self.die("RPC Error: %s" % e) def handle_get(self, oids, *args, **kwargs): for oid in oids: self.get_mib(oid) def get_mib(self, v): try: r = self.svc.get_text(v) if r.get("status"): self.print(r["data"]) else: self.print("%s: Not found" % v) except RPCError as e: self.die("RPC Error: %s" % e) @contextlib.contextmanager def open_output(self, path=None): """ Context manager for output writer :param path: :return: """ if path: self.prepare_dirs(path) self.print("Writing to file %s" % path) if os.path.splitext(path)[-1] == ".gz": with gzip.GzipFile(path, "w") as f: yield lambda x: f.write(smart_bytes(x)) else: with open(path, "w") as f: yield lambda x: f.write(x) else: self.print("Dumping to stdout") yield self.print def handle_make_collection(self, mib_name, bump=False, *args, **kwargs): if len(mib_name) != 1: self.print("Specify one MIB") self.die("") # Get MIB mib = MIB.get_by_name(mib_name[0]) if not mib: self.print("MIB not found: %s" % mib_name[0]) self.die("") # Prepare MIB data mib_data = list( sorted( [{ "oid": dd.oid, "name": dd.name, "description": dd.description, "syntax": dd.syntax, } for dd in MIBData.objects.filter(mib=mib.id)] + [{ "oid": dd.oid, "name": next((a for a in dd.aliases if a.startswith(mib.name + "::"))), "description": dd.description, "syntax": dd.syntax, } for dd in MIBData.objects.filter(aliases__startswith="%s::" % mib.name)], key=lambda x: x["oid"], )) # Prepare MIB if mib.last_updated: last_updated = mib.last_updated.strftime("%Y-%m-%d") else: last_updated = "1970-01-01" version = mib.version if bump: # Bump to next version version += 1 data = { "name": mib.name, "description": mib.description, "last_updated": last_updated, "version": version, "depends_on": mib.depends_on, "typedefs": mib.typedefs, "data": mib_data, } # Serialize and write with self.open_output(kwargs.get("output")) as f: f(ujson.dumps(data)) def handle_make_cmib(self, mib_name, *args, **kwargs): if len(mib_name) != 1: self.print("Specify one MIB") self.die("") # Get MIB mib = MIB.get_by_name(mib_name[0]) if not mib: self.print("MIB not found: %s" % mib_name[0]) self.die("") # Build cmib year = datetime.date.today().year r = [ "# -*- coding: utf-8 -*-", "# ----------------------------------------------------------------------", "# %s" % mib, "# Compiled MIB", "# Do not modify this file directly", "# Run ./noc mib make-cmib instead", "# ----------------------------------------------------------------------", "# Copyright (C) 2007-%s The NOC Project" % year, "# See LICENSE for details", "# ----------------------------------------------------------------------", "", "# MIB Name", 'NAME = "%s"' % mib, "", "# Metadata", 'LAST_UPDATED = "%s"' % mib.last_updated.isoformat().split("T")[0], 'COMPILED = "%s"' % datetime.date.today().isoformat(), "", "# MIB Data: name -> oid", "MIB = {", ] r += [ ",\n".join(' "%s": "%s"' % (md.name, md.oid) for md in sorted( MIBData.objects.filter(mib=mib.id), key=lambda x: [int(y) for y in x.oid.split(".")], )) ] r[-1] += "," r += ["}", ""] data = "\n".join(r) + "\n" with self.open_output(kwargs.get("output")) as f: f(data) def prepare_dirs(self, path): d = os.path.dirname(path) if not os.path.isdir(d): self.print("Creating directory %s", d) os.makedirs(d) def handle_import(self, paths, *args, **kwargs): left_paths = paths while left_paths: done = set() for p in left_paths: if self.upload_mib(p, **kwargs): done.add(p) if not done: # Cannot load additional mibs self.die("Cannot load MIBs: %s" % ", ".join(left_paths)) left_paths = [x for x in left_paths if x not in done] def upload_mib(self, path, local=False): """ Upload mib from file :param path: :param local: :return: """ with open(path, "rb") as f: data = f.read() try: r = self.svc.compile(data) if r.get("status"): return True if r.get("code") == ERR_MIB_MISSED: self.print("Cannot upload %s: MIB Missed - %s" % (path, r.get("msg"))) return False self.die("Cannot upload %s: %s" % (path, r.get("msg"))) except RPCError as e: self.die("RPC Error: %s" % e)
class Command(BaseCommand): help = "MIB manipulation tool" rx_oid = re.compile("^\d+(\.\d+)+") svc = open_sync_rpc("mib") def add_arguments(self, parser): parser.add_argument("--local", action="store_false", help="Not use mib service for import") subparsers = parser.add_subparsers(dest="cmd") # get get_parser = subparsers.add_parser("get") get_parser.add_argument("oids", nargs=argparse.REMAINDER, help="SNMP OIDs") # lookup lookup_parser = subparsers.add_parser("lookup") lookup_parser.add_argument("oids", nargs=argparse.REMAINDER, help="SNMP OIDs") # Make cmib "Make compiled MIB for SA and PM scripts" make_cmib_parser = subparsers.add_parser("make_cmib") make_cmib_parser.add_argument("-o", "--output", dest="output", default="") make_cmib_parser.add_argument("oids", nargs=argparse.REMAINDER, help="SNMP OIDs") # import import_parser = subparsers.add_parser("import") import_parser.add_argument("paths", nargs=argparse.REMAINDER, help="Path to MIB files") def handle(self, cmd, *args, **options): if options.get("local"): self.svc = MIBAPI(ServiceStub(), None, None) connect() return getattr(self, "handle_%s" % cmd)(*args, **options) def handle_lookup(self, oids, *args, **kwargs): for oid in oids: self.lookup_mib(oid) def lookup_mib(self, v): try: r = self.svc.lookup(v) if r.get("status"): self.print("%s = %s" % (r["name"], r["oid"])) else: self.print("%s: Not found" % v) except RPCError as e: self.die("RPC Error: %s" % e) def handle_get(self, oids, *args, **kwargs): for oid in oids: self.get_mib(oid) def get_mib(self, v): try: r = self.svc.get_text(v) if r.get("status"): self.print(r["data"]) else: self.print("%s: Not found" % v) except RPCError as e: self.die("RPC Error: %s" % e) def handle_make_cmib(self, oids, *args, **kwargs): if len(oids) != 1: self.stdout.write("Specify one MIB\n") self.die("") if kwargs["output"]: self.prepare_dirs(kwargs["output"]) self.print("Opening file %s", kwargs["output"]) f = open(kwargs["output"], "w") f = f.write else: self.print("Dumping to stdout") f = self.print mib = oids[0] try: m = MIB.objects.get(name=mib) except MIB.DoesNotExist: self.stdout.write("MIB not found: %s\n" % mib) self.die("") year = datetime.date.today().year r = [ "# -*- coding: utf-8 -*-", "# ----------------------------------------------------------------------", "# %s" % mib, "# Compiled MIB", "# Do not modify this file directly", "# Run ./noc mib make-cmib instead", "# ----------------------------------------------------------------------", "# Copyright (C) 2007-%s The NOC Project" % year, "# See LICENSE for details", "# ----------------------------------------------------------------------", "", "# MIB Name", 'NAME = "%s"' % mib, "", "# Metadata", 'LAST_UPDATED = "%s"' % m.last_updated.isoformat().split("T")[0], 'COMPILED = "%s"' % datetime.date.today().isoformat(), "", "# MIB Data: name -> oid", "MIB = {", ] rr = [] for md in sorted(MIBData.objects.filter(mib=m.id), key=lambda x: [int(y) for y in x.oid.split(".")]): rr += [' "%s": "%s"' % (md.name, md.oid)] r += [",\n".join(rr) + ","] r += ["}", ""] data = "\n".join(r) f(data) def prepare_dirs(self, path): d = os.path.dirname(path) if not os.path.isdir(d): self.print("Creating directory %s", d) os.makedirs(d) def handle_import(self, paths, *args, **kwargs): left_paths = paths while left_paths: done = set() for p in left_paths: if self.upload_mib(p, **kwargs): done.add(p) if not done: # Cannot load additional mibs self.die("Cannot load MIBs: %s" % ", ".join(left_paths)) left_paths = [x for x in left_paths if x not in done] def upload_mib(self, path, local=False): """ Upload mib from file :param path: :param local: :return: """ with open(path) as f: data = f.read() try: r = self.svc.compile(data) if r.get("status"): return True if r.get("code") == ERR_MIB_MISSED: return False self.die("Cannot upload %s: %s" % (path, r.get("msg"))) except RPCError as e: self.die("RPC Error: %s" % e)