Example #1
0
 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 = thr.rbac_create_data(options.data, **kwargs)
     if errors:
         raise HTTP(403, errors)
Example #2
0
    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, thr=thr, **kwargs)
            if errors:
                raise 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)
Example #3
0
    def action(self, nodename, thr=None, **kwargs):
        options = self.parse_options(kwargs)
        data = {}
        if options.catalog == "collector":
            if shared.NODE.collector_env.dbopensvc is None:
                raise HTTP(400, "This node is not registered on a collector")
            data = []
            options = {
                "limit": 0,
                "props": "id,tpl_name,tpl_author,tpl_comment",
                "orderby": "tpl_name",
            }

            for tpl in shared.NODE.collector_rest_get("/provisioning_templates", options)["data"]:
                data.append({
                    "id": tpl["id"],
                    "name": tpl["tpl_name"],
                    "desc": tpl["tpl_comment"],
                    "author": tpl["tpl_author"],
                    "catalog": "collector",
                })
        else:
            raise HTTP(400, "unknown catalog %s" % options.catalog)
        return data
Example #4
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 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],
     })
Example #5
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 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 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 = __import__(kind + "mgr_parser")
        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 = rcEnv.python_cmd + [
            os.path.join(rcEnv.paths.pathlib, kind + "mgr.py"), "-s",
            options.path
        ] + cmd
        thr.log_request("run '%s'" % " ".join(fullcmd), 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:
            proc = Popen(fullcmd, stdin=None, close_fds=True)
            thr.push_proc(proc)
            result = {
                "status": 0,
                "info": "started %s action %s" % (options.path, " ".join(cmd)),
            }
        return result