-
Notifications
You must be signed in to change notification settings - Fork 849
JSON-RPC: Add support for handler to pass information about the specifics when registering. #8865
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JSON-RPC: Add support for handler to pass information about the specifics when registering. #8865
Conversation
| structure. | ||
|
|
||
| File `jsonrpc.yaml` is a YAML format. The default configuration is: | ||
| File `jsonrpc.yaml` is a YAML format. The default configuration looks like: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So it's like a default imposter?
| int restricted; ///< Tells the RPC Manager if the call can be delivered or not based on the config rules. | ||
| } auth; | ||
| } TSRPCHandlerOptions; | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this in apidefs.h ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So can be directly used from both sides(core & plugins). isn't that the point of apidefs.h?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK but I don't see this used as the type of any parameter to any TS API function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although it sets the base, this change does not include any changes on the plugin API. We have a separated PR for that, which still didn't make it into 10-Dev. I will update that PR after we agree on this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So you're saying it's for future use?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So you're saying it's for future use?
short answer: yes.
long asnwer:
The future is here: #8630, I will update 8630 after this one is done.
At yahoo we are running the rpc TS API in production since quite some time now, so all this changes will get into our yahoo ats as well very soon.
| [this](std::string_view const &id, const YAML::Node &req) -> ts::Rv<YAML::Node> { | ||
| return get_files_registry_rpc_endpoint(id, req); | ||
| }, | ||
| &rpc::core_ats_rpc_service_provider_handle, {{rpc::NON_RESTRICTED_API}}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems dangerous, capturing the this pointer, tricky to keep it from not becoming stale due to object destruction:
wkaras ~/REPOS/MISC/LAMBDA_THIS
$ cat x.cc
#include <iostream>
struct A;
A *ga;
struct A
{
int i = 5;
auto f() { return [this]() -> A & { return *this; }; }
auto g()
{
A a{*this};
return [a]() -> int { return a.i; };
}
};
int main()
{
ga = new A;
auto lambda_f = ga->f();
auto lambda_g = ga->g();
delete ga;
if (&lambda_f() == ga)
{
std::cout << "Dangling pointer!\n";
}
std::cout << lambda_g() << '\n';
return 0;
}
wkaras ~/REPOS/MISC/LAMBDA_THIS
$ gcc -Wall -Wextra -pedantic x.cc -lstdc++
wkaras ~/REPOS/MISC/LAMBDA_THIS
$ ./a.out
Dangling pointer!
5
wkaras ~/REPOS/MISC/LAMBDA_THIS
$
The g() member function shows a safe way to capture an object whose class the function is a member of.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FileManager is now a singleton class, by the time it's gone it shouldn't dangle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest then that you make the FileManager constructor private.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| static constexpr auto logTag = "rpc"; | ||
| static constexpr auto logTagMsg = "rpc.msg"; | ||
| // --- Helpers | ||
| std::pair<ts::Errata, error::RPCErrorCode> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't pair kinda deprecated is favor of tuple?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Meh. The better question is, why pair instead of the struct Error defined earlier.
mgmt2/rpc/jsonrpc/JsonRPC.h
Outdated
| template <typename Func> | ||
| inline bool | ||
| add_method_handler(const std::string &name, Func &&call, const RPCRegistryInfo *info = nullptr) | ||
| add_method_handler(const std::string &name, Func &&call, const RPCRegistryInfo *info, TSRPCHandlerOptions const &opt) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this seems to get called with a string literal, you could avoid a heap allocation if the type was std::string_view.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Walt.
yes, I would probably have them constant defined and not use the name as literal in the call anyway, I wasn't very worry about this as it only happens at startup and at the end it will allocate to hold it internally.
I may add a new pr with some tweaks I have noted, takling this too possibly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
f60613c to
b3151ff
Compare
|
[approve ci autest] |
2 similar comments
|
[approve ci autest] |
|
[approve ci autest] |
b3151ff to
0be22ba
Compare
mgmt2/rpc/jsonrpc/Context.h
Outdated
|
|
||
| namespace rpc | ||
| { | ||
| const bool RESTRICTED_API{true}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not constexpr?
mgmt2/rpc/jsonrpc/Context.h
Outdated
| /// @param options Registered handler options. | ||
| /// @return ts::Errata The errata will be filled by each of the registered checkers, if there was any issue validating the | ||
| /// call, then the errata reflects that. | ||
| ts::Errata any_blockers(TSRPCHandlerOptions const &options) const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be better named "is_blocked".
mgmt2/rpc/jsonrpc/Defs.h
Outdated
|
|
||
| struct RPCResponseInfo { | ||
| RPCResponseInfo(std::optional<std::string> const &id_) : id(id_) {} | ||
| RPCResponseInfo(std::optional<std::string> const &id_) : id{id_} {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why use std::optional with std::string? Isn't an empty string the same as not having one?
mgmt2/rpc/jsonrpc/Defs.h
Outdated
| struct RPCResponseInfo { | ||
| RPCResponseInfo(std::optional<std::string> const &id_) : id(id_) {} | ||
| RPCResponseInfo(std::optional<std::string> const &id_) : id{id_} {} | ||
| RPCResponseInfo(std::error_code const &ec_) : error{ec_, {}} {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::optional is even odder if you have these overloads - why not have a constructor with no parameters at all?
| RPCHandlerResponse callResult; | ||
| std::error_code rpcError; | ||
| struct Error { | ||
| std::error_code ec; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can fix this once we switch to swoc::Errata. It supports embedding the ec in the Errata.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is on my TODO list once we have libswoc in our private repo.
… a new JSON-RPC endpoint handler. To support this a new class Context is introduced as well as a Handler option class, this changes sets the base for future work around the handler registration and the Plugin API.
…ration. It also fixes some bad links and typos.
…can now decide if they want to be administrative restricted or not. Add documentation support for this.
0be22ba to
80d52bf
Compare
80d52bf to
f532c93
Compare
So there are two changes here, I have them both in the same PR as the last one depends on the first one.
1 - We needed a way to let the handler to pass information to the registration which at some point later on could be validated or used in any way, so this is a base change for further checks(like client's socket credentials). This defines a new type in the
apidefs.h.inbecause this will eventually be used from the Plugin API.Please check this commit to see this changes only.
There is also a documentation update here in this commit
2 - The main driver for this change: adding peer's credentials check on rpc calls.
Context:
When moved from
traffic_mangeradmin socket to the newJSONRPCapi, the management api restrictions were left out, the only restriction in place was related to the creation of the jsonrpc unix socket(either700or777) just at user level losing the original capability to check the socket’s peers credentials and allow or deny certain operations, like read only calls(record lookup) vs operation that can change the state of ATS(like a record set). This was a useful method to allow some non-root users to perform some actions while we leave root users to have full access to the API. So this PR also includes the same feature but now on the JSONRPC node.Please check this commit to see this changes only.
This is an example of the output you will get when if request an unauthorized rpc method:
The raw json would look like: