예제 #1
0
 def action(self, nodename, thr=None, **kwargs):
     options = self.parse_options(kwargs)
     if options.catalog == "collector":
         if options.template is None:
             raise ex.HTTP(400, "template is not set")
         request_options = {"props": "tpl_definition"}
         try:
             data = shared.NODE.collector_rest_get(
                 "/provisioning_templates/%s" % options.template,
                 request_options)
             return data["data"][0]["tpl_definition"]
         except IndexError:
             raise ex.HTTP(404, "template not found")
     raise ex.HTTP(400, "unknown catalog %s" % options.catalog)
예제 #2
0
파일: post.py 프로젝트: sherlant/opensvc
 def action(self, nodename, thr=None, **kwargs):
     lock_id = self.lock_acquire(Env.nodename, "join", 30, thr=thr)
     if not lock_id:
         raise ex.HTTP(503, "Lock not acquired")
     with shared.JOIN_LOCK:
         data = self.join(nodename, thr=thr, **kwargs)
     self.lock_release("join", lock_id, thr=thr)
     return data
예제 #3
0
 def action(self, nodename, thr=None, **kwargs):
     options = self.parse_options(kwargs)
     cf = "/etc/drbd.d/%s.res" % options.res
     if not os.path.exists(cf):
         raise ex.HTTP(404, "resource configuration file does not exist")
     with open(cf, "r") as f:
         buff = f.read()
     return {"data": buff}
예제 #4
0
파일: get.py 프로젝트: sherlant/opensvc
 def action(self, nodename, thr=None, stream_id=None, **kwargs):
     options = self.parse_options(kwargs)
     svc = thr.get_service(options.path)
     if svc is None:
         raise ex.HTTP(404, "%s not found" % options.path)
     logfile = os.path.join(svc.log_d, svc.name + ".log")
     ofile = thr._action_logs_open(logfile, options.backlog, svc.path)
     return thr.read_file_lines(ofile)
예제 #5
0
파일: get.py 프로젝트: sherlant/opensvc
 def action(self, nodename, thr=None, **kwargs):
     options = self.parse_options(kwargs)
     if options.kind == "node":
         obj = shared.NODE
     elif options.kind:
         obj = factory(options.kind)(name="dummy", node=shared.NODE, volatile=True)
     else:
         raise ex.HTTP(400, "A kind must be specified.")
     return obj.full_kwstore.dump()
예제 #6
0
 def options_path(options, required=True):
     for key in ("path", "svcpath", "svcname"):
         try:
             return options[key]
         except KeyError:
             pass
     if required:
         raise ex.HTTP(400, "required option path is not set")
     return None
예제 #7
0
파일: post.py 프로젝트: sherlant/opensvc
 def rbac(self, nodename, thr=None, **kwargs):
     options = self.parse_options(kwargs)
     if options.template is not None:
         thr.rbac_requires(roles=["admin"], namespaces=[options.namespace], **kwargs)
         return
     if not options.data:
         return
     errors = self.rbac_create_data(payload=options.data, thr=thr, **kwargs)
     if errors:
         raise ex.HTTP(403, errors)
예제 #8
0
 def get_option(data, opt):
     name = opt["name"]
     fmt = opt.get("format", "string")
     required = opt.get("required", False)
     if fmt != "object_path" and required and name not in data:
         raise ex.HTTP(400, "required option %s is not set" % name)
     value = data.get(name, opt.get("default"))
     if value is None:
         value = opt.get("default")
     try:
         value = getattr(utilities.converters, "convert_" + fmt)(value)
     except AttributeError:
         pass
     except Exception as exc:
         raise ex.HTTP(
             400, "option %s format conversion to %s error: %s" %
             (name, fmt, exc))
     if fmt == "object_path":
         value = options_path(data, required=required)
     return name, value
