示例#1
0
def delete_by_id(host_id_list):
    payload_tracker = get_payload_tracker(account=current_identity.account_number, request_id=threadctx.request_id)

    with PayloadTrackerContext(
        payload_tracker, received_status_message="delete operation", current_operation="delete"
    ):
        query = _get_host_list_by_id_list(current_identity.account_number, host_id_list)

        if not query.count():
            flask.abort(status.HTTP_404_NOT_FOUND)

        for host_id, deleted in delete_hosts(query, current_app.event_producer):
            if deleted:
                logger.info("Deleted host: %s", host_id)
                tracker_message = "deleted host"
            else:
                logger.info("Host %s already deleted. Delete event not emitted.", host_id)
                tracker_message = "not deleted host"

            with PayloadTrackerProcessingContext(
                payload_tracker, processing_status_message=tracker_message
            ) as payload_tracker_processing_ctx:
                payload_tracker_processing_ctx.inventory_id = host_id

    return flask.Response(None, status.HTTP_200_OK)
示例#2
0
def delete_by_id(host_id_list):
    current_identity = get_current_identity()
    payload_tracker = get_payload_tracker(
        account=current_identity.account_number,
        request_id=threadctx.request_id)

    with PayloadTrackerContext(payload_tracker,
                               received_status_message="delete operation",
                               current_operation="delete"):
        query = _get_host_list_by_id_list(host_id_list)

        if not query.count():
            flask.abort(status.HTTP_404_NOT_FOUND)

        for host_id, deleted in delete_hosts(
                query, current_app.event_producer,
                inventory_config().host_delete_chunk_size):
            if deleted:
                log_host_delete_succeeded(logger, host_id, get_control_rule())
                tracker_message = "deleted host"
            else:
                log_host_delete_failed(logger, host_id)
                tracker_message = "not deleted host"

            with PayloadTrackerProcessingContext(
                    payload_tracker, processing_status_message=tracker_message
            ) as payload_tracker_processing_ctx:
                payload_tracker_processing_ctx.inventory_id = host_id

    return flask.Response(None, status.HTTP_200_OK)
示例#3
0
def add_host(host_data):
    payload_tracker = get_payload_tracker(payload_id=threadctx.request_id)

    with PayloadTrackerProcessingContext(
            payload_tracker, processing_status_message="adding/updating host"
    ) as payload_tracker_processing_ctx:

        try:
            logger.info("Attempting to add host...")
            input_host = deserialize_host(host_data)
            (output_host,
             add_results) = host_repository.add_host(input_host,
                                                     staleness_offset())
            metrics.add_host_success.labels(
                add_results.name,
                host_data.get("reporter", "null")).inc()  # created vs updated
            logger.info(
                "Host added"
            )  # This definitely needs to be more specific (added vs updated?)
            payload_tracker_processing_ctx.inventory_id = output_host["id"]
            return (output_host, add_results)
        except InventoryException:
            logger.exception("Error adding host ", extra={"host": host_data})
            metrics.add_host_failure.labels("InventoryException",
                                            host_data.get("reporter",
                                                          "null")).inc()
            raise
        except Exception:
            logger.exception("Error while adding host",
                             extra={"host": host_data})
            metrics.add_host_failure.labels("Exception",
                                            host_data.get("reporter",
                                                          "null")).inc()
            raise
示例#4
0
def update_system_profile(host_data, platform_metadata):
    payload_tracker = get_payload_tracker(request_id=threadctx.request_id)

    with PayloadTrackerProcessingContext(
            payload_tracker,
            processing_status_message="updating host system profile",
            current_operation="updating host system profile",
    ) as payload_tracker_processing_ctx:

        try:
            input_host = deserialize_host(host_data, schema=LimitedHostSchema)
            input_host.id = host_data.get("id")
            staleness_timestamps = Timestamps.from_config(inventory_config())
            identity = create_mock_identity_with_account(input_host.account)
            output_host, host_id, insights_id, update_result = host_repository.update_system_profile(
                input_host, identity, staleness_timestamps, EGRESS_HOST_FIELDS)
            log_update_system_profile_success(logger, output_host)
            payload_tracker_processing_ctx.inventory_id = output_host["id"]
            return output_host, host_id, insights_id, update_result
        except ValidationException:
            metrics.update_system_profile_failure.labels(
                "ValidationException").inc()
            raise
        except InventoryException:
            log_update_system_profile_failure(logger, host_data)
            raise
        except OperationalError as oe:
            log_db_access_failure(logger, f"Could not access DB {str(oe)}",
                                  host_data)
            raise oe
        except Exception:
            logger.exception("Error while updating host system profile",
                             extra={"host": host_data})
            metrics.update_system_profile_failure.labels("Exception").inc()
            raise
