CtlUtil.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /* (c) ZeroTier, Inc.
  2. * See LICENSE.txt in nonfree/
  3. */
  4. #include "CtlUtil.hpp"
  5. #ifdef ZT_CONTROLLER_USE_LIBPQ
  6. #include <iomanip>
  7. #include <sstream>
  8. #ifdef ZT1_CENTRAL_CONTROLLER
  9. #include <google/cloud/bigtable/admin/bigtable_table_admin_client.h>
  10. #include <google/cloud/bigtable/admin/bigtable_table_admin_connection.h>
  11. #include <google/cloud/bigtable/table.h>
  12. #include <google/cloud/pubsub/admin/subscription_admin_client.h>
  13. #include <google/cloud/pubsub/admin/subscription_admin_connection.h>
  14. #include <google/cloud/pubsub/admin/topic_admin_client.h>
  15. #include <google/cloud/pubsub/message.h>
  16. #include <google/cloud/pubsub/subscriber.h>
  17. #include <google/cloud/pubsub/subscription.h>
  18. #include <google/cloud/pubsub/topic.h>
  19. namespace pubsub = ::google::cloud::pubsub;
  20. namespace pubsub_admin = ::google::cloud::pubsub_admin;
  21. namespace bigtable_admin = ::google::cloud::bigtable_admin;
  22. #endif
  23. namespace ZeroTier {
  24. const char* _timestr()
  25. {
  26. time_t t = time(0);
  27. char* ts = ctime(&t);
  28. char* p = ts;
  29. if (! p)
  30. return "";
  31. while (*p) {
  32. if (*p == '\n') {
  33. *p = (char)0;
  34. break;
  35. }
  36. ++p;
  37. }
  38. return ts;
  39. }
  40. std::vector<std::string> split(std::string str, char delim)
  41. {
  42. std::istringstream iss(str);
  43. std::vector<std::string> tokens;
  44. std::string item;
  45. while (std::getline(iss, item, delim)) {
  46. tokens.push_back(item);
  47. }
  48. return tokens;
  49. }
  50. std::string url_encode(const std::string& value)
  51. {
  52. std::ostringstream escaped;
  53. escaped.fill('0');
  54. escaped << std::hex;
  55. for (std::string::const_iterator i = value.begin(), n = value.end(); i != n; ++i) {
  56. std::string::value_type c = (*i);
  57. // Keep alphanumeric and other accepted characters intact
  58. if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {
  59. escaped << c;
  60. continue;
  61. }
  62. // Any other characters are percent-encoded
  63. escaped << std::uppercase;
  64. escaped << '%' << std::setw(2) << int((unsigned char)c);
  65. escaped << std::nouppercase;
  66. }
  67. return escaped.str();
  68. }
  69. std::string random_hex_string(std::size_t length)
  70. {
  71. static const char hex_chars[] = "0123456789abcdef";
  72. std::random_device rd;
  73. std::mt19937 gen(rd());
  74. std::uniform_int_distribution<> dis(0, 15);
  75. std::string result;
  76. result.reserve(length);
  77. for (std::size_t i = 0; i < length; ++i) {
  78. result += hex_chars[dis(gen)];
  79. }
  80. return result;
  81. }
  82. #ifdef ZT1_CENTRAL_CONTROLLER
  83. void create_gcp_pubsub_topic_if_needed(std::string project_id, std::string topic_id)
  84. {
  85. // This is a no-op if the topic already exists.
  86. auto topicAdminClient = pubsub_admin::TopicAdminClient(pubsub_admin::MakeTopicAdminConnection());
  87. auto topicName = pubsub::Topic(project_id, topic_id).FullName();
  88. auto topicResult = topicAdminClient.GetTopic(topicName);
  89. if (! topicResult.ok()) {
  90. // Only create if not found
  91. if (topicResult.status().code() == google::cloud::StatusCode::kNotFound) {
  92. auto createResult = topicAdminClient.CreateTopic(topicName);
  93. if (! createResult.ok()) {
  94. fprintf(stderr, "Failed to create topic: %s\n", createResult.status().message().c_str());
  95. throw std::runtime_error("Failed to create topic");
  96. }
  97. fprintf(stderr, "Created topic: %s\n", topicName.c_str());
  98. }
  99. else {
  100. fprintf(stderr, "Failed to get topic: %s\n", topicResult.status().message().c_str());
  101. throw std::runtime_error("Failed to get topic");
  102. }
  103. }
  104. }
  105. // void create_bigtable_table(std::string project_id, std::string instance_id)
  106. // {
  107. // auto bigtableAdminClient =
  108. // bigtable_admin::BigtableTableAdminClient(bigtable_admin::MakeBigtableTableAdminConnection());
  109. // std::string table_id = "member_status";
  110. // std::string table_name = "projects/" + project_id + "/instances/" + instance_id + "/tables/" + table_id;
  111. // // Check if the table exists
  112. // auto table = bigtableAdminClient.GetTable(table_name);
  113. // if (! table.ok()) {
  114. // if (table.status().code() == google::cloud::StatusCode::kNotFound) {
  115. // google::bigtable::admin::v2::Table table_config;
  116. // table_config.set_name(table_id);
  117. // auto families = table_config.mutable_column_families();
  118. // // Define column families
  119. // // Column family "node_info" with max 1 version
  120. // // google::bigtable::admin::v2::ColumnFamily* node_info = table_config.add_column_families();
  121. // // Column family "check_in" with max 1 version
  122. // auto create_result = bigtableAdminClient.CreateTable(
  123. // "projects/" + project_id + "/instances/" + instance_id, table_id, table_config);
  124. // if (! create_result.ok()) {
  125. // fprintf(
  126. // stderr, "Failed to create Bigtable table member_status: %s\n",
  127. // create_result.status().message().c_str());
  128. // throw std::runtime_error("Failed to create Bigtable table");
  129. // }
  130. // fprintf(stderr, "Created Bigtable table: member_status\n");
  131. // }
  132. // else {
  133. // fprintf(stderr, "Failed to get Bigtable table member_status: %s\n", table.status().message().c_str());
  134. // throw std::runtime_error("Failed to get Bigtable table");
  135. // }
  136. // }
  137. // }
  138. #endif
  139. } // namespace ZeroTier
  140. #endif