mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-29 23:45:51 +00:00
Config improvements:
* More fine-grained Section mutators * Add remap for mapping legacy single sections to key value pairs * Add output stream operators for BasicConfig and Section * Allow section values to be overwritten from command line * Update rpc key/value configs from command line * Add RPC::Setup with defaults and remap legacy rpc sections
This commit is contained in:
@@ -309,7 +309,8 @@ public:
|
||||
, m_deprecatedUNL (make_UniqueNodeList (*m_jobQueue))
|
||||
|
||||
, m_rpcHTTPServer (make_RPCHTTPServer (*m_networkOPs,
|
||||
*m_jobQueue, *m_networkOPs, *m_resourceManager))
|
||||
*m_jobQueue, *m_networkOPs, *m_resourceManager,
|
||||
setup_RPC(getConfig()["rpc"])))
|
||||
|
||||
// passive object, not a Service
|
||||
, m_rpcServerHandler (*m_networkOPs, *m_resourceManager)
|
||||
|
||||
@@ -344,6 +344,7 @@ int run (int argc, char** argv)
|
||||
if (vm.count ("rpc_ip"))
|
||||
{
|
||||
getConfig ().setRpcIpAndOptionalPort (vm ["rpc_ip"].as <std::string> ());
|
||||
getConfig().overwrite("rpc", "ip", vm["rpc_ip"].as<std::string>());
|
||||
}
|
||||
|
||||
// Override the RPC destination port number
|
||||
@@ -352,6 +353,7 @@ int run (int argc, char** argv)
|
||||
{
|
||||
// VFALCO TODO This should be a short.
|
||||
getConfig ().setRpcPort (vm ["rpc_port"].as <int> ());
|
||||
getConfig().overwrite("rpc", "port", vm["rpc_port"].as<std::string>());
|
||||
}
|
||||
|
||||
if (vm.count ("quorum"))
|
||||
|
||||
@@ -38,9 +38,11 @@ public:
|
||||
RPCServerHandler m_deprecatedHandler;
|
||||
HTTP::Server m_server;
|
||||
std::unique_ptr <RippleSSLContext> m_context;
|
||||
RPC::Setup setup_;
|
||||
|
||||
RPCHTTPServerImp (Stoppable& parent, JobQueue& jobQueue,
|
||||
NetworkOPs& networkOPs, Resource::Manager& resourceManager)
|
||||
NetworkOPs& networkOPs, Resource::Manager& resourceManager,
|
||||
RPC::Setup const& setup)
|
||||
: RPCHTTPServer (parent)
|
||||
, m_resourceManager (resourceManager)
|
||||
, m_journal (deprecatedLogs().journal("HTTP-RPC"))
|
||||
@@ -48,18 +50,13 @@ public:
|
||||
, m_networkOPs (networkOPs)
|
||||
, m_deprecatedHandler (networkOPs, resourceManager)
|
||||
, m_server (*this, deprecatedLogs().journal("HTTP"))
|
||||
, setup_ (setup)
|
||||
{
|
||||
if (getConfig ().RPC_SECURE == 0)
|
||||
{
|
||||
m_context.reset (RippleSSLContext::createBare ());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (setup_.secure)
|
||||
m_context.reset (RippleSSLContext::createAuthenticated (
|
||||
getConfig ().RPC_SSL_KEY,
|
||||
getConfig ().RPC_SSL_CERT,
|
||||
getConfig ().RPC_SSL_CHAIN));
|
||||
}
|
||||
setup_.ssl_key, setup_.ssl_cert, setup_.ssl_chain));
|
||||
else
|
||||
m_context.reset (RippleSSLContext::createBare());
|
||||
}
|
||||
|
||||
~RPCHTTPServerImp()
|
||||
@@ -70,10 +67,9 @@ public:
|
||||
void
|
||||
setup (beast::Journal journal) override
|
||||
{
|
||||
if (! getConfig ().getRpcIP().empty () &&
|
||||
getConfig ().getRpcPort() != 0)
|
||||
if (! setup_.ip.empty() && setup_.port != 0)
|
||||
{
|
||||
auto ep = beast::IP::Endpoint::from_string (getConfig().getRpcIP());
|
||||
auto ep = beast::IP::Endpoint::from_string (setup_.ip);
|
||||
|
||||
// VFALCO TODO IP address should not have an "unspecified" state
|
||||
//if (! is_unspecified (ep))
|
||||
@@ -81,8 +77,8 @@ public:
|
||||
HTTP::Port port;
|
||||
port.security = HTTP::Port::Security::allow_ssl;
|
||||
port.addr = ep.at_port(0);
|
||||
if (getConfig ().getRpcPort() != 0)
|
||||
port.port = getConfig ().getRpcPort();
|
||||
if (setup_.port != 0)
|
||||
port.port = setup_.port;
|
||||
else
|
||||
port.port = ep.port();
|
||||
port.context = m_context.get ();
|
||||
@@ -123,7 +119,7 @@ public:
|
||||
onAccept (HTTP::Session& session) override
|
||||
{
|
||||
// Reject non-loopback connections if RPC_ALLOW_REMOTE is not set
|
||||
if (! getConfig().RPC_ALLOW_REMOTE &&
|
||||
if (! setup_.allow_remote &&
|
||||
! beast::IP::is_loopback (session.remoteAddress()))
|
||||
{
|
||||
session.close (false);
|
||||
@@ -295,10 +291,11 @@ RPCHTTPServer::RPCHTTPServer (Stoppable& parent)
|
||||
|
||||
std::unique_ptr <RPCHTTPServer>
|
||||
make_RPCHTTPServer (beast::Stoppable& parent, JobQueue& jobQueue,
|
||||
NetworkOPs& networkOPs, Resource::Manager& resourceManager)
|
||||
NetworkOPs& networkOPs, Resource::Manager& resourceManager,
|
||||
RPC::Setup const& setup)
|
||||
{
|
||||
return std::make_unique <RPCHTTPServerImp> (
|
||||
parent, jobQueue, networkOPs, resourceManager);
|
||||
parent, jobQueue, networkOPs, resourceManager, setup);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#ifndef RIPPLE_APP_RPCHTTPSERVER_H_INCLUDED
|
||||
#define RIPPLE_APP_RPCHTTPSERVER_H_INCLUDED
|
||||
|
||||
#include <ripple/core/Config.h>
|
||||
#include <beast/utility/Journal.h>
|
||||
#include <beast/utility/PropertyStream.h>
|
||||
#include <beast/cxx14/memory.h> // <memory>
|
||||
@@ -48,7 +49,8 @@ public:
|
||||
|
||||
std::unique_ptr <RPCHTTPServer>
|
||||
make_RPCHTTPServer (beast::Stoppable& parent, JobQueue& jobQueue,
|
||||
NetworkOPs& networkOPs, Resource::Manager& resourceManager);
|
||||
NetworkOPs& networkOPs, Resource::Manager& resourceManager,
|
||||
RPC::Setup const& setup);
|
||||
|
||||
} // ripple
|
||||
|
||||
|
||||
@@ -93,9 +93,30 @@ public:
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/** Overwrite a key/value pair with a command line argument
|
||||
If the section does not exist it is created.
|
||||
The previous value, if any, is overwritten.
|
||||
*/
|
||||
void
|
||||
overwrite (std::string const& section, std::string const& key,
|
||||
std::string const& value);
|
||||
|
||||
friend
|
||||
std::ostream&
|
||||
operator<< (std::ostream& ss, BasicConfig const& c);
|
||||
|
||||
protected:
|
||||
void
|
||||
build (IniFileSections const& ifs);
|
||||
|
||||
/** Insert a legacy single section as a key/value pair.
|
||||
Does nothing if the section does not exist, or does not contain
|
||||
a single line that is not a key/value pair.
|
||||
@deprecated
|
||||
*/
|
||||
void
|
||||
remap (std::string const& legacy_section,
|
||||
std::string const& key, std::string const& new_section);
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -456,10 +477,37 @@ public:
|
||||
int getSize (SizedItemName);
|
||||
void setup (std::string const& strConf, bool bQuiet);
|
||||
void load ();
|
||||
|
||||
private:
|
||||
void build_legacy();
|
||||
};
|
||||
|
||||
extern Config& getConfig ();
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace RPC {
|
||||
|
||||
struct Setup
|
||||
{
|
||||
bool allow_remote = false;
|
||||
std::string admin_user;
|
||||
std::string admin_password;
|
||||
std::string ip;
|
||||
int port = 5001;
|
||||
std::string user;
|
||||
std::string password;
|
||||
bool secure = false;
|
||||
std::string ssl_cert;
|
||||
std::string ssl_chain;
|
||||
std::string ssl_key;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
RPC::Setup
|
||||
setup_RPC (Section const& s);
|
||||
|
||||
} // ripple
|
||||
|
||||
#endif
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <beast/utility/ci_char_traits.h>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <map>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -42,6 +43,32 @@ public:
|
||||
/** Create an empty section. */
|
||||
Section() = default;
|
||||
|
||||
/** Returns the number of key/value pairs. */
|
||||
std::size_t
|
||||
keys() const
|
||||
{
|
||||
return map_.size();
|
||||
}
|
||||
|
||||
/** Returns all the lines in the section. */
|
||||
std::vector <std::string> const&
|
||||
lines() const
|
||||
{
|
||||
return lines_;
|
||||
}
|
||||
|
||||
/** Set a key/value pair.
|
||||
The previous value is discarded.
|
||||
*/
|
||||
void
|
||||
set (std::string const& key, std::string const& value);
|
||||
|
||||
/** Append a line to this section.
|
||||
If the line can be parsed as a key/value pair it is added to the map.
|
||||
*/
|
||||
void
|
||||
append (std::string const& line);
|
||||
|
||||
/** Append a set of lines to this section.
|
||||
Parsable key/value pairs are also added to the map.
|
||||
*/
|
||||
@@ -57,6 +84,10 @@ public:
|
||||
*/
|
||||
std::pair <std::string, bool>
|
||||
find (std::string const& name) const;
|
||||
|
||||
friend
|
||||
std::ostream&
|
||||
operator<< (std::ostream&, Section const& section);
|
||||
};
|
||||
|
||||
/** Set a value from a configuration Section
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <ripple/net/HTTPClient.h>
|
||||
#include <beast/http/ParsedURL.h>
|
||||
#include <beast/module/core/text/LexicalCast.h>
|
||||
#include <beast/streams/debug_ostream.h>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/format.hpp>
|
||||
@@ -31,6 +32,10 @@
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#ifndef DUMP_CONFIG
|
||||
#define DUMP_CONFIG 0
|
||||
#endif
|
||||
|
||||
namespace ripple {
|
||||
|
||||
//
|
||||
@@ -237,17 +242,48 @@ BasicConfig::section (std::string const& name) const
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
void
|
||||
BasicConfig::remap (std::string const& legacy_section,
|
||||
std::string const& key, std::string const& new_section)
|
||||
{
|
||||
auto const iter = map_.find (legacy_section);
|
||||
if (iter == map_.end())
|
||||
return;
|
||||
if (iter->second.keys() != 0)
|
||||
return;
|
||||
if (iter->second.lines().size() != 1)
|
||||
return;
|
||||
auto& s = map_[new_section];
|
||||
s.append (iter->second.lines().front());
|
||||
s.set (key, iter->second.lines().front());
|
||||
}
|
||||
|
||||
void
|
||||
BasicConfig::overwrite (std::string const& section, std::string const& key,
|
||||
std::string const& value)
|
||||
{
|
||||
auto const result = map_.emplace (section, Section{});
|
||||
result.first->second.set (key, value);
|
||||
}
|
||||
|
||||
void
|
||||
BasicConfig::build (IniFileSections const& ifs)
|
||||
{
|
||||
for (auto const& entry : ifs)
|
||||
{
|
||||
auto const result = map_.insert (std::make_pair (
|
||||
entry.first, Section{}));
|
||||
auto const result = map_.emplace (entry.first, Section{});
|
||||
result.first->second.append (entry.second);
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<< (std::ostream& ss, BasicConfig const& c)
|
||||
{
|
||||
for (auto const& s : c.map_)
|
||||
ss << "[" << s.first << "]\n" << s.second;
|
||||
return ss;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Config (DEPRECATED)
|
||||
@@ -458,6 +494,7 @@ void Config::load ()
|
||||
std::string strTemp;
|
||||
|
||||
build (secConfig);
|
||||
build_legacy();
|
||||
|
||||
// XXX Leak
|
||||
IniFileSections::mapped_type* smtTmp;
|
||||
@@ -973,4 +1010,55 @@ beast::File const& Config::getModuleDatabasePath ()
|
||||
return m_moduleDbPath;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
Config::build_legacy ()
|
||||
{
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// [rpc]
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
remap("rpc_allow_remote", "allow_remote", "rpc");
|
||||
//remap("rpc_admin_allow", "admin_allow", "rpc"); // Not a key-value pair
|
||||
remap("rpc_admin_user", "admin_user", "rpc");
|
||||
remap("rpc_admin_password", "admin_password", "rpc");
|
||||
remap("rpc_ip", "ip", "rpc");
|
||||
remap("rpc_port", "port", "rpc");
|
||||
remap("rpc_user", "user", "rpc");
|
||||
remap("rpc_password", "password", "rpc");
|
||||
//remap("rpc_startup", "startup", "rpc"); // Not a key-value pair
|
||||
remap("rpc_secure", "secure", "rpc");
|
||||
remap("rpc_ssl_cert", "ssl_cert", "rpc");
|
||||
remap("rpc_ssl_chain", "ssl_chain", "rpc");
|
||||
remap("rpc_ssl_key", "ssl_key", "rpc");
|
||||
|
||||
#if DUMP_CONFIG
|
||||
beast::debug_ostream log;
|
||||
log << (BasicConfig const&)*this;
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
RPC::Setup
|
||||
setup_RPC (Section const& s)
|
||||
{
|
||||
RPC::Setup c;
|
||||
set (c.allow_remote, "allow_remote", s);
|
||||
set (c.admin_user, "admin_user", s);
|
||||
set (c.admin_password, "admin_password", s);
|
||||
set (c.ip, "ip", s);
|
||||
set (c.port, "port", s);
|
||||
set (c.user, "user", s);
|
||||
set (c.password, "password", s);
|
||||
set (c.secure, "secure", s);
|
||||
set (c.ssl_cert, "ssl_cert", s);
|
||||
set (c.ssl_chain, "ssl_chain", s);
|
||||
set (c.ssl_key, "ssl_key", s);
|
||||
return c;
|
||||
}
|
||||
|
||||
} // ripple
|
||||
|
||||
@@ -19,11 +19,20 @@
|
||||
|
||||
#include <ripple/core/Section.h>
|
||||
#include <boost/regex.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
void
|
||||
Section::append (std::vector <std::string> const& lines)
|
||||
Section::set (std::string const& key, std::string const& value)
|
||||
{
|
||||
auto const result = map_.emplace (key, value);
|
||||
if (! result.second)
|
||||
result.first->second = value;
|
||||
}
|
||||
|
||||
void
|
||||
Section::append (std::string const& line)
|
||||
{
|
||||
// <key> '=' <value>
|
||||
static boost::regex const re1 (
|
||||
@@ -38,25 +47,18 @@ Section::append (std::vector <std::string> const& lines)
|
||||
, boost::regex_constants::optimize
|
||||
);
|
||||
|
||||
lines_.reserve (lines_.size() + lines.size());
|
||||
for (auto const& line : lines)
|
||||
{
|
||||
boost::smatch match;
|
||||
lines_.push_back (line);
|
||||
if (boost::regex_match (line, match, re1))
|
||||
{
|
||||
/*auto const result =*/ map_.emplace (
|
||||
std::make_pair (match[1], match[2]));
|
||||
#if 0
|
||||
if (! result.second)
|
||||
{
|
||||
// If we decide on how to merge values we can do it here.
|
||||
}
|
||||
beast::debug_ostream log;
|
||||
//log << "\"" << match[1] << "\" = \"" << match[2] << "\"";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
set (match[1], match[2]);
|
||||
}
|
||||
|
||||
void
|
||||
Section::append (std::vector <std::string> const& lines)
|
||||
{
|
||||
lines_.reserve (lines_.size() + lines.size());
|
||||
std::for_each (lines.begin(), lines.end(),
|
||||
[&](std::string const& line) { this->append (line); });
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -74,4 +76,14 @@ Section::find (std::string const& name) const
|
||||
return {iter->second, true};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
std::ostream&
|
||||
operator<< (std::ostream& os, Section const& section)
|
||||
{
|
||||
for (auto const& kv : section.map_)
|
||||
os << kv.first << "=" << kv.second << "\n";
|
||||
return os;
|
||||
}
|
||||
|
||||
} // ripple
|
||||
|
||||
Reference in New Issue
Block a user