experimental #2: now interpolates environment variables in config object file
parent
2871f8f8c1
commit
ebdb9d643a
|
@ -2,3 +2,8 @@
|
||||||
cmake-build-debug
|
cmake-build-debug
|
||||||
.idea
|
.idea
|
||||||
./.idea
|
./.idea
|
||||||
|
./cmake-build-release/
|
||||||
|
cmake-build-release
|
||||||
|
CMakeFiles
|
||||||
|
CMakeLists.txt
|
||||||
|
Makefile
|
|
@ -4,4 +4,5 @@ set(CMAKE_CXX_STANDARD 11)
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++1z -O0 -DDEBUG=1")
|
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++1z -O0 -DDEBUG=1")
|
||||||
set(SOURCE_FILES Rex.cpp src/loaders/abstract/loaders.cpp src/loaders/abstract/loaders.h src/json/jsoncpp.cpp src/loaders/low_level/JSON_Loader.cpp src/loaders/low_level/JSON_Loader.h src/loaders/misc/helpers.cpp src/loaders/misc/helpers.h src/loaders/abstract/Suite.cpp src/loaders/abstract/Suite.h src/loaders/abstract/Plan.cpp src/loaders/abstract/Plan.h src/loaders/abstract/Conf.cpp src/loaders/abstract/Conf.h src/loaders/abstract/Unit.cpp src/loaders/abstract/Unit.h src/loaders/abstract/Task.cpp src/loaders/abstract/Task.h src/Sproc/Sproc.cpp src/Sproc/Sproc.h src/Logger/Logger.cpp src/Logger/Logger.h)
|
set(SOURCE_FILES Rex.cpp src/loaders/abstract/loaders.cpp src/loaders/abstract/loaders.h src/json/jsoncpp.cpp src/loaders/low_level/JSON_Loader.cpp src/loaders/low_level/JSON_Loader.h src/loaders/misc/helpers.cpp src/loaders/misc/helpers.h src/loaders/abstract/Suite.cpp src/loaders/abstract/Suite.h src/loaders/abstract/Plan.cpp src/loaders/abstract/Plan.h src/loaders/abstract/Conf.cpp src/loaders/abstract/Conf.h src/loaders/abstract/Unit.cpp src/loaders/abstract/Unit.h src/loaders/abstract/Task.cpp src/loaders/abstract/Task.h src/Sproc/Sproc.cpp src/Sproc/Sproc.h src/Logger/Logger.cpp src/Logger/Logger.h)
|
||||||
|
|
||||||
|
|
||||||
add_executable(rex ${SOURCE_FILES})
|
add_executable(rex ${SOURCE_FILES})
|
||||||
|
|
|
@ -70,6 +70,8 @@ protected:
|
||||||
Conf::Conf(std::string filename, int LOG_LEVEL ): JSON_Loader(LOG_LEVEL ), slog(LOG_LEVEL, "_conf_" )
|
Conf::Conf(std::string filename, int LOG_LEVEL ): JSON_Loader(LOG_LEVEL ), slog(LOG_LEVEL, "_conf_" )
|
||||||
{
|
{
|
||||||
this->LOG_LEVEL = LOG_LEVEL;
|
this->LOG_LEVEL = LOG_LEVEL;
|
||||||
|
std::string jval_s;
|
||||||
|
bool jval_b;
|
||||||
|
|
||||||
// prepare context spaghetti
|
// prepare context spaghetti
|
||||||
this->override_context = false;
|
this->override_context = false;
|
||||||
|
@ -83,65 +85,59 @@ Conf::Conf(std::string filename, int LOG_LEVEL ): JSON_Loader(LOG_LEVEL ), slog(
|
||||||
throw ConfigLoadException("Config file not found.");
|
throw ConfigLoadException("Config file not found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->get_serialized(this->config_version, "config_version" ) != 0)
|
|
||||||
{
|
|
||||||
throw ConfigLoadException("config_version string is not set in the config file supplied: " + filename);
|
|
||||||
}
|
|
||||||
if ( this->config_version.asString() != VERSION_STRING )
|
|
||||||
{
|
|
||||||
throw ConfigLoadException("config_version string expected was " + std::string(VERSION_STRING) + " in: " + filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
// find the path to the unit definitions file
|
// find the path to the unit definitions file
|
||||||
if (this->get_serialized(this->units_path, "units_path" ) != 0 )
|
if (this->get_string(jval_s, "units_path") != 0 )
|
||||||
{
|
{ throw ConfigLoadException("units_path string is not set in the config file supplied: " + filename); } else {
|
||||||
throw ConfigLoadException("units_path string is not set in the config file supplied: " + filename);
|
this->units_path = jval_s;
|
||||||
}
|
}
|
||||||
|
jval_s = {0};
|
||||||
|
|
||||||
// find the path to logs directory
|
// find the path to logs directory
|
||||||
if (this->get_serialized(this->logs_path, "logs_path" ) != 0 )
|
if (this->get_string(jval_s, "logs_path") != 0 )
|
||||||
{
|
{ throw ConfigLoadException("logs_path string is not set in the config file supplied: " + filename); } else {
|
||||||
throw ConfigLoadException("logs_path string is not set in the config file supplied: " + filename);
|
this->logs_path = jval_s;
|
||||||
}
|
}
|
||||||
|
jval_s = {0};
|
||||||
|
|
||||||
if ( this->get_serialized(this->override_execution_context, "execution_context_override" ) != 0 )
|
if (this->get_bool(jval_b, "execution_context_override") != 0 )
|
||||||
{
|
{ throw ConfigLoadException("execution_context_override boolean is not set in the config file supplied: " + filename); } else {
|
||||||
throw ConfigLoadException("execution_context_override boolean is not set in the config file supplied: " + filename);
|
this->override_context = jval_b;
|
||||||
} else {
|
|
||||||
this->override_context = true;
|
|
||||||
}
|
}
|
||||||
|
jval_b = {0};
|
||||||
|
|
||||||
if ( this->get_serialized(this->execution_context, "execution_context" ) != 0 )
|
if (this->get_string(jval_s, "execution_context") != 0 )
|
||||||
{
|
{ throw ConfigLoadException("execution_context string is not set in the config file supplied: " + filename); } else {
|
||||||
throw ConfigLoadException("execution_context string is not set in the config file supplied: " + filename);
|
if ( ! is_dir( jval_s ) ) { throw ConfigLoadException( "The execution context supplied is an invalid directory."); } else {
|
||||||
} else {
|
this->execution_context = jval_s;
|
||||||
if ( is_dir( this->execution_context.asString() ) ) {
|
|
||||||
this->execution_context_literal = this->execution_context.asString();
|
|
||||||
} else {
|
|
||||||
throw ConfigLoadException( "The execution context supplied is an invalid directory.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
jval_s = {0};
|
||||||
|
|
||||||
|
interpolate( this->units_path );
|
||||||
|
interpolate( this->logs_path );
|
||||||
|
interpolate( this->execution_context );
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Conf::has_context_override - Specifies whether or not the override context function is enabled in the Conf file.
|
/// Conf::has_context_override - Specifies whether or not the override context function is enabled in the Conf file.
|
||||||
bool Conf::has_context_override() {
|
bool Conf::has_context_override() {
|
||||||
return this->override_execution_context.asBool();
|
return this->override_execution_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Conf::get_execution_context - Specifies the path to the current working directory to set for all unit executions.
|
/// Conf::get_execution_context - Specifies the path to the current working directory to set for all unit executions.
|
||||||
std::string Conf::get_execution_context() {
|
std::string Conf::get_execution_context() {
|
||||||
return this->execution_context_literal;
|
return this->execution_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Conf::get_units_path - Retrieves the path to the Unit definition file from the application configuration file.
|
/// Conf::get_units_path - Retrieves the path to the Unit definition file from the application configuration file.
|
||||||
std::string Conf::get_units_path() { return this->units_path.asString(); }
|
std::string Conf::get_units_path() { return this->units_path; }
|
||||||
|
|
||||||
/// Conf::get_units_path - Retrieves the path to the Unit definition file from the application configuration file.
|
/// Conf::get_units_path - Retrieves the path to the Unit definition file from the application configuration file.
|
||||||
std::string Conf::get_logs_path() { return this->logs_path.asString(); }
|
std::string Conf::get_logs_path() { return this->logs_path; }
|
||||||
|
|
||||||
/// Conf::set_execution_context- Sets the execution context.
|
/// Conf::set_execution_context- Sets the execution context.
|
||||||
void Conf::set_execution_context(std::string execution_context )
|
void Conf::set_execution_context(std::string execution_context )
|
||||||
{
|
{
|
||||||
this->execution_context_literal = execution_context;
|
this->execution_context = execution_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,28 +28,26 @@
|
||||||
|
|
||||||
#define STRINGIZE2(s) #s
|
#define STRINGIZE2(s) #s
|
||||||
#define STRINGIZE(s) STRINGIZE2(s)
|
#define STRINGIZE(s) STRINGIZE2(s)
|
||||||
# define IMPL_CONFIG_VERSION 4
|
# define IMPL_CONFIG_VERSION 5
|
||||||
# define VERSION_STRING STRINGIZE(IMPL_CONFIG_VERSION)
|
# define VERSION_STRING STRINGIZE(IMPL_CONFIG_VERSION)
|
||||||
|
|
||||||
class Conf: public JSON_Loader
|
class Conf: public JSON_Loader
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
Json::Value plan_path;
|
std::string plan_path;
|
||||||
Json::Value units_path;
|
std::string units_path;
|
||||||
Json::Value execution_context;
|
std::string execution_context;
|
||||||
Json::Value config_version;
|
std::string logs_path;
|
||||||
Json::Value logs_path;
|
|
||||||
|
|
||||||
// flag to indicate if execution context should be overriden in config file
|
// flag to indicate if execution context should be overriden in config file
|
||||||
// if set to true rex should use whats in the config file for current working directory
|
// if set to true rex should use whats in the config file for current working directory
|
||||||
// if set to false, rex should use the current working directory at time of execution
|
// if set to false, rex should use the current working directory at time of execution
|
||||||
Json::Value override_execution_context;
|
bool override_execution_context;
|
||||||
|
|
||||||
bool override_context;
|
bool override_context;
|
||||||
std::string execution_context_literal;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Conf(std::string filename, int LOG_LEVEL );
|
Conf( std::string filename, int LOG_LEVEL );
|
||||||
|
|
||||||
bool has_context_override();
|
bool has_context_override();
|
||||||
|
|
||||||
|
|
|
@ -130,7 +130,7 @@ std::string JSON_Loader::as_string()
|
||||||
/// \param key - The JSON key name to assign the value to (the root of the json::value object by name)
|
/// \param key - The JSON key name to assign the value to (the root of the json::value object by name)
|
||||||
/// \param verbose - Whether or not to print verbose output to STDOUT.
|
/// \param verbose - Whether or not to print verbose output to STDOUT.
|
||||||
/// \return - Boolean indicator of success or failure (0|1)
|
/// \return - Boolean indicator of success or failure (0|1)
|
||||||
int JSON_Loader::get_serialized(Json::Value &input, std::string key )
|
int JSON_Loader::get_serialized( Json::Value &input, std::string key )
|
||||||
{
|
{
|
||||||
// throw if the class is not ready to be used.
|
// throw if the class is not ready to be used.
|
||||||
if ( ! this->populated ) { throw JSON_Loader_NotReady(); }
|
if ( ! this->populated ) { throw JSON_Loader_NotReady(); }
|
||||||
|
@ -147,6 +147,60 @@ int JSON_Loader::get_serialized(Json::Value &input, std::string key )
|
||||||
// verbose mode tells the user what key we were looking for.
|
// verbose mode tells the user what key we were looking for.
|
||||||
this->slog.log( E_FATAL, "Failed to find key '" + key + "'." );
|
this->slog.log( E_FATAL, "Failed to find key '" + key + "'." );
|
||||||
|
|
||||||
|
// exit code for failure
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// JSON_Loader::get_string - assigns the serialized representation of the value of a key (json::value)
|
||||||
|
///
|
||||||
|
/// \param input - A reference to the json::value object to receive the new value.
|
||||||
|
/// \param key - The JSON key name to assign the value to (the root of the json::value object by name)
|
||||||
|
/// \param verbose - Whether or not to print verbose output to STDOUT.
|
||||||
|
/// \return - Boolean indicator of success or failure (0|1)
|
||||||
|
int JSON_Loader::get_string( std::string &input, std::string key )
|
||||||
|
{
|
||||||
|
// throw if the class is not ready to be used.
|
||||||
|
if ( ! this->populated ) { throw JSON_Loader_NotReady(); }
|
||||||
|
|
||||||
|
if ( this->json_root.isMember( key ) )
|
||||||
|
{
|
||||||
|
// key was found so return it to the passed input ref
|
||||||
|
input = this->json_root[ key ].asString();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// key was not found
|
||||||
|
|
||||||
|
// verbose mode tells the user what key we were looking for.
|
||||||
|
this->slog.log( E_FATAL, "Failed to find key '" + key + "'." );
|
||||||
|
|
||||||
|
// exit code for failure
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// JSON_Loader::get_bool - assigns the serialized representation of the value of a key (json::value)
|
||||||
|
///
|
||||||
|
/// \param input - A reference to the json::value object to receive the new value.
|
||||||
|
/// \param key - The JSON key name to assign the value to (the root of the json::value object by name)
|
||||||
|
/// \param verbose - Whether or not to print verbose output to STDOUT.
|
||||||
|
/// \return - Boolean indicator of success or failure (0|1)
|
||||||
|
int JSON_Loader::get_bool( bool & input, std::string key )
|
||||||
|
{
|
||||||
|
// throw if the class is not ready to be used.
|
||||||
|
if ( ! this->populated ) { throw JSON_Loader_NotReady(); }
|
||||||
|
|
||||||
|
if ( this->json_root.isMember( key ) )
|
||||||
|
{
|
||||||
|
// key was found so return it to the passed input ref
|
||||||
|
input = this->json_root[ key ].asBool();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// key was not found
|
||||||
|
|
||||||
|
// verbose mode tells the user what key we were looking for.
|
||||||
|
this->slog.log( E_FATAL, "Failed to find key '" + key + "'." );
|
||||||
|
|
||||||
// exit code for failure
|
// exit code for failure
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
|
@ -50,7 +50,9 @@ class JSON_Loader
|
||||||
std::string as_string();
|
std::string as_string();
|
||||||
|
|
||||||
// safely handle deserialized type retrieval (if we want it to be safe)
|
// safely handle deserialized type retrieval (if we want it to be safe)
|
||||||
int get_serialized(Json::Value &input, std::string key );
|
int get_serialized( Json::Value & input, std::string key );
|
||||||
|
int get_string(std::string & input, std::string key );
|
||||||
|
int get_bool(bool & input, std::string key );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Logger slog;
|
Logger slog;
|
||||||
|
|
|
@ -56,4 +56,17 @@ std::string get_8601()
|
||||||
// ss << std::put_time(gmtime(&itt), "%FT%TZ");
|
// ss << std::put_time(gmtime(&itt), "%FT%TZ");
|
||||||
ss << std::put_time(localtime(&itt), "%Y-%m-%d_%H:%M:%S");
|
ss << std::put_time(localtime(&itt), "%Y-%m-%d_%H:%M:%S");
|
||||||
return ss.str();
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void interpolate( std::string & text )
|
||||||
|
{
|
||||||
|
static std::regex env( "\\$\\{([^}]+)\\}" );
|
||||||
|
std::smatch match;
|
||||||
|
while ( std::regex_search( text, match, env ) )
|
||||||
|
{
|
||||||
|
const char * s = getenv( match[1].str().c_str() );
|
||||||
|
const std::string var( s == NULL ? "" : s );
|
||||||
|
text.replace( match[0].first, match[0].second, var );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -32,14 +32,22 @@
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
|
|
||||||
bool exists (const std::string& name);
|
bool exists (const std::string& name);
|
||||||
|
|
||||||
std::string get_working_path();
|
std::string get_working_path();
|
||||||
|
|
||||||
bool is_file( std::string );
|
bool is_file( std::string );
|
||||||
|
|
||||||
bool is_dir( std::string );
|
bool is_dir( std::string );
|
||||||
|
|
||||||
|
// expand environment variables in string
|
||||||
|
void interpolate( std::string & text);
|
||||||
|
|
||||||
std::string get_8601();
|
std::string get_8601();
|
||||||
|
|
||||||
const char * command2args( std::string input_string );
|
const char * command2args( std::string input_string );
|
||||||
|
|
||||||
#endif //REX_HELPERS_JH
|
#endif //REX_HELPERS_JH
|
||||||
|
|
Loading…
Reference in New Issue