コード例 #1
0
def update_facts_by_namespace(operation, host_id_list, namespace, fact_dict):

    current_identity = get_current_identity()
    query = Host.query.filter(
        (Host.account == current_identity.account_number)
        & Host.id.in_(host_id_list)
        & Host.facts.has_key(
            namespace)  # noqa: W601 JSONB query filter, not a dict
    )

    hosts_to_update = find_non_culled_hosts(
        update_query_for_owner_id(current_identity, query)).all()

    logger.debug("hosts_to_update:%s", hosts_to_update)

    if len(hosts_to_update) != len(host_id_list):
        error_msg = (
            "ERROR: The number of hosts requested does not match the number of hosts found in the host database.  "
            "This could happen if the namespace does not exist or the account number associated with the call does "
            "not match the account number associated with one or more the hosts.  Rejecting the fact change request."
        )
        logger.debug(error_msg)
        return error_msg, 400

    for host in hosts_to_update:
        if operation is FactOperations.replace:
            host.replace_facts_in_namespace(namespace, fact_dict)
        else:
            host.merge_facts_in_namespace(namespace, fact_dict)

    db.session.commit()

    logger.debug("hosts_to_update:%s", hosts_to_update)

    return 200
コード例 #2
0
def _find_hosts_by_hostname_or_id(hostname):
    current_identity = get_current_identity()
    logger.debug("_find_hosts_by_hostname_or_id(%s)", hostname)

    filter_list = [
        Host.display_name.comparator.contains(hostname),
        Host.canonical_facts["fqdn"].astext.contains(hostname.casefold()),
    ]

    try:
        UUID(hostname)
        host_id = hostname
        filter_list.append(Host.id == host_id)
        logger.debug("Adding id (uuid) to the filter list")
    except Exception:
        # Do not filter using the id
        logger.debug("The hostname (%s) could not be converted into a UUID",
                     hostname,
                     exc_info=True)

    return Host.query.filter(
        and_(*[
            Host.account == current_identity.account_number,
            or_(*filter_list)
        ]))
コード例 #3
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)
コード例 #4
0
def get_host_list(
    display_name,
    fqdn,
    hostname_or_id,
    insights_id,
    provider_id,
    provider_type,
    tags,
    page,
    per_page,
    param_order_by,
    param_order_how,
    staleness,
    registered_with,
    filter,
    fields,
):
    limit, offset = pagination_params(page, per_page)
    xjoin_order_by, xjoin_order_how = params_to_order(param_order_by,
                                                      param_order_how)

    all_filters = query_filters(
        fqdn,
        display_name,
        hostname_or_id,
        insights_id,
        provider_id,
        provider_type,
        tags,
        staleness,
        registered_with,
        filter,
    )

    current_identity = get_current_identity()
    if current_identity.identity_type == IdentityType.SYSTEM and current_identity.auth_type != AuthType.CLASSIC:
        all_filters += owner_id_filter()

    additional_fields = tuple()

    system_profile_fields = []
    if fields.get("system_profile"):
        additional_fields = ("system_profile", )
        system_profile_fields = list(fields.get("system_profile").keys())

    variables = {
        "limit": limit,
        "offset": offset,
        "order_by": xjoin_order_by,
        "order_how": xjoin_order_how,
        "filter": all_filters,
        "fields": system_profile_fields,
    }
    response = graphql_query(QUERY, variables,
                             log_get_host_list_failed)["hosts"]

    total = response["meta"]["total"]
    check_pagination(offset, total)

    return map(deserialize_host, response["data"]), total, additional_fields
コード例 #5
0
def _find_hosts_by_display_name(display_name):

    current_identity = get_current_identity()
    logger.debug("find_hosts_by_display_name(%s)", display_name)
    return Host.query.filter(
        and_(Host.account == current_identity.account_number,
             Host.display_name.comparator.contains(display_name)))
