Merge branch 'features/federation-status' into 'develop'
Add a federation_status endpoint showing unreachable instances See merge request pleroma/pleroma!3086
This commit is contained in:
commit
4800ee656b
|
@ -42,6 +42,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- Admin API: (`GET /api/pleroma/admin/users`) added filters user by `unconfirmed` status
|
- Admin API: (`GET /api/pleroma/admin/users`) added filters user by `unconfirmed` status
|
||||||
- Admin API: (`GET /api/pleroma/admin/users`) added filters user by `actor_type`
|
- Admin API: (`GET /api/pleroma/admin/users`) added filters user by `actor_type`
|
||||||
- Pleroma API: Add `idempotency_key` to the chat message entity that can be used for optimistic message sending.
|
- Pleroma API: Add `idempotency_key` to the chat message entity that can be used for optimistic message sending.
|
||||||
|
- Pleroma API: (`GET /api/v1/pleroma/federation_status`) Add a way to get a list of unreachable instances.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ defmodule Pleroma.Instances do
|
||||||
defdelegate reachable?(url_or_host), to: @adapter
|
defdelegate reachable?(url_or_host), to: @adapter
|
||||||
defdelegate set_reachable(url_or_host), to: @adapter
|
defdelegate set_reachable(url_or_host), to: @adapter
|
||||||
defdelegate set_unreachable(url_or_host, unreachable_since \\ nil), to: @adapter
|
defdelegate set_unreachable(url_or_host, unreachable_since \\ nil), to: @adapter
|
||||||
|
defdelegate get_consistently_unreachable(), to: @adapter
|
||||||
|
|
||||||
def set_consistently_unreachable(url_or_host),
|
def set_consistently_unreachable(url_or_host),
|
||||||
do: set_unreachable(url_or_host, reachability_datetime_threshold())
|
do: set_unreachable(url_or_host, reachability_datetime_threshold())
|
||||||
|
|
|
@ -119,6 +119,17 @@ def set_unreachable(url_or_host, unreachable_since) when is_binary(url_or_host)
|
||||||
|
|
||||||
def set_unreachable(_, _), do: {:error, nil}
|
def set_unreachable(_, _), do: {:error, nil}
|
||||||
|
|
||||||
|
def get_consistently_unreachable do
|
||||||
|
reachability_datetime_threshold = Instances.reachability_datetime_threshold()
|
||||||
|
|
||||||
|
from(i in Instance,
|
||||||
|
where: ^reachability_datetime_threshold > i.unreachable_since,
|
||||||
|
order_by: i.unreachable_since,
|
||||||
|
select: {i.host, i.unreachable_since}
|
||||||
|
)
|
||||||
|
|> Repo.all()
|
||||||
|
end
|
||||||
|
|
||||||
defp parse_datetime(datetime) when is_binary(datetime) do
|
defp parse_datetime(datetime) when is_binary(datetime) do
|
||||||
NaiveDateTime.from_iso8601(datetime)
|
NaiveDateTime.from_iso8601(datetime)
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.ApiSpec.PleromaInstancesOperation do
|
||||||
|
alias OpenApiSpex.Operation
|
||||||
|
alias OpenApiSpex.Schema
|
||||||
|
|
||||||
|
def open_api_operation(action) do
|
||||||
|
operation = String.to_existing_atom("#{action}_operation")
|
||||||
|
apply(__MODULE__, operation, [])
|
||||||
|
end
|
||||||
|
|
||||||
|
def show_operation do
|
||||||
|
%Operation{
|
||||||
|
tags: ["PleromaInstances"],
|
||||||
|
summary: "Instances federation status",
|
||||||
|
description: "Information about instances deemed unreachable by the server",
|
||||||
|
operationId: "PleromaInstances.show",
|
||||||
|
responses: %{
|
||||||
|
200 => Operation.response("PleromaInstances", "application/json", pleroma_instances())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def pleroma_instances do
|
||||||
|
%Schema{
|
||||||
|
type: :object,
|
||||||
|
properties: %{
|
||||||
|
unreachable: %Schema{
|
||||||
|
type: :object,
|
||||||
|
properties: %{hostname: %Schema{type: :string, format: :"date-time"}}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
example: %{
|
||||||
|
"unreachable" => %{"consistently-unreachable.name" => "2020-10-14 22:07:58.216473"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,21 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.PleromaAPI.InstancesController do
|
||||||
|
use Pleroma.Web, :controller
|
||||||
|
|
||||||
|
alias Pleroma.Instances
|
||||||
|
|
||||||
|
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
||||||
|
|
||||||
|
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PleromaInstancesOperation
|
||||||
|
|
||||||
|
def show(conn, _params) do
|
||||||
|
unreachable =
|
||||||
|
Instances.get_consistently_unreachable()
|
||||||
|
|> Map.new(fn {host, date} -> {host, to_string(date)} end)
|
||||||
|
|
||||||
|
json(conn, %{"unreachable" => unreachable})
|
||||||
|
end
|
||||||
|
end
|
|
@ -398,6 +398,7 @@ defmodule Pleroma.Web.Router do
|
||||||
scope "/api/v1/pleroma", Pleroma.Web.PleromaAPI do
|
scope "/api/v1/pleroma", Pleroma.Web.PleromaAPI do
|
||||||
pipe_through(:api)
|
pipe_through(:api)
|
||||||
get("/accounts/:id/scrobbles", ScrobbleController, :index)
|
get("/accounts/:id/scrobbles", ScrobbleController, :index)
|
||||||
|
get("/federation_status", InstancesController, :show)
|
||||||
end
|
end
|
||||||
|
|
||||||
scope "/api/v1", Pleroma.Web.MastodonAPI do
|
scope "/api/v1", Pleroma.Web.MastodonAPI do
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.PleromaApi.InstancesControllerTest do
|
||||||
|
use Pleroma.Web.ConnCase
|
||||||
|
|
||||||
|
alias Pleroma.Instances
|
||||||
|
|
||||||
|
setup_all do: clear_config([:instance, :federation_reachability_timeout_days], 1)
|
||||||
|
|
||||||
|
setup do
|
||||||
|
constant = "http://consistently-unreachable.name/"
|
||||||
|
eventual = "http://eventually-unreachable.com/path"
|
||||||
|
|
||||||
|
{:ok, %Pleroma.Instances.Instance{unreachable_since: constant_unreachable}} =
|
||||||
|
Instances.set_consistently_unreachable(constant)
|
||||||
|
|
||||||
|
_eventual_unrechable = Instances.set_unreachable(eventual)
|
||||||
|
|
||||||
|
%{constant_unreachable: constant_unreachable, constant: constant}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "GET /api/v1/pleroma/federation_status", %{
|
||||||
|
conn: conn,
|
||||||
|
constant_unreachable: constant_unreachable,
|
||||||
|
constant: constant
|
||||||
|
} do
|
||||||
|
constant_host = URI.parse(constant).host
|
||||||
|
|
||||||
|
assert conn
|
||||||
|
|> put_req_header("content-type", "application/json")
|
||||||
|
|> get("/api/v1/pleroma/federation_status")
|
||||||
|
|> json_response_and_validate_schema(200) == %{
|
||||||
|
"unreachable" => %{constant_host => to_string(constant_unreachable)}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue