Пример #1
0
 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)
Пример #2
0
 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, ""
Пример #3
0
 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
Пример #4
0
 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)
Пример #5
0
 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 ""
Пример #6
0
 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")
Пример #7
0
 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
Пример #8
0
 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
Пример #9
0
 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
Пример #10
0
 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
         )
Пример #11
0
 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
Пример #12
0
 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")
         })
Пример #13
0
 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
Пример #14
0
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)
Пример #15
0
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)