コード例 #6
0
def validate_schema(repo_fork="RedHatInsights", repo_branch="master", days=1, max_messages=10000):
    # Use the identity header to make sure the user is someone from our team.
    config = Config(RuntimeEnvironment.SERVICE)
    identity = get_current_identity()
    if not hasattr(identity, "user") or identity.user.get("username") not in config.sp_authorized_users:
        flask.abort(403, "This endpoint is restricted to HBI Admins.")

    consumer = KafkaConsumer(
        bootstrap_servers=config.bootstrap_servers,
        api_version=(0, 10, 1),
        value_deserializer=lambda m: m.decode(),
        **config.validator_kafka_consumer,
    )
    try:
        response = validate_sp_for_branch(
            consumer,
            {config.host_ingress_topic, config.additional_validation_topic},
            repo_fork,
            repo_branch,
            days,
            max_messages,
        )
        consumer.close()
        return flask_json_response(response)
    except (ValueError, AttributeError) as e:
        consumer.close()
        flask.abort(400, str(e))
コード例 #7
0
        def modified_func(*args, **kwargs):
            if not inventory_config().rbac_enforced:
                return func(*args, **kwargs)

            if get_current_identity().identity_type != CHECKED_TYPE:
                return func(*args, **kwargs)

            # track that RBAC is being used to control access
            g.access_control_rule = "RBAC"
            logger.debug("access_control_rule set")

            rbac_data = get_rbac_permissions()

            permission_type = required_permission.value.split(":")[2]

            for rbac_permission in rbac_data:
                if (rbac_permission["permission"]
                        == Permission.ADMIN.value  # inventory:*:*
                        or rbac_permission["permission"]
                        == Permission.HOSTS_ALL.value  # inventory:hosts:*
                        or rbac_permission["permission"] ==
                        f"inventory:*:{permission_type}"  # inventory:*:(read | write)
                        or rbac_permission["permission"] == required_permission
                        .value  # inventory:hosts:(read | write)
                    ):
                    return func(*args, **kwargs)

            rbac_permission_denied(logger, required_permission.value,
                                   rbac_data)
            abort(status.HTTP_403_FORBIDDEN)
コード例 #8
0
def get_sap_system(tags=None,
                   page=None,
                   per_page=None,
                   staleness=None,
                   registered_with=None,
                   filter=None):
    if not xjoin_enabled():
        logger.error("xjoin-search not enabled")
        flask.abort(503)

    limit, offset = pagination_params(page, per_page)

    variables = {
        "hostFilter": {
            # we're not indexing null timestamps in ES
            "OR": list(staleness_filter(staleness))
        },
        "limit": limit,
        "offset": offset,
    }
    hostfilter_and_variables = ()

    if tags:
        hostfilter_and_variables = build_tag_query_dict_tuple(tags)

    if registered_with:
        hostfilter_and_variables += build_registered_with_filter(
            registered_with)

    if filter:
        for key in filter:
            if key == "system_profile":
                hostfilter_and_variables += build_system_profile_filter(
                    filter["system_profile"])
            else:
                raise ValidationException("filter key is invalid")

    current_identity = get_current_identity()
    if current_identity.identity_type == IdentityType.SYSTEM:
        hostfilter_and_variables += owner_id_filter()

    if hostfilter_and_variables != ():
        variables["hostFilter"]["AND"] = hostfilter_and_variables

    response = graphql_query(SAP_SYSTEM_QUERY, variables,
                             log_get_sap_system_failed)

    data = response["hostSystemProfile"]

    check_pagination(offset, data["sap_system"]["meta"]["total"])

    log_get_sap_system_succeeded(logger, data)
    return flask_json_response(
        build_collection_response(data["sap_system"]["data"], page, per_page,
                                  data["sap_system"]["meta"]["total"]))