示例#5
0
def handle_message(message, event_producer):
    validated_operation_msg = parse_operation_message(message)
    platform_metadata = validated_operation_msg.get("platform_metadata") or {}

    # create a dummy identity for working around the identity requirement for CRUD operations
    identity = Identity(USER_IDENTITY)

    # set account_number in dummy idenity to the actual account_number received in the payload
    identity.account_number = validated_operation_msg["data"]["account"]

    request_id = platform_metadata.get("request_id", "-1")
    initialize_thread_local_storage(request_id)

    payload_tracker = get_payload_tracker(request_id=request_id)

    with PayloadTrackerContext(payload_tracker,
                               received_status_message="message received",
                               current_operation="handle_message"):
        output_host, host_id, insights_id, add_results = add_host(
            validated_operation_msg["data"], identity)
        event_type = add_host_results_to_event_type(add_results)
        event = build_event(event_type,
                            output_host,
                            platform_metadata=platform_metadata)

        headers = message_headers(add_results, insights_id)
        event_producer.write_event(event, str(host_id), headers, Topic.egress)

        # for transition to platform.inventory.events
        if inventory_config().secondary_topic_enabled:
            event_producer.write_event(event, str(host_id), headers,
                                       Topic.events)
def add_host(host_data):
    payload_tracker = get_payload_tracker(request_id=threadctx.request_id)

    with PayloadTrackerProcessingContext(
            payload_tracker, processing_status_message="adding/updating host"
    ) as payload_tracker_processing_ctx:

        try:
            input_host = deserialize_host(host_data)
            staleness_timestamps = Timestamps.from_config(inventory_config())
            logger.info(
                "Attempting to add host",
                extra={
                    "input_host": {
                        "account": input_host.account,
                        "display_name": input_host.display_name,
                        "canonical_facts": input_host.canonical_facts,
                        "reporter": input_host.reporter,
                        "stale_timestamp":
                        input_host.stale_timestamp.isoformat(),
                        "tags": input_host.tags,
                    }
                },
            )
            (output_host,
             add_results) = host_repository.add_host(input_host,
                                                     staleness_timestamps,
                                                     fields=EGRESS_HOST_FIELDS)
            metrics.add_host_success.labels(
                add_results.name,
                host_data.get("reporter", "null")).inc()  # created vs updated
            # log all the incoming host data except facts and system_profile b/c they can be quite large
            logger.info(
                "Host %s",
                add_results.name,
                extra={
                    "host": {
                        i: output_host[i]
                        for i in output_host
                        if i not in ("facts", "system_profile")
                    }
                },
            )
            payload_tracker_processing_ctx.inventory_id = output_host["id"]
            return (output_host, add_results)
        except InventoryException:
            logger.exception("Error adding host ", extra={"host": host_data})
            metrics.add_host_failure.labels("InventoryException",
                                            host_data.get("reporter",
                                                          "null")).inc()
            raise
        except Exception:
            logger.exception("Error while adding host",
                             extra={"host": host_data})
            metrics.add_host_failure.labels("Exception",
                                            host_data.get("reporter",
                                                          "null")).inc()
            raise
示例#7
0
def add_host_list(host_list):
    response_host_list = []
    number_of_errors = 0

    payload_tracker = get_payload_tracker(
        account=current_identity.account_number,
        payload_id=threadctx.request_id)

    with PayloadTrackerContext(payload_tracker,
                               received_status_message="add host operation"):

        for host in host_list:
            try:
                with PayloadTrackerProcessingContext(
                        payload_tracker,
                        processing_status_message="adding/updating host"
                ) as payload_tracker_processing_ctx:
                    input_host = deserialize_host(host)
                    (output_host, add_result) = _add_host(input_host)
                    status_code = _convert_host_results_to_http_status(
                        add_result)
                    response_host_list.append({
                        "status": status_code,
                        "host": output_host
                    })
                    payload_tracker_processing_ctx.inventory_id = output_host[
                        "id"]
            except ValidationException as e:
                number_of_errors += 1
                logger.exception("Input validation error while adding host",
                                 extra={"host": host})
                response_host_list.append({
                    **e.to_json(), "title": "Bad Request",
                    "host": host
                })
            except InventoryException as e:
                number_of_errors += 1
                logger.exception("Error adding host", extra={"host": host})
                response_host_list.append({**e.to_json(), "host": host})
            except Exception:
                number_of_errors += 1
                logger.exception("Error adding host", extra={"host": host})
                response_host_list.append({
                    "status": 500,
                    "title": "Error",
                    "type": "unknown",
                    "detail": "Could not complete operation",
                    "host": host,
                })

        response = {
            "total": len(response_host_list),
            "errors": number_of_errors,
            "data": response_host_list
        }
        return _build_json_response(response, status=207)
