Example #1
0
 def get_caps(self):
     # name -> id map
     caps = dict(
         (self.CAPS_MAP[d["name"]], d["_id"])
         for d in Capability._get_collection().find({
             "name": {
                 "$in": list(self.CAPS_MAP)
             }
         }, {
             "_id": 1,
             "name": 1
         })
     )
     # object -> caps
     add_expr = dict(
         (c, {"$in": [caps[c], "$caps.capability"]})
         for c in caps
     )
     project_expr = dict((c, 1) for c in caps)
     project_expr["_id"] = 1
     return dict(
         (d["_id"], dict((x, d[x]) for x in d if x != "_id"))
         for d in ObjectCapabilities._get_collection().aggregate([
             {"$addFields": add_expr},
             {"$project": project_expr}
         ])
     )
Example #2
0
 def get_caps(self):
     # name -> id map
     caps = {
         self.CAPS_MAP[d["name"]]: d["_id"]
         for d in Capability._get_collection().find(
             {"name": {
                 "$in": list(self.CAPS_MAP)
             }}, {
                 "_id": 1,
                 "name": 1
             })
     }
     # object -> caps
     add_expr = {c: {"$in": [caps[c], "$caps.capability"]} for c in caps}
     project_expr = {c: 1 for c in caps}
     project_expr["_id"] = 1
     return {
         d["_id"]: {x: d[x]
                    for x in d if x != "_id"}
         for d in ObjectCapabilities._get_collection().aggregate(
             [{
                 "$addFields": add_expr
             }, {
                 "$project": project_expr
             }])
     }
Example #3
0
 def get_capabilities(cls, object):
     """
     Resolve object capabilities
     :param object: ManagedObject instance or id
     :return: dict of capability name -> current value
     """
     if hasattr(object, "id"):
         object = object.id
     caps = {}
     oc = ObjectCapabilities._get_collection().find_one({"_id": object})
     if oc:
         for c in oc["caps"]:
             cc = Capability.get_by_id(c["capability"])
             if cc:
                 caps[cc.name] = c.get("value")
     return caps
Example #4
0
    def update_capabilities(cls, object, caps, source):
        """
        Update stored capabilities
        :param object:
        :param caps:
        :param source:
        :return:
        """
        o_label = object
        if hasattr(object, "id"):
            o_label = object.name
            object = object.id
        o_label += "|%s" % source
        oc = ObjectCapabilities._get_collection().find_one({"_id": object}) or {}
        # Update existing capabilities
        new_caps = []
        seen = set()
        changed = False
        for ci in oc.get("caps", []):
            c = Capability.get_by_id(ci["capability"])
            cs = ci.get("source")
            cv = ci.get("value")
            if not c:
                logger.info("[%s] Removing unknown capability id %s", o_label, ci["capability"])
                continue
            cn = c.name
            seen.add(cn)
            if cs == source:
                if cn in caps:
                    if caps[cn] != cv:
                        logger.info(
                            "[%s] Changing capability %s: %s -> %s", o_label, cn, cv, caps[cn]
                        )
                        ci["value"] = caps[cn]
                        changed = True
                else:
                    logger.info("[%s] Removing capability %s", o_label, cn)
                    changed = True
                    continue
            elif cn in caps:
                logger.info(
                    "[%s] Not changing capability %s: " "Already set with source '%s'",
                    o_label,
                    cn,
                    cs,
                )
            new_caps += [ci]
        # Add new capabilities
        for cn in set(caps) - seen:
            c = Capability.get_by_name(cn)
            if not c:
                logger.info("[%s] Unknown capability %s, ignoring", o_label, cn)
                continue
            logger.info("[%s] Adding capability %s = %s", o_label, cn, caps[cn])
            new_caps += [{"capability": c.id, "value": caps[cn], "source": source}]
            changed = True

        if changed:
            logger.info("[%s] Saving changes", o_label)
            ObjectCapabilities._get_collection().update(
                {"_id": object}, {"$set": {"caps": new_caps}}, upsert=True
            )
            cache.delete("cred-%s" % object, version=CREDENTIAL_CACHE_VERSION)
        caps = {}
        for ci in new_caps:
            cn = Capability.get_by_id(ci["capability"])
            if cn:
                caps[cn.name] = ci.get("value")
        return caps