コード例 #9
0
def get_sap_sids(search=None, tags=None, page=None, per_page=None, staleness=None, registered_with=None, filter=None):
    if not xjoin_enabled():
        logger.error("xjoin-search not enabled")
        flask.abort(503)

    limit, offset = pagination_params(page, per_page)

    variables = {
        "hostFilter": {
            # we're not indexing null timestamps in ES
            "OR": list(staleness_filter(staleness))
        },
        "limit": limit,
        "offset": offset,
    }

    hostfilter_and_variables = ()

    if tags:
        hostfilter_and_variables = build_tag_query_dict_tuple(tags)

    if registered_with:
        variables["hostFilter"]["NOT"] = {"insights_id": {"eq": None}}

    if search:
        variables["filter"] = {
            # Escaped so that the string literals are not interpreted as regex
            "search": {"regex": f".*{custom_escape(search)}.*"}
        }

    if filter:
        for key in filter:
            if key == "system_profile":
                hostfilter_and_variables += build_system_profile_filter(filter["system_profile"])
            else:
                raise ValidationException("filter key is invalid")

    current_identity = get_current_identity()
    if current_identity.identity_type == IdentityType.SYSTEM and current_identity.auth_type != AuthType.CLASSIC:
        hostfilter_and_variables += owner_id_filter()

    if hostfilter_and_variables != ():
        variables["hostFilter"]["AND"] = hostfilter_and_variables

    response = graphql_query(SAP_SIDS_QUERY, variables, log_get_sap_sids_failed)

    data = response["hostSystemProfile"]

    check_pagination(offset, data["sap_sids"]["meta"]["total"])

    log_get_sap_sids_succeeded(logger, data)
    return flask_json_response(
        build_collection_response(data["sap_sids"]["data"], page, per_page, data["sap_sids"]["meta"]["total"])
    )
コード例 #10
0
def get_operating_system(
    tags=None,
    page: Optional[int] = None,
    per_page: Optional[int] = None,
    staleness: Optional[str] = None,
    registered_with: Optional[str] = None,
    filter=None,
):
    limit, offset = pagination_params(page, per_page)

    variables = {
        "hostFilter": {
            # we're not indexing null timestamps in ES
            "OR": list(staleness_filter(staleness))
        },
        "limit": limit,
        "offset": offset,
    }
    hostfilter_and_variables = ()

    if tags:
        hostfilter_and_variables = build_tag_query_dict_tuple(tags)

    if registered_with:
        variables["hostFilter"]["NOT"] = {"insights_id": {"eq": None}}

    if filter:
        for key in filter:
            if key == "system_profile":
                hostfilter_and_variables += build_system_profile_filter(
                    filter["system_profile"])
            else:
                raise ValidationException("filter key is invalid")

    current_identity = get_current_identity()
    if current_identity.identity_type == IdentityType.SYSTEM:
        hostfilter_and_variables += owner_id_filter()

    if hostfilter_and_variables != ():
        variables["hostFilter"]["AND"] = hostfilter_and_variables

    response = graphql_query(OPERATING_SYSTEM_QUERY, variables,
                             log_get_operating_system_failed)

    data = response["hostSystemProfile"]

    check_pagination(offset, data["operating_system"]["meta"]["total"])

    log_get_operating_system_succeeded(logger, data)

    return flask_json_response(
        build_collection_response(data["operating_system"]["data"], page,
                                  per_page,
                                  data["operating_system"]["meta"]["total"]))
コード例 #11
0
def _add_host(input_host):
    current_identity = get_current_identity()
    if not current_identity.is_trusted_system and current_identity.account_number != input_host.account:
        raise InventoryException(
            title="Invalid request",
            detail=
            "The account number associated with the user does not match the account number associated with the "
            "host",
        )

    return add_host(input_host,
                    staleness_timestamps(),
                    update_system_profile=False)