示例#8
0
def handle_message(message, event_producer):
    validated_operation_msg = parse_operation_message(message)
    platform_metadata = validated_operation_msg.get("platform_metadata") or {}
    initialize_thread_local_storage(platform_metadata)

    payload_tracker = get_payload_tracker(request_id=threadctx.request_id)

    with PayloadTrackerContext(payload_tracker, received_status_message="message received"):
        (output_host, add_results) = add_host(validated_operation_msg["data"])
        event = build_egress_topic_event(add_results.name, output_host, platform_metadata)
        event_producer.write_event(event, output_host["id"], message_headers(add_results.name))
示例#9
0
def add_host(host_data, platform_metadata):
    payload_tracker = get_payload_tracker(request_id=threadctx.request_id)

    with PayloadTrackerProcessingContext(
            payload_tracker,
            processing_status_message="adding/updating host",
            current_operation="adding/updating host"
    ) as payload_tracker_processing_ctx:

        try:
            identity = _get_identity(host_data, platform_metadata)
            # basic-auth does not need owner_id
            if identity.identity_type == IdentityType.SYSTEM:
                host_data = _set_owner(host_data, identity)

            input_host = deserialize_host(host_data)
            staleness_timestamps = Timestamps.from_config(inventory_config())
            log_add_host_attempt(logger, input_host)
            output_host, host_id, insights_id, add_result = host_repository.add_host(
                input_host,
                identity,
                staleness_timestamps,
                fields=EGRESS_HOST_FIELDS)
            log_add_update_host_succeeded(logger, add_result, host_data,
                                          output_host)
            payload_tracker_processing_ctx.inventory_id = output_host["id"]
            return output_host, host_id, insights_id, add_result
        except ValidationException:
            metrics.add_host_failure.labels("ValidationException",
                                            host_data.get("reporter",
                                                          "null")).inc()
            raise
        except InventoryException as ie:
            log_add_host_failure(logger, str(ie.detail), host_data)
            raise
        except OperationalError as oe:
            log_db_access_failure(logger, f"Could not access DB {str(oe)}",
                                  host_data)
            raise oe
        except Exception:
            logger.exception("Error while adding host",
                             extra={"host": host_data})
            metrics.add_host_failure.labels("Exception",
                                            host_data.get("reporter",
                                                          "null")).inc()
            raise
def handle_message(message, event_producer):
    validated_operation_msg = parse_operation_message(message)
    platform_metadata = validated_operation_msg.get("platform_metadata") or {}

    request_id = platform_metadata.get("request_id", "-1")
    initialize_thread_local_storage(request_id)

    payload_tracker = get_payload_tracker(request_id=request_id)

    with PayloadTrackerContext(
        payload_tracker, received_status_message="message received", current_operation="handle_message"
    ):
        (output_host, add_results) = add_host(validated_operation_msg["data"])
        event_type = add_host_results_to_event_type(add_results)
        event = build_event(event_type, output_host, platform_metadata=platform_metadata)
        event_producer.write_event(event, output_host["id"], message_headers(add_results), Topic.egress)

        # for transition to platform.inventory.events
        if inventory_config().secondary_topic_enabled:
            event_producer.write_event(event, output_host["id"], message_headers(add_results), Topic.events)
def handle_message(message, event_producer):
    validated_operation_msg = parse_operation_message(message)
    metadata = validated_operation_msg.get("platform_metadata") or {}
    initialize_thread_local_storage(metadata)

    payload_tracker = get_payload_tracker(payload_id=threadctx.request_id)

    with PayloadTrackerContext(payload_tracker,
                               received_status_message="message received"):

        # FIXME: verify operation type
        (output_host, add_results) = add_host(validated_operation_msg["data"])

        if add_results == host_repository.AddHostResults.created:
            event_type = "created"
        else:
            event_type = "updated"

        event = build_event(event_type, output_host, metadata)

        event_producer.write_event(event, output_host["id"])
示例#12
0
def delete_by_id(host_id_list):
    payload_tracker = get_payload_tracker(
        account=current_identity.account_number,
        payload_id=threadctx.request_id)

    with PayloadTrackerContext(payload_tracker,
                               received_status_message="delete operation"):

        query = _get_host_list_by_id_list(current_identity.account_number,
                                          host_id_list)

        hosts_to_delete = query.all()

        if not hosts_to_delete:
            return flask.abort(status.HTTP_404_NOT_FOUND)

        with metrics.delete_host_processing_time.time():
            query.delete(synchronize_session="fetch")
        db.session.commit()

        metrics.delete_host_count.inc(len(hosts_to_delete))

        # This process of checking for an already deleted host relies
        # on checking the session after it has been updated by the commit()
        # function and marked the deleted hosts as expired.  It is after this
        # change that the host is called by a new query and, if deleted by a
        # different process, triggers the ObjectDeletedError and is not emited.
        for deleted_host in hosts_to_delete:
            # Prevents ObjectDeletedError from being raised.
            if instance_state(deleted_host).expired:
                # Can’t log the Host ID. Accessing an attribute raises ObjectDeletedError.
                logger.info("Host already deleted. Delete event not emitted.")
            else:
                with PayloadTrackerProcessingContext(
                        payload_tracker,
                        processing_status_message="deleted host"
                ) as payload_tracker_processing_ctx:
                    logger.debug("Deleted host: %s", deleted_host)
                    emit_event(events.delete(deleted_host))
                    payload_tracker_processing_ctx.inventory_id = deleted_host.id