예제 #9
0
파일: post.py 프로젝트: arnaudveron/opensvc
    def rbac(self, nodename, thr=None, **kwargs):
        options = self.parse_options(kwargs)
        name, namespace, kind = split_path(options.path)

        if options.action in GUEST_ACTIONS:
            role = "guest"
        elif options.action in OPERATOR_ACTIONS:
            role = "operator"
        elif options.action in ADMIN_ACTIONS:
            role = "admin"
        else:
            role = "root"

        if options.action == "set":
            # load current config
            try:
                cf = shared.SERVICES[options.path].print_config_data()
            except Exception as exc:
                cf = {}

            # purge unwanted sections
            try:
                del cf["metadata"]
            except Exception:
                pass

            # merge changes in current config
            for buff in options.options.get("kw", []):
                k, v = buff.split("=", 1)
                if k[-1] in ("+", "-"):
                    k = k[:-1]
                k = k.strip()
                try:
                    s, k = k.split(".", 1)
                except Exception:
                    s = "DEFAULT"
                if s not in cf:
                    cf[s] = {}
                cf[s][k] = v

            # apply object create rbac to the amended config
            payload = {options.path: cf}
            errors = self.rbac_create_data(payload=payload, thr=thr, **kwargs)
            if errors:
                raise ex.HTTP(403, errors)
        else:
            thr.rbac_requires(roles=[role], namespaces=[namespace], **kwargs)

        if options.cmd:
            # compat, requires root
            kwargs["roles"] = ["root"]
            thr.rbac_requires(**kwargs)
예제 #10
0
파일: get.py 프로젝트: sherlant/opensvc
 def action(self, nodename, thr=None, **kwargs):
     options = self.parse_options(kwargs)
     timeout = options.timeout if options.timeout and options.timeout < MAX_TIMEOUT else MAX_TIMEOUT
     if not which("gotty"):
         raise ex.HTTP(500, "The gotty executable is not installed")
     creds = "user:"******"private_key")
     cert_chain = os.path.join(Env.paths.certs, "certificate_chain")
     cmd = [
         "gotty",
         "--port",
         "0",
         "--random-url",
         "--tls",
         "--tls-crt",
         cert_chain,
         "--tls-key",
         private_key,
         "--timeout",
         str(timeout),
         "--once",
         "--ws-origin",
         ".*",
         "--permit-write",
         "om",
         options.path,
         "enter",
         "--rid",
         options.rid,
     ]
     env = dict(os.environ).update({
         "GOTTY_CREDENTIAL": creds,
     })
     proc = subprocess.Popen(cmd,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE,
                             env=env)
     thr.parent.push_proc(proc)
     for line in iter(proc.stderr.readline, ""):
         line = try_decode(line)
         if "https://" not in line:
             continue
         url = line.split("https://::", 1)[-1].strip()
         url = "https://" + creds + "@" + Env.nodename + url
         return {"data": {"url": url}}
예제 #11
0
 def action(self, nodename, thr=None, stream_id=None, **kwargs):
     options = self.parse_options(kwargs)
     svc = thr.get_service(options.path)
     if svc is None:
         raise ex.HTTP(404, "%s not found" % options.path)
     request_headers = HTTPHeaderMap(
         thr.streams[stream_id]["request"].headers)
     try:
         content_type = bdecode(request_headers.get("accept").pop())
     except:
         content_type = "application/json"
     thr.streams[stream_id]["content_type"] = content_type
     logfile = os.path.join(svc.log_d, svc.name + ".log")
     ofile = thr._action_logs_open(logfile, 0, svc.path)
     thr.streams[stream_id]["pushers"].append({
         "o": self,
         "fn": "h2_push_logs",
         "args": [ofile, True],
     })
예제 #12
0
 def action(self, nodename, thr=None, **kwargs):
     if "node.x.drbdadm" not in capabilities:
         raise ex.Error("this node is not drbd capable")
     out, err, ret = justcall(["drbdadm", "dump"])
     if ret:
         raise ex.HTTP(500, err)
     minors = set()
     ports = set()
     for line in out.splitlines():
         m = re.match(RE_MINOR, line)
         if m is not None:
             minors.add(int(m.group(1)))
         m = re.match(RE_PORT, line)
         if m is not None:
             ports.add(int(m.group(1)))
     return {
         "minors": sorted(list(minors)),
         "ports": sorted(list(ports)),
     }