コード例 #12
0
def host_checkin(body):

    current_identity = get_current_identity()
    canonical_facts = deserialize_canonical_facts(body)
    existing_host = find_existing_host(current_identity, canonical_facts)

    if existing_host:
        existing_host._update_modified_date()
        db.session.commit()
        serialized_host = serialize_host(existing_host, staleness_timestamps(),
                                         EGRESS_HOST_FIELDS)
        _emit_patch_event(serialized_host, existing_host.id,
                          existing_host.canonical_facts.get("insights_id"))
        return flask_json_response(serialized_host, 201)
    else:
        flask.abort(404, "No hosts match the provided canonical facts.")
コード例 #13
0
def get_host_ids_list(
    display_name,
    fqdn,
    hostname_or_id,
    insights_id,
    provider_id,
    provider_type,
    registered_with,
    staleness,
    tags,
    filter,
):
    all_filters = query_filters(
        fqdn,
        display_name,
        hostname_or_id,
        insights_id,
        provider_id,
        provider_type,
        tags,
        staleness,
        registered_with,
        filter,
    )

    current_identity = get_current_identity()
    if current_identity.identity_type == IdentityType.SYSTEM and current_identity.auth_type != AuthType.CLASSIC:
        all_filters += owner_id_filter()

    variables = {
        "limit": 100,
        "filter": all_filters
    }  # maximum limit handled by xjoin.
    response = graphql_query(HOST_IDS_QUERY, variables,
                             log_get_host_list_failed)["hosts"]

    return [x["id"] for x in response["data"]]
コード例 #14
0
def _find_hosts_by_canonical_fact(canonical_fact, value):
    return single_canonical_fact_host_query(get_current_identity(),
                                            canonical_fact, value)
コード例 #15
0
def _find_all_hosts():
    identity = get_current_identity()
    query = Host.query.filter(Host.account == identity.account_number)
    return update_query_for_owner_id(identity, query)
コード例 #16
0
def get_tags(
    search=None,
    tags=None,
    display_name=None,
    fqdn=None,
    hostname_or_id=None,
    insights_id=None,
    provider_id=None,
    provider_type=None,
    order_by=None,
    order_how=None,
    page=None,
    per_page=None,
    staleness=None,
    registered_with=None,
    filter=None,
):
    if not xjoin_enabled():
        logger.error("xjoin-search not enabled")
        flask.abort(503)

    limit, offset = pagination_params(page, per_page)

    variables = {
        "order_by": order_by,
        "order_how": order_how,
        "limit": limit,
        "offset": offset,
        "hostFilter": {
            # we're not indexing null timestamps in ES
            "OR": list(staleness_filter(staleness))
        },
    }

    hostfilter_and_variables = query_filters(
        fqdn,
        display_name,
        hostname_or_id,
        insights_id,
        provider_id,
        provider_type,
        tags,
        None,
        registered_with,
        filter,
    )

    if search:
        variables["filter"] = {
            # Escaped so that the string literals are not interpreted as regex
            "search": {
                "regex": f".*{custom_escape(search)}.*"
            }
        }

    current_identity = get_current_identity()
    if current_identity.identity_type == IdentityType.SYSTEM:
        hostfilter_and_variables += owner_id_filter()

    if hostfilter_and_variables != ():
        variables["hostFilter"]["AND"] = hostfilter_and_variables

    response = graphql_query(TAGS_QUERY, variables, log_get_tags_failed)
    data = response["hostTags"]

    check_pagination(offset, data["meta"]["total"])

    log_get_tags_succeeded(logger, data)
    return flask_json_response(
        build_collection_response(data["data"], page, per_page,
                                  data["meta"]["total"]))
コード例 #17
0
def owner_id_filter():
    return ({"spf_owner_id": {"eq": get_current_identity().system["cn"]}}, )
コード例 #18
0
def _get_host_list_by_id_list(host_id_list):
    current_identity = get_current_identity()
    query = Host.query.filter((Host.account == current_identity.account_number)
                              & Host.id.in_(host_id_list))
    return find_non_culled_hosts(
        update_query_for_owner_id(current_identity, query))