示例#13
0
def handle_message(message, event_producer, message_operation=add_host):
    validated_operation_msg = parse_operation_message(message)
    platform_metadata = validated_operation_msg.get("platform_metadata", {})

    request_id = platform_metadata.get("request_id", UNKNOWN_REQUEST_ID_VALUE)
    initialize_thread_local_storage(request_id)

    payload_tracker = get_payload_tracker(request_id=request_id)

    with PayloadTrackerContext(payload_tracker,
                               received_status_message="message received",
                               current_operation="handle_message"):
        try:
            host = validated_operation_msg["data"]

            output_host, host_id, insights_id, operation_result = message_operation(
                host, platform_metadata)
            event_type = operation_results_to_event_type(operation_result)
            event = build_event(event_type,
                                output_host,
                                platform_metadata=platform_metadata)

            headers = message_headers(operation_result, insights_id)
            event_producer.write_event(event, str(host_id), headers)
        except ValidationException as ve:
            logger.error(
                "Validation error while adding or updating host: %s",
                ve,
                extra={"host": {
                    "reporter": host.get("reporter")
                }},
            )
            raise
        except ValueError as ve:
            logger.error("Value error while adding or updating host: %s",
                         ve,
                         extra={"reporter": host.get("reporter")})
            raise
 def _get_tracker(self, account=None, payload_id=None, producer=None):
     config = Config(RuntimeEnvironment.server)
     init_payload_tracker(config, producer=producer)
     return get_payload_tracker(account=account, payload_id=payload_id)
示例#15
0
def add_host_list(body):
    if not inventory_config().rest_post_enabled:
        return flask_json_response(
            {
                "detail": "The method is not allowed for the requested URL.",
                "status": 405,
                "title": "Method Not Allowed",
                "type": "about:blank",
            },
            status=405,
        )
    reporter = None

    response_host_list = []
    number_of_errors = 0

    payload_tracker = get_payload_tracker(account=current_identity.account_number, request_id=threadctx.request_id)

    with PayloadTrackerContext(
        payload_tracker, received_status_message="add host operation", current_operation="add host"
    ):

        for host in body:
            try:
                with PayloadTrackerProcessingContext(
                    payload_tracker,
                    processing_status_message="adding/updating host",
                    current_operation="adding/updating host",
                ) as payload_tracker_processing_ctx:
                    if host.get("tags"):
                        tags_ignored_from_http_count.inc()
                        logger.info("Tags from an HTTP request were ignored")

                    input_host = deserialize_host_http(host)
                    output_host, host_id, _, add_result = _add_host(input_host)
                    status_code = _convert_host_results_to_http_status(add_result)
                    response_host_list.append({"status": status_code, "host": output_host})
                    payload_tracker_processing_ctx.inventory_id = host_id

                    reporter = host.get("reporter")
            except ValidationException as e:
                number_of_errors += 1
                logger.exception("Input validation error while adding host", extra={"host": host})
                response_host_list.append({**e.to_json(), "title": "Bad Request", "host": host})
            except InventoryException as e:
                number_of_errors += 1
                logger.exception("Error adding host", extra={"host": host})
                response_host_list.append({**e.to_json(), "host": host})
            except Exception:
                number_of_errors += 1
                logger.exception("Error adding host", extra={"host": host})
                response_host_list.append(
                    {
                        "status": 500,
                        "title": "Error",
                        "type": "unknown",
                        "detail": "Could not complete operation",
                        "host": host,
                    }
                )

        rest_post_request_count.labels(reporter=reporter).inc()

        response = {"total": len(response_host_list), "errors": number_of_errors, "data": response_host_list}
        return flask_json_response(response, status=207)
 def _get_tracker(self, account=None, payload_id=None, producer=None):
     config = Config()
     init_payload_tracker(config, producer=producer)
     return get_payload_tracker(account=account, payload_id=payload_id)
 def _payload_tracker(account=None, request_id=None, producer=None):
     config = Config(RuntimeEnvironment.SERVER)
     init_payload_tracker(config, producer=producer)
     return get_payload_tracker(account=account, request_id=request_id)