rrdlabels.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. #define NETDATA_RRD_INTERNALS
  3. #include "rrd.h"
  4. char *translate_label_source(LABEL_SOURCE l) {
  5. switch (l) {
  6. case LABEL_SOURCE_AUTO:
  7. return "AUTO";
  8. case LABEL_SOURCE_NETDATA_CONF:
  9. return "NETDATA.CONF";
  10. case LABEL_SOURCE_DOCKER :
  11. return "DOCKER";
  12. case LABEL_SOURCE_ENVIRONMENT :
  13. return "ENVIRONMENT";
  14. case LABEL_SOURCE_KUBERNETES :
  15. return "KUBERNETES";
  16. default:
  17. return "Invalid label source";
  18. }
  19. }
  20. int is_valid_label_value(char *value) {
  21. while(*value) {
  22. if(*value == '"' || *value == '\'' || *value == '*' || *value == '!') {
  23. return 0;
  24. }
  25. value++;
  26. }
  27. return 1;
  28. }
  29. int is_valid_label_key(char *key) {
  30. //Prometheus exporter
  31. if(!strcmp(key, "chart") || !strcmp(key, "family") || !strcmp(key, "dimension"))
  32. return 0;
  33. //Netdata and Prometheus internal
  34. if (*key == '_')
  35. return 0;
  36. while(*key) {
  37. if(!(isdigit(*key) || isalpha(*key) || *key == '.' || *key == '_' || *key == '-'))
  38. return 0;
  39. key++;
  40. }
  41. return 1;
  42. }
  43. void strip_last_symbol(
  44. char *str,
  45. char symbol,
  46. SKIP_ESCAPED_CHARACTERS_OPTION skip_escaped_characters)
  47. {
  48. char *end = str;
  49. while (*end && *end != symbol) {
  50. if (unlikely(skip_escaped_characters && *end == '\\')) {
  51. end++;
  52. if (unlikely(!*end))
  53. break;
  54. }
  55. end++;
  56. }
  57. if (likely(*end == symbol))
  58. *end = '\0';
  59. }
  60. char *strip_double_quotes(char *str, SKIP_ESCAPED_CHARACTERS_OPTION skip_escaped_characters)
  61. {
  62. if (*str == '"') {
  63. str++;
  64. strip_last_symbol(str, '"', skip_escaped_characters);
  65. }
  66. return str;
  67. }
  68. struct label *create_label(char *key, char *value, LABEL_SOURCE label_source)
  69. {
  70. size_t key_len = strlen(key), value_len = strlen(value);
  71. size_t n = sizeof(struct label) + key_len + 1 + value_len + 1;
  72. struct label *result = callocz(1,n);
  73. if (result != NULL) {
  74. char *c = (char *)result;
  75. c += sizeof(struct label);
  76. strcpy(c, key);
  77. result->key = c;
  78. c += key_len + 1;
  79. strcpy(c, value);
  80. result->value = c;
  81. result->label_source = label_source;
  82. result->key_hash = simple_hash(result->key);
  83. }
  84. return result;
  85. }
  86. void free_label_list(struct label *labels)
  87. {
  88. while (labels != NULL)
  89. {
  90. struct label *current = labels;
  91. labels = labels->next;
  92. freez(current);
  93. }
  94. }
  95. void replace_label_list(struct label_index *labels, struct label *new_labels)
  96. {
  97. netdata_rwlock_wrlock(&labels->labels_rwlock);
  98. struct label *old_labels = labels->head;
  99. labels->head = new_labels;
  100. netdata_rwlock_unlock(&labels->labels_rwlock);
  101. free_label_list(old_labels);
  102. }
  103. struct label *add_label_to_list(struct label *l, char *key, char *value, LABEL_SOURCE label_source)
  104. {
  105. struct label *lab = create_label(key, value, label_source);
  106. lab->next = l;
  107. return lab;
  108. }
  109. void update_label_list(struct label **labels, struct label *new_labels)
  110. {
  111. free_label_list(*labels);
  112. *labels = NULL;
  113. while (new_labels != NULL)
  114. {
  115. *labels = add_label_to_list(*labels, new_labels->key, new_labels->value, new_labels->label_source);
  116. new_labels = new_labels->next;
  117. }
  118. }
  119. struct label *label_list_lookup_key(struct label *head, char *key, uint32_t key_hash)
  120. {
  121. while (head != NULL)
  122. {
  123. if (head->key_hash == key_hash && !strcmp(head->key, key))
  124. return head;
  125. head = head->next;
  126. }
  127. return NULL;
  128. }
  129. int label_list_contains_key(struct label *head, char *key, uint32_t key_hash)
  130. {
  131. return (label_list_lookup_key(head, key, key_hash) != NULL);
  132. }
  133. int label_list_contains(struct label *head, struct label *check)
  134. {
  135. return label_list_contains_key(head, check->key, check->key_hash);
  136. }
  137. struct label *label_list_lookup_keylist(struct label *head, char *key)
  138. {
  139. SIMPLE_PATTERN *pattern = NULL;
  140. pattern = simple_pattern_create(key, ",|\t\r\n\f\v", SIMPLE_PATTERN_EXACT);
  141. while (head != NULL)
  142. {
  143. if (simple_pattern_matches(pattern, head->key))
  144. break;
  145. head = head->next;
  146. }
  147. simple_pattern_free(pattern);
  148. return head;
  149. }
  150. int label_list_contains_keylist(struct label *head, char *keylist)
  151. {
  152. return (label_list_lookup_keylist(head, keylist) != NULL);
  153. }
  154. /* Create a list with entries from both lists.
  155. If any entry in the low priority list is masked by an entry in the high priority list then delete it.
  156. */
  157. struct label *merge_label_lists(struct label *lo_pri, struct label *hi_pri)
  158. {
  159. struct label *result = hi_pri;
  160. while (lo_pri != NULL)
  161. {
  162. struct label *current = lo_pri;
  163. lo_pri = lo_pri->next;
  164. if (!label_list_contains(result, current)) {
  165. current->next = result;
  166. result = current;
  167. }
  168. else
  169. freez(current);
  170. }
  171. return result;
  172. }