예제 #13
0
파일: post.py 프로젝트: arnaudveron/opensvc
    def action(self, nodename, thr=None, **kwargs):
        options = self.parse_options(kwargs)
        name, namespace, kind = split_path(options.path)

        if thr.get_service(options.path) is None and options.action not in ("create", "deploy"):
            thr.log_request("service action (%s not installed)" % options.path, nodename, lvl="warning", **kwargs)
            raise ex.HTTP(404, "%s not found" % options.path)
        if not options.action and not options.cmd:
            thr.log_request("service action (no action set)", nodename, lvl="error", **kwargs)
            raise ex.HTTP(400, "action not set")

        for opt in ("node", "daemon", "svcs", "service", "s", "parm_svcs", "local", "id"):
            if opt in options.options:
                del options.options[opt]
        for opt, ropt in (("jsonpath_filter", "filter"),):
            if opt in options.options:
                options.options[ropt] = options.options[opt]
                del options.options[opt]
        options.options["local"] = True
        pmod = importlib.import_module("commands.{kind}.parser".format(kind=kind))
        popt = pmod.OPT

        def find_opt(opt):
            for k, o in popt.items():
                if o.dest == opt:
                    return o
                if o.dest == "parm_" + opt:
                    return o

        if options.cmd:
            cmd = [options.cmd]
        else:
            cmd = [options.action]
            for opt, val in options.options.items():
                po = find_opt(opt)
                if po is None:
                    continue
                if val == po.default:
                    continue
                if val is None:
                    continue
                opt = po._long_opts[0] if po._long_opts else po._short_opts[0]
                if po.action == "append":
                    cmd += [opt + "=" + str(v) for v in val]
                elif po.action == "store_true" and val:
                    cmd.append(opt)
                elif po.action == "store_false" and not val:
                    cmd.append(opt)
                elif po.type == "string":
                    opt += "=" + val
                    cmd.append(opt)
                elif po.type == "integer":
                    opt += "=" + str(val)
                    cmd.append(opt)

        fullcmd = Env.om + ["svc", "-s", options.path] + cmd
        thr.log_request("run 'om %s %s'" % (options.path, " ".join(cmd)), nodename, **kwargs)
        if options.sync:
            proc = Popen(fullcmd, stdout=PIPE, stderr=PIPE, stdin=None, close_fds=True)
            out, err = proc.communicate()
            try:
                result = json.loads(out)
            except Exception:
                result = {
                    "status": 0,
                    "data": {
                        "out": bdecode(out),
                        "err": bdecode(err),
                        "ret": proc.returncode,
                    },
                }
        else:
            import uuid
            session_id = str(uuid.uuid4())
            env = {}
            env.update(os.environ)
            env["OSVC_PARENT_SESSION_UUID"] = session_id
            proc = Popen(fullcmd, stdin=None, close_fds=True, env=env)
            thr.push_proc(proc)
            result = {
                "status": 0,
                "data": {
                    "pid": proc.pid,
                    "session_id": session_id,
                },
                "info": "started %s action %s" % (options.path, " ".join(cmd)),
            }
        return result
예제 #14
0
    def action(self, nodename, thr=None, **kwargs):
        options = self.parse_options(kwargs)
        name, namespace, kind = split_path(options.path)

        if thr.get_service(options.path) is None and options.action not in (
                "create", "deploy"):
            thr.log_request("service action (%s not installed)" % options.path,
                            nodename,
                            lvl="warning",
                            **kwargs)
            raise ex.HTTP(404, "%s not found" % options.path)
        if not options.action and not options.cmd:
            thr.log_request("service action (no action set)",
                            nodename,
                            lvl="error",
                            **kwargs)
            raise ex.HTTP(400, "action not set")

        for opt in ("node", "daemon", "svcs", "service", "s", "parm_svcs",
                    "local", "id"):
            if opt in options.options:
                del options.options[opt]
        for opt, ropt in (("jsonpath_filter", "filter"), ):
            if opt in options.options:
                options.options[ropt] = options.options[opt]
                del options.options[opt]
        options.options["local"] = True

        if options.cmd:
            cmd = [options.cmd]
        else:
            pmod = importlib.import_module(
                "commands.{kind}.parser".format(kind=kind))
            cmd = get_action_args_from_parser(pmod.OPT, options.action,
                                              options)

        fullcmd = Env.om + ["svc", "-s", options.path] + cmd
        thr.log_request("run 'om %s %s'" % (options.path, " ".join(cmd)),
                        nodename, **kwargs)
        if options.sync:
            proc = Popen(fullcmd,
                         stdout=PIPE,
                         stderr=PIPE,
                         stdin=None,
                         close_fds=True)
            out, err = proc.communicate()
            try:
                result = json.loads(out)
            except Exception:
                result = {
                    "status": 0,
                    "data": {
                        "out": bdecode(out),
                        "err": bdecode(err),
                        "ret": proc.returncode,
                    },
                }
        else:
            import uuid
            session_id = str(uuid.uuid4())
            env = {}
            env.update(os.environ)
            env["OSVC_PARENT_SESSION_UUID"] = session_id
            proc = Popen(fullcmd, stdin=None, close_fds=True, env=env)
            thr.parent.push_proc(proc, cmd=fullcmd, session_id=session_id)
            result = {
                "status": 0,
                "data": {
                    "pid": proc.pid,
                    "session_id": session_id,
                },
                "info": "started %s action %s" % (options.path, " ".join(cmd)),
            }
        return result