### Description

From the nodes stats API, we should extract the `ingest` stats into their own endpoint. This endpoint can then be non-node-centric, and present a global view of the pipelines, processors, and the metrics collected around ingest in general.
server/src/main/java/org/elasticsearch/rest/action/info/RestClusterInfoAction.java
static final Map<String, Function<NodesStatsResponse, ChunkedToXContent>> RESPONSE_MAPPER = Map.of(
        NodesInfoRequest.Metric.HTTP.metricName(),
        nodesStatsResponse -> nodesStatsResponse.getNodes().stream().map(NodeStats::getHttp).reduce(HttpStats.IDENTITY, HttpStats::merge)
    );
    static final Set<String> AVAILABLE_TARGETS = RESPONSE_MAPPER.keySet();
    @Override
    public String getName() {
        return "cluster_info_action";
    }
    @Override
    public List<Route> routes() {
        return List.of(new Route(RestRequest.Method.GET, "/_info/{target}"));
    }
    @Override
    public RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException {
        var nodesStatsRequest = new NodesStatsRequest().clear();
        var targets = Strings.tokenizeByCommaToSet(request.param("target"));
        if (targets.size() == 1 && targets.contains("_all")) {
            targets.clear();
            AVAILABLE_TARGETS.forEach(m -> {
                nodesStatsRequest.addMetric(m);
                targets.add(m);
            });
        } else if (targets.contains("_all")) {
            throw new IllegalArgumentException(
                String.format(Locale.ROOT, "request [%s] contains _all and individual target [%s]", request.path(), request.param("target"))
            );
        } else {
            var invalidTargetParams = targets.stream()
                .filter(Predicate.not(AVAILABLE_TARGETS::contains))