diff options
author | Tor Brede Vekterli <vekterli@yahooinc.com> | 2022-08-25 13:27:59 +0000 |
---|---|---|
committer | Tor Brede Vekterli <vekterli@yahooinc.com> | 2022-08-25 13:34:11 +0000 |
commit | bf13afeb506b581aa7af898941c3c5cf885946d4 (patch) | |
tree | 4bfc92d95caa87e446c84726998ce083fb361337 | |
parent | a105ffc48d22834af461cafd17da6e4bc8c7e715 (diff) |
Add capabilities and RPC filters for sentinel and internal Proton APIs
5 files changed, 59 insertions, 12 deletions
diff --git a/configd/src/apps/sentinel/rpchooks.cpp b/configd/src/apps/sentinel/rpchooks.cpp index c09c7676c79..b0c0cb1094f 100644 --- a/configd/src/apps/sentinel/rpchooks.cpp +++ b/configd/src/apps/sentinel/rpchooks.cpp @@ -6,6 +6,7 @@ #include "peer-check.h" #include "report-connectivity.h" #include <vespa/fnet/frt/supervisor.h> +#include <vespa/fnet/frt/require_capabilities.h> #include <vespa/fnet/frt/rpcrequest.h> #include <vespa/log/log.h> @@ -23,6 +24,13 @@ RPCHooks::RPCHooks(CommandQueue &commands, FRT_Supervisor &supervisor, ModelOwne RPCHooks::~RPCHooks() = default; +namespace { + +std::unique_ptr<FRT_RequireCapabilities> make_sentinel_api_capability_filter() { + return FRT_RequireCapabilities::of(vespalib::net::tls::Capability::config_sentinel_api()); +} + +} void RPCHooks::initRPC(FRT_Supervisor *supervisor) @@ -34,18 +42,22 @@ RPCHooks::initRPC(FRT_Supervisor *supervisor) FRT_METHOD(RPCHooks::rpc_listServices), this); rb.MethodDesc("list services"); rb.ReturnDesc("status", "Status for services"); + rb.RequestAccessFilter(make_sentinel_api_capability_filter()); //------------------------------------------------------------------------- rb.DefineMethod("sentinel.service.restart", "s", "", FRT_METHOD(RPCHooks::rpc_restartService), this); rb.MethodDesc("restart a service"); + rb.RequestAccessFilter(make_sentinel_api_capability_filter()); //------------------------------------------------------------------------- rb.DefineMethod("sentinel.service.stop", "s", "", FRT_METHOD(RPCHooks::rpc_stopService), this); rb.MethodDesc("stop a service"); + rb.RequestAccessFilter(make_sentinel_api_capability_filter()); //------------------------------------------------------------------------- rb.DefineMethod("sentinel.service.start", "s", "", FRT_METHOD(RPCHooks::rpc_startService), this); rb.MethodDesc("start a service"); + rb.RequestAccessFilter(make_sentinel_api_capability_filter()); //------------------------------------------------------------------------- rb.DefineMethod("sentinel.check.connectivity", "sii", "s", FRT_METHOD(RPCHooks::rpc_checkConnectivity), this); @@ -54,6 +66,7 @@ RPCHooks::initRPC(FRT_Supervisor *supervisor) rb.ParamDesc("port", "Port number of peer sentinel"); rb.ParamDesc("timeout", "Timeout for check in milliseconds"); rb.ReturnDesc("status", "Status (ok, bad, or unknown) for peer"); + rb.RequestAccessFilter(make_sentinel_api_capability_filter()); //------------------------------------------------------------------------- rb.DefineMethod("sentinel.report.connectivity", "i", "SS", FRT_METHOD(RPCHooks::rpc_reportConnectivity), this); @@ -61,6 +74,7 @@ RPCHooks::initRPC(FRT_Supervisor *supervisor) rb.ParamDesc("timeout", "Timeout for check in milliseconds"); rb.ReturnDesc("hostnames", "Names of peers checked"); rb.ReturnDesc("peerstatus", "Status description for each peer"); + rb.RequestAccessFilter(make_sentinel_api_capability_filter()); //------------------------------------------------------------------------- } diff --git a/searchcore/src/vespa/searchcore/proton/server/rpc_hooks.cpp b/searchcore/src/vespa/searchcore/proton/server/rpc_hooks.cpp index a320dd0f9ac..587da244937 100644 --- a/searchcore/src/vespa/searchcore/proton/server/rpc_hooks.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/rpc_hooks.cpp @@ -5,6 +5,7 @@ #include <vespa/searchcore/proton/matchengine/matchengine.h> #include <vespa/vespalib/util/lambdatask.h> #include <vespa/vespalib/util/compressionconfig.h> +#include <vespa/fnet/frt/require_capabilities.h> #include <vespa/fnet/frt/supervisor.h> #include <vespa/fnet/transport.h> @@ -55,6 +56,14 @@ RPCHooksBase::reportState(FRT_RPCRequest * req) ret.AddInt32(0); } +namespace { + +std::unique_ptr<FRT_RequireCapabilities> make_proton_admin_api_capability_filter() { + return FRT_RequireCapabilities::of(vespalib::net::tls::Capability::content_proton_admin_api()); +} + +} + void RPCHooksBase::initRPC() { @@ -68,6 +77,7 @@ RPCHooksBase::initRPC() rb.ReturnDesc("keys", "Array of state keys"); rb.ReturnDesc("values", "Array of state values"); rb.ReturnDesc("newgen", "New state generation count"); + rb.RequestAccessFilter(make_proton_admin_api_capability_filter()); //------------------------------------------------------------------------- rb.DefineMethod("proton.getStatus", "s", "SSSS", FRT_METHOD(RPCHooksBase::rpc_GetProtonStatus), this); @@ -77,21 +87,25 @@ RPCHooksBase::initRPC() rb.ReturnDesc("states", "Array of states "); rb.ReturnDesc("internalStates", "Array of internal states "); rb.ReturnDesc("message", "Array of status messages"); + rb.RequestAccessFilter(make_proton_admin_api_capability_filter()); //------------------------------------------------------------------------- rb.DefineMethod("pandora.rtc.die", "", "", FRT_METHOD(RPCHooksBase::rpc_die), this); rb.MethodDesc("Exit the rtc application without cleanup"); + rb.RequestAccessFilter(make_proton_admin_api_capability_filter()); //------------------------------------------------------------------------- rb.DefineMethod("proton.triggerFlush", "", "b", FRT_METHOD(RPCHooksBase::rpc_triggerFlush), this); rb.MethodDesc("Tell the node to trigger flush ASAP"); rb.ReturnDesc("success", "Whether or not a flush was triggered."); + rb.RequestAccessFilter(make_proton_admin_api_capability_filter()); //------------------------------------------------------------------------- rb.DefineMethod("proton.prepareRestart", "", "b", FRT_METHOD(RPCHooksBase::rpc_prepareRestart), this); rb.MethodDesc("Tell the node to prepare for a restart by flushing components " "such that TLS replay time + time spent flushing components is as low as possible"); rb.ReturnDesc("success", "Whether or not prepare for restart was triggered."); + rb.RequestAccessFilter(make_proton_admin_api_capability_filter()); } RPCHooksBase::Params::Params(Proton &parent, uint32_t port, const config::ConfigUri & configUri, diff --git a/vespalib/src/tests/net/tls/capabilities/capabilities_test.cpp b/vespalib/src/tests/net/tls/capabilities/capabilities_test.cpp index 4a20200c631..96d345a40f0 100644 --- a/vespalib/src/tests/net/tls/capabilities/capabilities_test.cpp +++ b/vespalib/src/tests/net/tls/capabilities/capabilities_test.cpp @@ -38,12 +38,14 @@ TEST("CapabilitySet instances are equality comparable") { } TEST("Can get underlying name of all Capability instances") { - EXPECT_EQUAL(Capability::content_storage_api().name(), "vespa.content.storage_api"sv); - EXPECT_EQUAL(Capability::content_document_api().name(), "vespa.content.document_api"sv); - EXPECT_EQUAL(Capability::content_search_api().name(), "vespa.content.search_api"sv); - EXPECT_EQUAL(Capability::slobrok_api().name(), "vespa.slobrok.api"sv); - EXPECT_EQUAL(Capability::content_status_pages().name(), "vespa.content.status_pages"sv); - EXPECT_EQUAL(Capability::content_metrics_api().name(), "vespa.content.metrics_api"sv); + EXPECT_EQUAL(Capability::content_storage_api().name(), "vespa.content.storage_api"sv); + EXPECT_EQUAL(Capability::content_document_api().name(), "vespa.content.document_api"sv); + EXPECT_EQUAL(Capability::content_search_api().name(), "vespa.content.search_api"sv); + EXPECT_EQUAL(Capability::content_proton_admin_api().name(), "vespa.content.proton_admin_api"sv); + EXPECT_EQUAL(Capability::slobrok_api().name(), "vespa.slobrok.api"sv); + EXPECT_EQUAL(Capability::config_sentinel_api().name(), "vespa.config.sentinel_api"sv); + EXPECT_EQUAL(Capability::content_status_pages().name(), "vespa.content.status_pages"sv); + EXPECT_EQUAL(Capability::content_metrics_api().name(), "vespa.content.metrics_api"sv); EXPECT_EQUAL(Capability::content_cluster_controller_internal_state_api().name(), "vespa.content.cluster_controller.internal_state_api"sv); } @@ -69,12 +71,14 @@ void check_capability_set_mapping(const std::string& name, CapabilitySet expecte } TEST("All known capabilities can be looked up by name") { - check_capability_mapping("vespa.content.storage_api", Capability::content_storage_api()); - check_capability_mapping("vespa.content.document_api", Capability::content_document_api()); - check_capability_mapping("vespa.content.search_api", Capability::content_search_api()); - check_capability_mapping("vespa.slobrok.api", Capability::slobrok_api()); - check_capability_mapping("vespa.content.status_pages", Capability::content_status_pages()); - check_capability_mapping("vespa.content.metrics_api", Capability::content_metrics_api()); + check_capability_mapping("vespa.content.storage_api", Capability::content_storage_api()); + check_capability_mapping("vespa.content.document_api", Capability::content_document_api()); + check_capability_mapping("vespa.content.search_api", Capability::content_search_api()); + check_capability_mapping("vespa.content.proton_admin_api", Capability::content_proton_admin_api()); + check_capability_mapping("vespa.slobrok.api", Capability::slobrok_api()); + check_capability_mapping("vespa.config.sentinel_api", Capability::config_sentinel_api()); + check_capability_mapping("vespa.content.status_pages", Capability::content_status_pages()); + check_capability_mapping("vespa.content.metrics_api", Capability::content_metrics_api()); check_capability_mapping("vespa.content.cluster_controller.internal_state_api", Capability::content_cluster_controller_internal_state_api()); } diff --git a/vespalib/src/vespa/vespalib/net/tls/capability.cpp b/vespalib/src/vespa/vespalib/net/tls/capability.cpp index 64de250e60d..db357ffd820 100644 --- a/vespalib/src/vespa/vespalib/net/tls/capability.cpp +++ b/vespalib/src/vespa/vespalib/net/tls/capability.cpp @@ -16,8 +16,10 @@ constexpr std::array<std::string_view, Capability::max_value_count()> capability "vespa.content.storage_api"sv, "vespa.content.document_api"sv, "vespa.content.search_api"sv, + "vespa.content.proton_admin_api"sv, "vespa.content.cluster_controller.internal_state_api"sv, "vespa.slobrok.api"sv, + "vespa.config.sentinel_api"sv, "vespa.content.status_pages"sv, "vespa.content.metrics_api"sv, }; @@ -40,8 +42,10 @@ std::optional<Capability> Capability::find_capability(const string& cap_name) no {"vespa.content.storage_api", content_storage_api()}, {"vespa.content.document_api", content_document_api()}, {"vespa.content.search_api", content_search_api()}, + {"vespa.content.proton_admin_api", content_proton_admin_api()}, {"vespa.content.cluster_controller.internal_state_api", content_cluster_controller_internal_state_api()}, {"vespa.slobrok.api", slobrok_api()}, + {"vespa.config.sentinel_api", config_sentinel_api()}, {"vespa.content.status_pages", content_status_pages()}, {"vespa.content.metrics_api", content_metrics_api()}, }); diff --git a/vespalib/src/vespa/vespalib/net/tls/capability.h b/vespalib/src/vespa/vespalib/net/tls/capability.h index 842e3f3a363..3b4f7d79264 100644 --- a/vespalib/src/vespa/vespalib/net/tls/capability.h +++ b/vespalib/src/vespa/vespalib/net/tls/capability.h @@ -23,12 +23,15 @@ private: // Each ID value corresponds to a unique single-bit position. // These values shall never be exposed outside the running process, i.e. they // must be possible to change arbitrarily internally across versions. + // Changes must be reflected in capabilities_test.cpp enum class Id : uint32_t { ContentStorageApi = 0, // Must start at zero ContentDocumentApi, ContentSearchApi, + ContentProtonAdminApi, ContentClusterControllerInternalStateApi, SlobrokApi, + ConfigSentinelApi, ContentStatusPages, ContentMetricsApi, // When adding a capability ID to the end, max_value_count() MUST be updated @@ -80,6 +83,10 @@ public: return Capability(Id::ContentSearchApi); } + constexpr static Capability content_proton_admin_api() noexcept { + return Capability(Id::ContentProtonAdminApi); + } + constexpr static Capability content_cluster_controller_internal_state_api() noexcept { return Capability(Id::ContentClusterControllerInternalStateApi); } @@ -88,6 +95,10 @@ public: return Capability(Id::SlobrokApi); } + constexpr static Capability config_sentinel_api() noexcept { + return Capability(Id::ConfigSentinelApi); + } + constexpr static Capability content_status_pages() noexcept { return Capability(Id::ContentStatusPages); } |