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);
91 rapidjson::Document d;
92 d.Parse<rapidjson::kParseStopWhenDoneFlag>(buf.
val.c_str());
93 if (d.HasParseError()) {
95 return_buf.
err_msg.assign(GetParseError_En(d.GetParseError()));
98 const rapidjson::Value& token_val = d[
"data"][
"data"][key.c_str()];
99 return_buf.
val.assign(token_val.GetString());
112 std::string vault_key = key;
114 std::transform(vault_key.begin(), vault_key.end(), vault_key.begin(), toupper);
116 std::replace(vault_key.begin(), vault_key.end(),
'.',
'_');
117 get_vault_secret(kv, vault_key, buf);
121 config_record.push_back(std::string(
"Failed to retrieve Vault Secret: ") \
130 if (key.empty())
return;
132 std::string env_key = key;
134 std::transform(env_key.begin(), env_key.end(), env_key.begin(), toupper);
136 std::replace(env_key.begin(), env_key.end(),
'.',
'_');
137 std::string query_key;
143 ApplicationProfile::get_profile_name() + std::string(
"/");
145 query_key = query_key + env_key;
151 rapidjson::Document d;
152 d.Parse<rapidjson::kParseStopWhenDoneFlag>(buf.
val.c_str());
153 if (d.HasParseError()) {
154 throw std::invalid_argument(GetParseError_En(d.GetParseError()));
158 std::string value_string;
160 for (
auto& itr : d.GetArray()) {
161 rapidjson::Value::ConstMemberIterator val_iter = \
162 itr.FindMember(
"Value");
163 if (val_iter != itr.MemberEnd()) {
164 if (!(val_iter->value.IsNull())) {
165 parsed_buffer.
val.assign(val_iter->value.GetString());
173 parsed_buffer.
val, decoded_buffer);
183 inline void load_environment_variable(std::string& key) {
185 std::string env_key = key;
187 std::transform(env_key.begin(), env_key.end(), env_key.begin(), toupper);
189 std::replace(env_key.begin(), env_key.end(),
'.',
'_');
191 const char *env_value = std::getenv(env_key.c_str());
193 std::string env_str(env_value);
199 bool auth_details_included, std::string& un, std::string& pw) {
202 std::string vault_addr_key = configuration_key_start +
"vault";
203 std::string vault_cert_key = configuration_key_start +
"vault.cert";
204 std::string vault_atype_key = configuration_key_start +
"vault.authtype";
205 std::string vault_un_key = configuration_key_start +
"vault.un";
206 std::string vault_pw_key = configuration_key_start +
"vault.pw";
207 std::string secrets_path(
"/v1/secret/data/");
208 int auth_type = BASIC_AUTH_TYPE;
215 if (auth_details_included || (kv->
opt_exist(vault_un_key) && kv->
opt_exist(vault_pw_key))) {
216 if (auth_details_included) {
217 vault_un_buf.
val.assign(un);
218 vault_pw_buf.
val.assign(pw);
220 kv->
get_opt(vault_un_key, vault_un_buf);
221 kv->
get_opt(vault_pw_key, vault_pw_buf);
226 kv->
get_opt(vault_addr_key, vault_addr_buf);
227 kv->
get_opt(vault_cert_key, vault_cert_buf);
228 kv->
get_opt(vault_atype_key, vault_authtype_buf);
229 if (vault_authtype_buf.
val ==
"APPROLE") {
230 auth_type = APPROLE_AUTH_TYPE;
232 config_record.push_back(std::string(
"Setting Vault Information: ") \
233 + vault_addr_buf.
val);
235 5, vault_cert_buf.
val, auth_type, vault_un_buf.
val, vault_pw_buf.
val);
237 kv->
get_opt(vault_addr_key, vault_addr_buf);
238 kv->
get_opt(vault_atype_key, vault_authtype_buf);
239 kv->
get_opt(vault_un_key, vault_un_buf);
240 kv->
get_opt(vault_pw_key, vault_pw_buf);
241 if (vault_authtype_buf.
val ==
"APPROLE") {
242 auth_type = APPROLE_AUTH_TYPE;
244 config_record.push_back(std::string(
"Setting Vault Information: ") \
245 + vault_addr_buf.
val);
247 5, auth_type, vault_un_buf.
val, vault_pw_buf.
val);
257 std::string consul_add_key = configuration_key_start +
"consul";
258 std::string consul_cert_key = configuration_key_start +
"consul.cert";
259 std::string consul_token_key = configuration_key_start +
"consul.token";
265 vconsul_token_buf.success) {
266 kv->
get_opt(consul_add_key, consul_addr_buf);
267 config_record.push_back(std::string(
"Setting Consul Information: ") \
268 + consul_addr_buf.
val);
270 vconsul_cert_buf.
val, vconsul_token_buf.
val);
273 vconsul_token_buf.success) {
274 kv->
get_opt(consul_add_key, consul_addr_buf);
275 kv->
get_opt(consul_cert_key, consul_cert_buf);
276 config_record.push_back(std::string(
"Setting Consul Information: ") \
277 + consul_addr_buf.
val);
279 consul_cert_buf.
val, vconsul_token_buf.
val);
281 }
else if (kv->
opt_exist(consul_add_key) && \
282 kv->opt_exist(consul_cert_key) && \
283 kv->opt_exist(consul_token_key)) {
284 config_record.push_back(std::string(
"Setting Consul Information: ") \
285 + consul_addr_buf.
val);
286 kv->
get_opt(consul_add_key, consul_addr_buf);
287 kv->
get_opt(consul_cert_key, consul_cert_buf);
288 kv->
get_opt(consul_token_key, consul_token_buf);
290 consul_cert_buf.
val, consul_token_buf.
val);
292 }
else if (kv->
opt_exist(consul_add_key) && \
294 kv->
get_opt(consul_add_key, consul_addr_buf);
295 if (vconsul_cert_buf.
success) {
296 consul_cert_buf.
val = vconsul_cert_buf.
val;
297 consul_cert_buf.
success =
true;
299 kv->
get_opt(consul_cert_key, consul_cert_buf);
301 config_record.push_back(std::string(
"Secure Consul Connection: ") \
302 + consul_addr_buf.
val);
304 consul_cert_buf.
val);
306 }
else if (kv->
opt_exist(consul_add_key) && \
308 kv->
get_opt(consul_add_key, consul_addr_buf);
309 if (vconsul_token_buf.
success) {
310 consul_token_buf.
val = vconsul_token_buf.
val;
311 consul_token_buf.
success =
true;
313 kv->
get_opt(consul_token_key, consul_token_buf);
315 config_record.push_back(std::string(
"Authenticated Consul Connection: ") \
316 + consul_addr_buf.
val);
318 config_record.push_back(std::string(
"Adding ACL Token: ") \
319 + consul_addr_buf.
val);
322 }
else if (kv->
opt_exist(consul_add_key)) {
323 kv->
get_opt(consul_add_key, consul_addr_buf);
324 config_record.push_back(std::string(
"Setting Consul Information: ") \
325 + consul_addr_buf.
val);
343 std::string config_key_start;
346 config_key_start += std::string(
".");
350 config_key_start += std::string(
".");
352 config_record.push_back(config_key_start);
353 configuration_key_start.assign(config_key_start);
354 std::string env_config_key_start(config_key_start);
355 std::transform(env_config_key_start.begin(), env_config_key_start.end(), \
356 env_config_key_start.begin(), toupper);
357 std::replace(env_config_key_start.begin(), env_config_key_start.end(),
'.',
'_');
362 std::string props_env_key = env_config_key_start + std::string(
"PROPS_FILE");
363 const char *env_props_value = std::getenv(props_env_key.c_str());
364 if (env_props_value) {
365 std::string props_file_str(env_props_value);
367 config_record.push_back(std::string(
"Setting Properties File: ") \
372 std::string props_key = config_key_start + std::string(
"props");
378 config_record.push_back(std::string(
"Setting Properties File: ") \
384 props_file_name =
"/etc/";
386 props_file_name +=
"/app.properties";
389 config_record.push_back(std::string(
"Setting Properties File: ") \
392 props_file_name =
"app.properties";
395 config_record.push_back(std::string(
"Setting Properties File: ") \
402 std::string vault_un_file =
"vault_un.txt";
403 std::string vault_pw_file =
"vault_pw.txt";
404 std::string vault_un_value;
405 std::string vault_pw_value;
406 bool vault_auth_from_file =
false;
409 if (exists_test(vault_un_file) && exists_test(vault_pw_file)) {
410 std::ifstream unfs(vault_un_file);
411 vault_un_value.assign((std::istreambuf_iterator<char>(unfs)), \
412 (std::istreambuf_iterator<char>()));
413 std::ifstream pwfs(vault_pw_file);
414 vault_pw_value.assign((std::istreambuf_iterator<char>(pwfs)), \
415 (std::istreambuf_iterator<char>()));
416 vault_auth_from_file =
true;
417 config_record.push_back(std::string(
"Using Vault authentication info from files"));
421 std::string env_vault_addr_key = env_config_key_start + std::string(
"VAULT_ADDRESS");
422 std::string env_vault_cert_key = env_config_key_start + std::string(
"VAULT_SSL_CERT");
423 std::string env_vault_authtype_key = env_config_key_start + std::string(
"VAULT_AUTH_TYPE");
424 std::string env_vault_authun_key = env_config_key_start + std::string(
"VAULT_AUTH_UN");
425 std::string env_vault_authpw_key = env_config_key_start + std::string(
"VAULT_AUTH_PW");
426 const char *env_vault_addr = std::getenv(env_vault_addr_key.c_str());
427 const char *env_vault_cert = std::getenv(env_vault_cert_key.c_str());
428 const char *env_vault_authtype = std::getenv(env_vault_authtype_key.c_str());
429 const char *env_vault_authun = std::getenv(env_vault_authun_key.c_str());
430 const char *env_vault_authpw = std::getenv(env_vault_authpw_key.c_str());
433 if (env_vault_addr && env_vault_cert && env_vault_authtype) {
434 if (vault_auth_from_file || (env_vault_authun && env_vault_authpw)) {
435 if (vault_auth_from_file) {
436 un.assign(vault_un_value);
437 pw.assign(vault_pw_value);
439 un.assign(env_vault_authun);
440 pw.assign(env_vault_authpw);
442 std::string vaddr(env_vault_addr);
443 std::string cert(env_vault_cert);
444 std::string secrets_path(
"/v1/secret/data/");
445 std::string authtype_string(env_vault_authtype);
446 int auth_type = BASIC_AUTH_TYPE;
447 if (authtype_string ==
"APPROLE") {
448 auth_type = APPROLE_AUTH_TYPE;
450 config_record.push_back(std::string(
"Setting Vault Information from Environment Variables: ") \
454 }
else if (env_vault_addr && env_vault_authtype && env_vault_authun && env_vault_authpw) {
455 if (vault_auth_from_file) {
456 un.assign(vault_un_value);
457 pw.assign(vault_pw_value);
459 un.assign(env_vault_authun);
460 pw.assign(env_vault_authpw);
462 std::string vaddr(env_vault_addr);
463 std::string secrets_path(
"/v1/secret/data/");
464 std::string authtype_string(env_vault_authtype);
465 int auth_type = BASIC_AUTH_TYPE;
466 if (authtype_string ==
"APPROLE") {
467 auth_type = APPROLE_AUTH_TYPE;
469 config_record.push_back(std::string(
"Setting Vault Information from Environment Variables: ") \
481 std::string consul_cert_vault_key = env_config_key_start \
482 + std::string(
"CONSUL_SSL_CERT");
483 std::string consul_token_vault_key = env_config_key_start \
484 + std::string(
"CONSUL_ACL_TOKEN");
486 consul_cert_buf.
success =
false;
488 consul_token_buf.
success =
false;
490 config_record.push_back(std::string(
"Checking Vault for Consul Security info"));
497 bool generate_consul_token =
false;
500 std::string gen_consul_token_key = config_key_start +
"consul.token.role";
502 generate_consul_token =
true;
507 std::string env_get_consul_token_key = env_config_key_start \
508 + std::string(
"CONSUL_TOKEN_ROLE");
509 const char *env_gen_consul_token = std::getenv(env_get_consul_token_key.c_str());
510 if (env_gen_consul_token) {
511 gen_consul_token_buf.
val.assign(env_gen_consul_token);
512 gen_consul_token_buf.
success =
true;
513 generate_consul_token =
true;
516 if (generate_consul_token && gen_consul_token_buf.
success) {
517 config_record.push_back(
"Generating Consul ACL Token with role: " + gen_consul_token_buf.
val);
520 if (!(consul_token_buf.
success)) {
521 config_record.push_back(std::string(
"Failed to generate Consul ACL Token: ") \
530 std::string env_consul_value_key = env_config_key_start \
531 + std::string(
"CONSUL_ADDRESS");
532 std::string env_consul_cert_key = env_config_key_start \
533 + std::string(
"CONSUL_SSL_CERT");
534 std::string env_consul_token_key = env_config_key_start \
535 + std::string(
"CONSUL_ACL_TOKEN");
536 const char *env_consul_value = std::getenv(env_consul_value_key.c_str());
537 const char *env_consul_cert_value = std::getenv(env_consul_cert_key.c_str());
538 const char *env_consul_token_value = std::getenv(env_consul_token_key.c_str());
539 if (env_consul_value && env_consul_cert_value && env_consul_token_value) {
540 std::string consul_addr_str(env_consul_value);
541 std::string consul_cert_str(env_consul_cert_value);
542 std::string consul_token_str(env_consul_token_value);
543 config_record.push_back(std::string(
"Setting Consul Address: ") + consul_addr_str);
545 }
else if (env_consul_value && env_consul_cert_value) {
546 std::string consul_addr_str(env_consul_value);
547 std::string consul_cert_str(env_consul_cert_value);
548 config_record.push_back(std::string(
"Setting Consul Address: ") + consul_addr_str);
550 }
else if (env_consul_value) {
552 std::string consul_addr_str(env_consul_value);
554 config_record.push_back(std::string(
"Setting Consul Address: ") + consul_addr_str);
556 }
else if (consul_cert_buf.
success && env_consul_token_value) {
557 std::string consul_token_str(env_consul_token_value);
558 config_record.push_back(std::string(
"Setting Consul Address: ") + consul_addr_str);
560 }
else if (env_consul_cert_value && consul_token_buf.
success) {
561 std::string consul_cert_str(env_consul_cert_value);
562 config_record.push_back(std::string(
"Setting Consul Address: ") + consul_addr_str);
565 config_record.push_back(std::string(
"Setting Consul Address: ") + consul_addr_str);
574 std::string cluster_key = config_key_start + std::string(
"cluster");
575 std::string env_cluster_key = env_config_key_start + std::string(
"CLUSTER");
580 cluster_name.assign(cluster_name_buf.
val);
581 config_record.push_back(std::string(
"Setting Cluster Name: ") + cluster_name);
588 cluster_name.assign(cluster_name_buf.
val);
589 config_record.push_back(std::string(
"Setting Cluster Name: ") + cluster_name);
592 const char *env_cluster_name = std::getenv(env_cluster_key.c_str());
593 if (env_cluster_name) {
594 cluster_name.assign(env_cluster_name);
595 config_record.push_back(std::string(
"Setting Cluster Name: ") + cluster_name);
601 SafeApplicationProfile(argc, argv) {init();}
603 std::string prof_name) : \
604 SafeApplicationProfile(argc, argv, app_name, prof_name) {init();}
606 SafeApplicationProfile(args) {init();}
608 std::string app_name, std::string prof_name) : \
609 SafeApplicationProfile(args, app_name, prof_name) {init();}
611 SafeApplicationProfile(app_name, prof_name) {init();}
617 config_record.clear();
618 config_record.push_back(std::string(
"Loading Configuration"));
619 config_record.push_back(configuration_key_start);
626 for (std::pair<std::string, std::string> element : \
627 KeyValueStore::get_opts()) {
628 config_record.push_back(std::string(
"Loading Records for Key: ") \
634 load_consul_value(consul, element.first);
636 load_environment_variable(element.first);
641 for (
auto& secure_opt : secure_opt_keys) {
653 std::string final_key = configuration_key_start + key;
654 std::string blank_val;
655 secure_opt_keys.push_back(final_key);
670 std::string final_key = configuration_key_start + key;
675 inline void add_opt(
const std::string& key,
const std::string& val) {
676 std::string final_key = configuration_key_start + key;
681 inline void set_opt(std::string& key, std::string& val) {
682 std::string final_key = configuration_key_start + key;
688 std::string final_key = configuration_key_start + key;
695 #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:616
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:681
void get_opt(std::string key, StringBuffer &val)
Get an option by key.
Definition: tiered_app_profile.h:669
bool opt_exist(std::string &key)
Does an option exist?
Definition: tiered_app_profile.h:687
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:666
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:675
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:660
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:652
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:663
bool opt_exist(std::string key)
Does a key exist?
Definition: kv_store.h:49