32 #include <unordered_map> 40 #include "rapidjson/document.h" 41 #include "rapidjson/error/en.h" 43 #include "aossl/core/include/kv_store.h" 44 #include "aossl/core/include/kv_store_interface.h" 45 #include "aossl/profile/include/app_profile.h" 46 #include "aossl/profile/include/safe_app_profile.h" 47 #include "aossl/vault/include/vault_interface.h" 48 #include "aossl/vault/include/factory_vault.h" 50 #ifndef AOSSL_PROFILE_INCLUDE_TIERED_APP_PROFILE_H_ 51 #define AOSSL_PROFILE_INCLUDE_TIERED_APP_PROFILE_H_ 64 std::string props_file_name;
65 std::string cluster_name;
66 std::string configuration_key_start;
67 std::vector<std::string> secure_opt_keys;
68 std::vector<std::string> config_record;
69 inline bool exists_test(
const std::string& name) {
71 return (stat (name.c_str(), &buffer) == 0);
81 config_record.push_back(std::string(
"Retrieved Record: ") + buf.
val \
82 + std::string(
" for key: ") + key);
93 rapidjson::Document d;
94 d.Parse<rapidjson::kParseStopWhenDoneFlag>(buf.
val.c_str());
95 if (d.HasParseError()) {
97 return_buf.
err_msg.assign(GetParseError_En(d.GetParseError()));
100 const rapidjson::Value& token_val = d[
"data"][
"data"][key.c_str()];
101 return_buf.
val.assign(token_val.GetString());
102 config_record.push_back(std::string(
"Retrieved Record for key: ") \
103 + key + std::string(
" from Vault"));
116 std::string vault_key = key;
118 std::transform(vault_key.begin(), vault_key.end(), vault_key.begin(), toupper);
120 std::replace(vault_key.begin(), vault_key.end(),
'.',
'_');
121 get_vault_secret(kv, vault_key, buf);
125 config_record.push_back(std::string(
"Failed to retrieve Vault Secret: ") \
134 if (key.empty())
return;
136 std::string env_key = key;
138 std::transform(env_key.begin(), env_key.end(), env_key.begin(), toupper);
140 std::replace(env_key.begin(), env_key.end(),
'.',
'_');
141 std::string query_key;
147 ApplicationProfile::get_profile_name() + std::string(
"/");
149 query_key = query_key + env_key;
155 rapidjson::Document d;
156 d.Parse<rapidjson::kParseStopWhenDoneFlag>(buf.
val.c_str());
157 if (d.HasParseError()) {
158 throw std::invalid_argument(GetParseError_En(d.GetParseError()));
162 std::string value_string;
164 for (
auto& itr : d.GetArray()) {
165 rapidjson::Value::ConstMemberIterator val_iter = \
166 itr.FindMember(
"Value");
167 if (val_iter != itr.MemberEnd()) {
168 if (!(val_iter->value.IsNull())) {
169 parsed_buffer.
val.assign(val_iter->value.GetString());
177 parsed_buffer.
val, decoded_buffer);
180 config_record.push_back(std::string(
"Retrieved Record: ") + decoded_buffer.
val \
181 + std::string(
" for key: ") + key + std::string(
" from Consul"));
189 inline void load_environment_variable(std::string& key) {
191 std::string env_key = key;
193 std::transform(env_key.begin(), env_key.end(), env_key.begin(), toupper);
195 std::replace(env_key.begin(), env_key.end(),
'.',
'_');
197 const char *env_value = std::getenv(env_key.c_str());
199 std::string env_str(env_value);
201 config_record.push_back(std::string(
"Retrieved Record: ") + env_str \
202 + std::string(
" for key: ") + key + std::string(
" from Environment Variable"));
207 bool auth_details_included, std::string& un, std::string& pw) {
210 std::string vault_addr_key = configuration_key_start +
"vault";
211 std::string vault_cert_key = configuration_key_start +
"vault.cert";
212 std::string vault_atype_key = configuration_key_start +
"vault.authtype";
213 std::string vault_un_key = configuration_key_start +
"vault.un";
214 std::string vault_pw_key = configuration_key_start +
"vault.pw";
215 std::string secrets_path(
"/v1/secret/data/");
216 int auth_type = BASIC_AUTH_TYPE;
223 if (auth_details_included || (kv->
opt_exist(vault_un_key) && kv->
opt_exist(vault_pw_key))) {
224 if (auth_details_included) {
225 vault_un_buf.
val.assign(un);
226 vault_pw_buf.
val.assign(pw);
228 kv->
get_opt(vault_un_key, vault_un_buf);
229 kv->
get_opt(vault_pw_key, vault_pw_buf);
234 kv->
get_opt(vault_addr_key, vault_addr_buf);
235 kv->
get_opt(vault_cert_key, vault_cert_buf);
236 kv->
get_opt(vault_atype_key, vault_authtype_buf);
237 if (vault_authtype_buf.
val ==
"APPROLE") {
238 auth_type = APPROLE_AUTH_TYPE;
240 config_record.push_back(std::string(
"Setting Vault Information: ") \
241 + vault_addr_buf.
val);
243 5, vault_cert_buf.
val, auth_type, vault_un_buf.
val, vault_pw_buf.
val);
245 kv->
get_opt(vault_addr_key, vault_addr_buf);
246 kv->
get_opt(vault_atype_key, vault_authtype_buf);
247 kv->
get_opt(vault_un_key, vault_un_buf);
248 kv->
get_opt(vault_pw_key, vault_pw_buf);
249 if (vault_authtype_buf.
val ==
"APPROLE") {
250 auth_type = APPROLE_AUTH_TYPE;
252 config_record.push_back(std::string(
"Setting Vault Information: ") \
253 + vault_addr_buf.
val);
255 5, auth_type, vault_un_buf.
val, vault_pw_buf.
val);
265 std::string consul_add_key = configuration_key_start +
"consul";
266 std::string consul_cert_key = configuration_key_start +
"consul.cert";
267 std::string consul_token_key = configuration_key_start +
"consul.token";
273 vconsul_token_buf.success) {
274 kv->
get_opt(consul_add_key, consul_addr_buf);
275 config_record.push_back(std::string(
"Setting Consul Information: ") \
276 + consul_addr_buf.
val);
278 vconsul_cert_buf.
val, vconsul_token_buf.
val);
281 vconsul_token_buf.success) {
282 kv->
get_opt(consul_add_key, consul_addr_buf);
283 kv->
get_opt(consul_cert_key, consul_cert_buf);
284 config_record.push_back(std::string(
"Setting Consul Information: ") \
285 + consul_addr_buf.
val);
287 consul_cert_buf.
val, vconsul_token_buf.
val);
289 }
else if (kv->
opt_exist(consul_add_key) && \
290 kv->opt_exist(consul_cert_key) && \
291 kv->opt_exist(consul_token_key)) {
292 config_record.push_back(std::string(
"Setting Consul Information: ") \
293 + consul_addr_buf.
val);
294 kv->
get_opt(consul_add_key, consul_addr_buf);
295 kv->
get_opt(consul_cert_key, consul_cert_buf);
296 kv->
get_opt(consul_token_key, consul_token_buf);
298 consul_cert_buf.
val, consul_token_buf.
val);
300 }
else if (kv->
opt_exist(consul_add_key) && \
302 kv->
get_opt(consul_add_key, consul_addr_buf);
303 if (vconsul_cert_buf.
success) {
304 consul_cert_buf.
val = vconsul_cert_buf.
val;
305 consul_cert_buf.
success =
true;
307 kv->
get_opt(consul_cert_key, consul_cert_buf);
309 config_record.push_back(std::string(
"Secure Consul Connection: ") \
310 + consul_addr_buf.
val);
312 consul_cert_buf.
val);
314 }
else if (kv->
opt_exist(consul_add_key) && \
316 kv->
get_opt(consul_add_key, consul_addr_buf);
317 if (vconsul_token_buf.
success) {
318 consul_token_buf.
val = vconsul_token_buf.
val;
319 consul_token_buf.
success =
true;
321 kv->
get_opt(consul_token_key, consul_token_buf);
323 config_record.push_back(std::string(
"Authenticated Consul Connection: ") \
324 + consul_addr_buf.
val);
326 config_record.push_back(std::string(
"Adding ACL Token: ") \
327 + consul_addr_buf.
val);
330 }
else if (kv->
opt_exist(consul_add_key)) {
331 kv->
get_opt(consul_add_key, consul_addr_buf);
332 config_record.push_back(std::string(
"Setting Consul Information: ") \
333 + consul_addr_buf.
val);
351 std::string config_key_start;
354 config_key_start += std::string(
".");
358 config_key_start += std::string(
".");
360 config_record.push_back(config_key_start);
361 configuration_key_start.assign(config_key_start);
362 std::string env_config_key_start(config_key_start);
363 std::transform(env_config_key_start.begin(), env_config_key_start.end(), \
364 env_config_key_start.begin(), toupper);
365 std::replace(env_config_key_start.begin(), env_config_key_start.end(),
'.',
'_');
370 std::string props_env_key = env_config_key_start + std::string(
"PROPS_FILE");
371 const char *env_props_value = std::getenv(props_env_key.c_str());
372 if (env_props_value) {
373 std::string props_file_str(env_props_value);
375 config_record.push_back(std::string(
"Setting Properties File: ") \
380 std::string props_key = config_key_start + std::string(
"props");
386 config_record.push_back(std::string(
"Setting Properties File: ") \
392 props_file_name =
"/etc/";
394 props_file_name +=
"/app.properties";
397 config_record.push_back(std::string(
"Setting Properties File: ") \
400 props_file_name =
"app.properties";
403 config_record.push_back(std::string(
"Setting Properties File: ") \
410 std::string vault_un_file =
"vault_un.txt";
411 std::string vault_pw_file =
"vault_pw.txt";
412 std::string vault_un_value;
413 std::string vault_pw_value;
414 bool vault_auth_from_file =
false;
417 if (exists_test(vault_un_file) && exists_test(vault_pw_file)) {
418 std::ifstream unfs(vault_un_file);
419 vault_un_value.assign((std::istreambuf_iterator<char>(unfs)), \
420 (std::istreambuf_iterator<char>()));
421 std::ifstream pwfs(vault_pw_file);
422 vault_pw_value.assign((std::istreambuf_iterator<char>(pwfs)), \
423 (std::istreambuf_iterator<char>()));
424 vault_auth_from_file =
true;
425 config_record.push_back(std::string(
"Using Vault authentication info from files"));
429 std::string env_vault_addr_key = env_config_key_start + std::string(
"VAULT_ADDRESS");
430 std::string env_vault_cert_key = env_config_key_start + std::string(
"VAULT_SSL_CERT");
431 std::string env_vault_authtype_key = env_config_key_start + std::string(
"VAULT_AUTH_TYPE");
432 std::string env_vault_authun_key = env_config_key_start + std::string(
"VAULT_AUTH_UN");
433 std::string env_vault_authpw_key = env_config_key_start + std::string(
"VAULT_AUTH_PW");
434 const char *env_vault_addr = std::getenv(env_vault_addr_key.c_str());
435 const char *env_vault_cert = std::getenv(env_vault_cert_key.c_str());
436 const char *env_vault_authtype = std::getenv(env_vault_authtype_key.c_str());
437 const char *env_vault_authun = std::getenv(env_vault_authun_key.c_str());
438 const char *env_vault_authpw = std::getenv(env_vault_authpw_key.c_str());
441 if (env_vault_addr && env_vault_cert && env_vault_authtype) {
442 if (vault_auth_from_file || (env_vault_authun && env_vault_authpw)) {
443 if (vault_auth_from_file) {
444 un.assign(vault_un_value);
445 pw.assign(vault_pw_value);
447 un.assign(env_vault_authun);
448 pw.assign(env_vault_authpw);
450 std::string vaddr(env_vault_addr);
451 std::string cert(env_vault_cert);
452 std::string secrets_path(
"/v1/secret/data/");
453 std::string authtype_string(env_vault_authtype);
454 int auth_type = BASIC_AUTH_TYPE;
455 if (authtype_string ==
"APPROLE") {
456 auth_type = APPROLE_AUTH_TYPE;
458 config_record.push_back(std::string(
"Setting Vault Information from Environment Variables: ") \
462 }
else if (env_vault_addr && env_vault_authtype && env_vault_authun && env_vault_authpw) {
463 if (vault_auth_from_file) {
464 un.assign(vault_un_value);
465 pw.assign(vault_pw_value);
467 un.assign(env_vault_authun);
468 pw.assign(env_vault_authpw);
470 std::string vaddr(env_vault_addr);
471 std::string secrets_path(
"/v1/secret/data/");
472 std::string authtype_string(env_vault_authtype);
473 int auth_type = BASIC_AUTH_TYPE;
474 if (authtype_string ==
"APPROLE") {
475 auth_type = APPROLE_AUTH_TYPE;
477 config_record.push_back(std::string(
"Setting Vault Information from Environment Variables: ") \
489 std::string consul_cert_vault_key = env_config_key_start \
490 + std::string(
"CONSUL_SSL_CERT");
491 std::string consul_token_vault_key = env_config_key_start \
492 + std::string(
"CONSUL_ACL_TOKEN");
494 consul_cert_buf.
success =
false;
496 consul_token_buf.
success =
false;
498 config_record.push_back(std::string(
"Checking Vault for Consul Security info"));
505 bool generate_consul_token =
false;
508 std::string gen_consul_token_key = config_key_start +
"consul.token.role";
510 generate_consul_token =
true;
515 std::string env_get_consul_token_key = env_config_key_start \
516 + std::string(
"CONSUL_TOKEN_ROLE");
517 const char *env_gen_consul_token = std::getenv(env_get_consul_token_key.c_str());
518 if (env_gen_consul_token) {
519 gen_consul_token_buf.
val.assign(env_gen_consul_token);
520 gen_consul_token_buf.
success =
true;
521 generate_consul_token =
true;
524 if (generate_consul_token && gen_consul_token_buf.
success) {
525 config_record.push_back(
"Generating Consul ACL Token with role: " + gen_consul_token_buf.
val);
528 if (!(consul_token_buf.
success)) {
529 config_record.push_back(std::string(
"Failed to generate Consul ACL Token: ") \
538 std::string env_consul_value_key = env_config_key_start \
539 + std::string(
"CONSUL_ADDRESS");
540 std::string env_consul_cert_key = env_config_key_start \
541 + std::string(
"CONSUL_SSL_CERT");
542 std::string env_consul_token_key = env_config_key_start \
543 + std::string(
"CONSUL_ACL_TOKEN");
544 const char *env_consul_value = std::getenv(env_consul_value_key.c_str());
545 const char *env_consul_cert_value = std::getenv(env_consul_cert_key.c_str());
546 const char *env_consul_token_value = std::getenv(env_consul_token_key.c_str());
547 if (env_consul_value && env_consul_cert_value && env_consul_token_value) {
548 std::string consul_addr_str(env_consul_value);
549 std::string consul_cert_str(env_consul_cert_value);
550 std::string consul_token_str(env_consul_token_value);
551 config_record.push_back(std::string(
"Setting Consul Address: ") + consul_addr_str);
553 }
else if (env_consul_value && env_consul_cert_value) {
554 std::string consul_addr_str(env_consul_value);
555 std::string consul_cert_str(env_consul_cert_value);
556 config_record.push_back(std::string(
"Setting Consul Address: ") + consul_addr_str);
558 }
else if (env_consul_value) {
560 std::string consul_addr_str(env_consul_value);
562 config_record.push_back(std::string(
"Setting Consul Address: ") + consul_addr_str);
564 }
else if (consul_cert_buf.
success && env_consul_token_value) {
565 std::string consul_token_str(env_consul_token_value);
566 config_record.push_back(std::string(
"Setting Consul Address: ") + consul_addr_str);
568 }
else if (env_consul_cert_value && consul_token_buf.
success) {
569 std::string consul_cert_str(env_consul_cert_value);
570 config_record.push_back(std::string(
"Setting Consul Address: ") + consul_addr_str);
573 config_record.push_back(std::string(
"Setting Consul Address: ") + consul_addr_str);
582 std::string cluster_key = config_key_start + std::string(
"cluster");
583 std::string env_cluster_key = env_config_key_start + std::string(
"CLUSTER");
588 cluster_name.assign(cluster_name_buf.
val);
589 config_record.push_back(std::string(
"Setting Cluster Name: ") + cluster_name);
596 cluster_name.assign(cluster_name_buf.
val);
597 config_record.push_back(std::string(
"Setting Cluster Name: ") + cluster_name);
600 const char *env_cluster_name = std::getenv(env_cluster_key.c_str());
601 if (env_cluster_name) {
602 cluster_name.assign(env_cluster_name);
603 config_record.push_back(std::string(
"Setting Cluster Name: ") + cluster_name);
609 SafeApplicationProfile(argc, argv) {init();}
611 std::string prof_name) : \
612 SafeApplicationProfile(argc, argv, app_name, prof_name) {init();}
614 SafeApplicationProfile(args) {init();}
616 std::string app_name, std::string prof_name) : \
617 SafeApplicationProfile(args, app_name, prof_name) {init();}
619 SafeApplicationProfile(app_name, prof_name) {init();}
625 config_record.clear();
626 config_record.push_back(std::string(
"Loading Configuration"));
627 config_record.push_back(configuration_key_start);
634 for (std::pair<std::string, std::string> element : \
635 KeyValueStore::get_opts()) {
636 config_record.push_back(std::string(
"Loading Records for Key: ") \
642 load_consul_value(consul, element.first);
644 load_environment_variable(element.first);
649 for (
auto& secure_opt : secure_opt_keys) {
661 std::string final_key = configuration_key_start + key;
662 std::string blank_val;
663 secure_opt_keys.push_back(final_key);
678 std::string final_key = configuration_key_start + key;
683 inline void add_opt(
const std::string& key,
const std::string& val) {
684 std::string final_key = configuration_key_start + key;
689 inline void set_opt(std::string& key, std::string& val) {
690 std::string final_key = configuration_key_start + key;
696 std::string final_key = configuration_key_start + key;
703 #endif // AOSSL_PROFILE_INCLUDE_TIERED_APP_PROFILE_H_ std::string get_profile_name()
Get the Profile Name.
Definition: app_profile.h:186
Application Session which accepts default configuration values.
Definition: safe_app_profile.h:42
void load_config()
Load the configuration from the various sources.
Definition: tiered_app_profile.h:624
A Structure for holding a single value.
Definition: buffers.h:42
void add_opt(const std::string &key, std::string value)
Add an option.
Definition: kv_store.h:79
std::string val
Value stored.
Definition: buffers.h:44
void set_opt(std::string &key, std::string &val)
Set an option.
Definition: tiered_app_profile.h:689
void get_opt(std::string key, StringBuffer &val)
Get an option by key.
Definition: tiered_app_profile.h:677
bool opt_exist(std::string &key)
Does an option exist?
Definition: tiered_app_profile.h:695
VaultInterface * get_vault()
Get the Vault Interface.
Definition: app_profile.h:177
Biased Application Session which implements tiered configuration.
Definition: tiered_app_profile.h:63
std::vector< std::string > get_config_record()
Get the latest Configuration Record.
Definition: tiered_app_profile.h:674
KeyValueStoreInterface * get_cli()
Get the Command Line Interface.
Definition: app_profile.h:168
void set_opt(std::string &key, std::string &value)
Set an option.
Definition: kv_store.h:83
std::string get_app_name()
Get the Application Name.
Definition: app_profile.h:183
virtual void load_config()=0
Re-load configuration.
void set_profile_name(std::string prof)
Get the Profile Name.
Definition: app_profile.h:192
StringBuffer * get_opt(std::string key)
Get an option by key.
Definition: kv_store.h:60
void add_opt(const std::string &key, const std::string &val)
Add an option.
Definition: tiered_app_profile.h:683
The Consul Administrator, who handles configuration & service discovery.
Definition: consul_interface.h:115
void set_consul_address(std::string caddr)
Set the address of the consul agent.
Definition: app_profile.h:121
virtual StringBuffer * get_opt(std::string key)=0
Get an option by key.
virtual void add_acl_token(std::string &token)=0
Add an ACL Token to the Consul Admin.
void set_vault_address(std::string &vaddr, std::string &secrets_path, int tout, std::string &cert, int auth_type, std::string &un, std::string &pw)
Update the Vault connectivity information.
Definition: app_profile.h:148
Key Value Store.
Definition: kv_store_interface.h:38
bool success
Success flag.
Definition: buffers.h:35
virtual void base64_decode_by_reference(std::string const &encoded_string, StringBuffer &ret_buffer)=0
Convinience Method for base64 decoding.
std::string get_cluster_name()
Get the Cluster Name.
Definition: tiered_app_profile.h:668
ConsulInterface * get_consul()
Get the Consul Interface.
Definition: app_profile.h:174
KeyValueStoreInterface * get_props()
Get the Properties File Reader.
Definition: app_profile.h:171
std::string err_msg
Error Message.
Definition: buffers.h:38
void add_secure_opt(std::string &key)
Definition: tiered_app_profile.h:660
void set_property_file(std::string &filename)
Set the location of the properties file.
Definition: app_profile.h:112
virtual bool opt_exist(std::string key)=0
Does a key exist?
void set_cluster_name(std::string &new_name)
Set the Cluster Name.
Definition: tiered_app_profile.h:671
bool opt_exist(std::string key)
Does a key exist?
Definition: kv_store.h:49