示例#1
0
    def _create_object(self, spec, parent, share_with, metakeys):
        try:
            blobs = []
            config = dict(spec["cfg"])

            for first, second in config.items():
                if isinstance(second, dict) and list(second.keys()) == ["in-blob"]:
                    if not g.auth_user.has_rights(Capabilities.adding_blobs):
                        raise Forbidden("You are not permitted to add blob objects")
                    blob_obj = self._get_embedded_blob(second["in-blob"], share_with, metakeys)
                    config[first]["in-blob"] = blob_obj.dhash
                    blobs.append(blob_obj)
                elif isinstance(second, dict) and ("in-blob" in list(second.keys())):
                    raise BadRequest("'in-blob' should be the only key")

            obj, is_new = Config.get_or_create(
                config,
                spec["family"],
                spec["config_type"],
                parent=parent,
                share_with=share_with,
                metakeys=metakeys
            )

            for blob in blobs:
                blob.add_parent(obj, commit=False)

            return obj, is_new
        except ObjectTypeConflictError:
            raise Conflict("Object already exists and is not a config")
示例#2
0
def send_config_to_karton(cfg: Config) -> str:
    producer = Producer(identity="karton.mwdb",
                        config=KartonConfig(config.karton.config_path))

    task = Task(headers={
        "type": "config",
        "kind": cfg.config_type,
        "family": cfg.family
    },
                payload={
                    "config":
                    cfg.cfg,
                    "dhash":
                    cfg.dhash,
                    "attributes":
                    cfg.get_metakeys(as_dict=True, check_permissions=False)
                })
    producer.send_task(task)
    cfg.add_metakey("karton", task.root_uid, check_permissions=False)
    logger.info("Configuration sent to karton with %s", task.root_uid)
    return task.root_uid
示例#3
0
    def post(self, remote_name, identifier):
        """
        ---
        summary: Push config from local to remote instance
        description: |
            Push config from the local instance to the remote instance
        security:
            - bearerAuth: []
        tags:
            - remotes
        parameters:
            - in: path
              name: remote_name
              description: Name of remote instance
              schema:
                type: string
            - in: path
              name: identifier
              description: Object identifier (SHA256/SHA512/SHA1/MD5)
              schema:
                type: string
        requestBody:
            required: false
            description: Additional options for object push
            content:
              application/json:
                schema: RemoteOptionsRequestSchema
        responses:
            200:
                description: Information about pushed config
            404:
                description: |
                    When the name of the remote instance is not figured
                    in the application config or object doesn't exist
        """
        db_object = Config.access(identifier)
        if db_object is None:
            raise NotFound("Object not found")

        config = db_object.cfg
        # Extract in-blob references into embedded content
        for first, second in config.items():
            if isinstance(second, dict) and list(second.keys()) == ["in-blob"]:
                in_blob = second["in-blob"]
                if not isinstance(in_blob, str):
                    raise BadRequest(
                        "'in-blob' key doesn't contain a correct blob reference"
                    )
                embedded_blob = TextBlob.access(in_blob)
                if not embedded_blob:
                    raise NotFound(
                        f"Referenced blob '{in_blob}' doesn't exist")
                second["in-blob"] = {
                    "content": embedded_blob.content,
                    "blob_name": embedded_blob.blob_name,
                    "blob_type": embedded_blob.blob_type,
                }

        remote = RemoteAPI(remote_name)
        options = loads_schema(request.get_data(as_text=True),
                               RemoteOptionsRequestSchema())
        params = {
            "family": db_object.family,
            "cfg": config,
            "config_type": db_object.config_type,
            "upload_as": options["upload_as"],
        }
        response = remote.request("POST", "config", json=params).json()
        logger.info(
            f"{db_object.type} pushed remote",
            extra={
                "dhash": db_object.dhash,
                "remote_name": remote_name
            },
        )
        return response
示例#4
0
    def post(self, remote_name, identifier):
        """
        ---
        summary: Pulls config from remote to local instance
        description: |
            Pulls config from the remote instance to the local instance
        security:
            - bearerAuth: []
        tags:
            - remotes
        parameters:
            - in: path
              name: remote_name
              description: Name of remote instance
              schema:
                type: string
            - in: path
              name: identifier
              description: Config identifier
              schema:
                type: string
        requestBody:
            required: false
            description: Additional options for object pull
            content:
              application/json:
                schema: RemoteOptionsRequestSchema
        responses:
            200:
                description: Information about pulled config
                content:
                  application/json:
                    schema: ConfigItemResponseSchema
            403:
                description: |
                    No permissions to perform additional operations
                    (e.g. adding parent, metakeys)
            404:
                description: |
                    When the name of the remote instance is not figured
                    in the application config
            409:
                description: Object exists yet but has different type
        """
        remote = RemoteAPI(remote_name)
        config_spec = remote.request("GET", f"config/{identifier}").json()
        options = loads_schema(request.get_data(as_text=True),
                               RemoteOptionsRequestSchema())
        share_with = get_shares_for_upload(options["upload_as"])
        try:
            config = dict(config_spec["cfg"])
            blobs = []
            for first, second in config.items():
                if isinstance(second, dict) and list(
                        second.keys()) == ["in-blob"]:
                    if not g.auth_user.has_rights(Capabilities.adding_blobs):
                        raise Forbidden(
                            "You are not permitted to add blob objects")
                    in_blob = second["in-blob"]
                    if not isinstance(in_blob, str):
                        raise BadRequest(
                            "'in-blob' is not a correct blob reference")
                    blob_obj = TextBlob.access(in_blob)
                    if not blob_obj:
                        # If blob object doesn't exist locally: pull it as well
                        blob_spec = remote.request("GET",
                                                   f"blob/{in_blob}").json()
                        blob_obj, _ = TextBlob.get_or_create(
                            content=blob_spec["content"],
                            blob_name=blob_spec["blob_name"],
                            blob_type=blob_spec["blob_type"],
                            share_with=share_with,
                        )
                    blobs.append(blob_obj)
                    config[first]["in-blob"] = blob_obj.dhash

                elif isinstance(second, dict) and ("in-blob" in list(
                        second.keys())):
                    raise BadRequest("'in-blob' should be the only key")

            item, is_new = Config.get_or_create(
                cfg=config_spec["cfg"],
                family=config_spec["family"],
                config_type=config_spec["config_type"],
                share_with=share_with,
            )

            for blob in blobs:
                blob.add_parent(item, commit=False)
        except ObjectTypeConflictError:
            raise Conflict("Object already exists and is not a config")

        return self.create_pulled_object(item, is_new)
示例#5
0
 def on_created_config(self, cfg: Config) -> None:
     metakeys = cfg.get_metakeys(as_dict=True, check_permissions=False)
     if "karton" in metakeys:
         logger.info("Analyzed artifact - not sending to karton")
         return
     send_config_to_karton(cfg)