claim.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. #include "claim.h"
  3. #include "../registry/registry_internals.h"
  4. #include "../aclk/aclk_common.h"
  5. char *claiming_pending_arguments = NULL;
  6. static char *claiming_errors[] = {
  7. "Agent claimed successfully", // 0
  8. "Unknown argument", // 1
  9. "Problems with claiming working directory", // 2
  10. "Missing dependencies", // 3
  11. "Failure to connect to endpoint", // 4
  12. "Unknown HTTP error message", // 5
  13. "invalid node id", // 6
  14. "invalid node name", // 7
  15. "invalid room id", // 8
  16. "invalid public key", // 9
  17. "token expired/token not found/invalid token", // 10
  18. "already claimed", // 11
  19. "processing claiming", // 12
  20. "Internal Server Error", // 13
  21. "Gateway Timeout", // 14
  22. "Service Unavailable" // 15
  23. };
  24. static char *claimed_id = NULL;
  25. char *is_agent_claimed(void)
  26. {
  27. return claimed_id;
  28. }
  29. #define CLAIMING_COMMAND_LENGTH 16384
  30. #define CLAIMING_PROXY_LENGTH CLAIMING_COMMAND_LENGTH/4
  31. extern struct registry registry;
  32. /* rrd_init() must have been called before this function */
  33. void claim_agent(char *claiming_arguments)
  34. {
  35. #ifndef ENABLE_ACLK
  36. info("The claiming feature is under development and still subject to change before the next release");
  37. return;
  38. #endif
  39. int exit_code;
  40. pid_t command_pid;
  41. char command_buffer[CLAIMING_COMMAND_LENGTH + 1];
  42. FILE *fp;
  43. char *cloud_base_hostname = NULL; // Initializers are over-written but prevent gcc complaining about clobbering.
  44. char *cloud_base_port = NULL;
  45. char *cloud_base_url = config_get(CONFIG_SECTION_CLOUD, "cloud base url", "https://netdata.cloud");
  46. if( aclk_decode_base_url(cloud_base_url, &cloud_base_hostname, &cloud_base_port))
  47. {
  48. error("Configuration error - cannot decode \"cloud base url\"");
  49. return;
  50. }
  51. const char *proxy_str;
  52. ACLK_PROXY_TYPE proxy_type;
  53. char proxy_flag[CLAIMING_PROXY_LENGTH] = "-noproxy";
  54. proxy_str = aclk_get_proxy(&proxy_type);
  55. if (proxy_type == PROXY_TYPE_SOCKS5 || proxy_type == PROXY_TYPE_HTTP)
  56. snprintf(proxy_flag, CLAIMING_PROXY_LENGTH, "-proxy=\"%s\"", proxy_str);
  57. snprintfz(command_buffer,
  58. CLAIMING_COMMAND_LENGTH,
  59. "exec netdata-claim.sh %s -hostname=%s -id=%s -url=%s %s",
  60. proxy_flag,
  61. netdata_configured_hostname,
  62. localhost->machine_guid,
  63. cloud_base_url,
  64. claiming_arguments);
  65. info("Executing agent claiming command 'netdata-claim.sh'");
  66. fp = mypopen(command_buffer, &command_pid);
  67. if(!fp) {
  68. error("Cannot popen(\"%s\").", command_buffer);
  69. return;
  70. }
  71. info("Waiting for claiming command to finish.");
  72. while (fgets(command_buffer, CLAIMING_COMMAND_LENGTH, fp) != NULL) {;}
  73. exit_code = mypclose(fp, command_pid);
  74. info("Agent claiming command returned with code %d", exit_code);
  75. if (0 == exit_code) {
  76. load_claiming_state();
  77. return;
  78. }
  79. if (exit_code < 0) {
  80. error("Agent claiming command failed to complete its run.");
  81. return;
  82. }
  83. errno = 0;
  84. unsigned maximum_known_exit_code = sizeof(claiming_errors) / sizeof(claiming_errors[0]) - 1;
  85. if ((unsigned)exit_code > maximum_known_exit_code) {
  86. error("Agent failed to be claimed with an unknown error.");
  87. return;
  88. }
  89. error("Agent failed to be claimed with the following error message:");
  90. error("\"%s\"", claiming_errors[exit_code]);
  91. }
  92. void load_claiming_state(void)
  93. {
  94. if (claimed_id != NULL) {
  95. freez(claimed_id);
  96. claimed_id = NULL;
  97. }
  98. char filename[FILENAME_MAX + 1];
  99. struct stat statbuf;
  100. snprintfz(filename, FILENAME_MAX, "%s/claim.d/claimed_id", netdata_configured_user_config_dir);
  101. // check if the file exists
  102. if (lstat(filename, &statbuf) != 0) {
  103. info("lstat on File '%s' failed reason=\"%s\". Setting state to AGENT_UNCLAIMED.", filename, strerror(errno));
  104. return;
  105. }
  106. if (unlikely(statbuf.st_size == 0)) {
  107. info("File '%s' has no contents. Setting state to AGENT_UNCLAIMED.", filename);
  108. return;
  109. }
  110. FILE *f = fopen(filename, "rt");
  111. if (unlikely(f == NULL)) {
  112. error("File '%s' cannot be opened. Setting state to AGENT_UNCLAIMED.", filename);
  113. return;
  114. }
  115. claimed_id = callocz(1, statbuf.st_size + 1);
  116. size_t bytes_read = fread(claimed_id, 1, statbuf.st_size, f);
  117. claimed_id[bytes_read] = 0;
  118. info("File '%s' was found. Setting state to AGENT_CLAIMED.", filename);
  119. fclose(f);
  120. snprintfz(filename, FILENAME_MAX, "%s/claim.d/private.pem", netdata_configured_user_config_dir);
  121. }