master
c 209 lines 6.05 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "claim.h"
4
5 // --------------------------------------------------------------------------------------------------------------------
6 // keep track of the last claiming failure reason
7
8 static char cloud_claim_failure_reason[4096] = "";
9
10 void claim_agent_failure_reason_set(const char *format, ...) {
11 if(!format || !*format) {
12 cloud_claim_failure_reason[0] = '\0';
13 return;
14 }
15
16 va_list args;
17 va_start(args, format);
18 vsnprintf(cloud_claim_failure_reason, sizeof(cloud_claim_failure_reason), format, args);
19 va_end(args);
20
21 nd_log(NDLS_DAEMON, NDLP_ERR,
22 "CLAIM: %s", cloud_claim_failure_reason);
23 }
24
25 const char *claim_agent_failure_reason_get(void) {
26 if(!cloud_claim_failure_reason[0])
27 return "Agent is not claimed yet";
28 else
29 return cloud_claim_failure_reason;
30 }
31
32 // --------------------------------------------------------------------------------------------------------------------
33 // claimed_id load/save
34
35 bool claimed_id_save_to_file(const char *claimed_id_str) {
36 bool ret;
37 const char *filename = filename_from_path_entry_strdupz(netdata_configured_cloud_dir, "claimed_id");
38 FILE *fp = fopen(filename, "w");
39 if(fp) {
40 fprintf(fp, "%s", claimed_id_str);
41 fclose(fp);
42 ret = true;
43 }
44 else {
45 nd_log(NDLS_DAEMON, NDLP_ERR,
46 "CLAIM: cannot open file '%s' for writing.", filename);
47 ret = false;
48 }
49
50 freez((void *)filename);
51 return ret;
52 }
53
54 static ND_UUID claimed_id_parse(const char *claimed_id, const char *source) {
55 ND_UUID uuid;
56
57 if(uuid_parse_flexi(claimed_id, uuid.uuid) != 0) {
58 uuid = UUID_ZERO;
59 nd_log(NDLS_DAEMON, NDLP_ERR,
60 "CLAIM: claimed_id '%s' (loaded from '%s'), is not a valid UUID.",
61 claimed_id, source);
62 }
63
64 return uuid;
65 }
66
67 static ND_UUID claimed_id_load_from_file(void) {
68 ND_UUID uuid;
69
70 long bytes_read;
71 const char *filename = filename_from_path_entry_strdupz(netdata_configured_cloud_dir, "claimed_id");
72 char *claimed_id = read_by_filename(filename, &bytes_read);
73
74 if(!claimed_id)
75 uuid = UUID_ZERO;
76 else
77 uuid = claimed_id_parse(claimed_id, filename);
78
79 freez(claimed_id);
80 freez((void *)filename);
81 return uuid;
82 }
83
84 static ND_UUID claimed_id_get_from_cloud_conf(void) {
85 if(inicfg_exists(&cloud_config, CONFIG_SECTION_GLOBAL, "claimed_id")) {
86 const char *claimed_id = inicfg_get(&cloud_config, CONFIG_SECTION_GLOBAL, "claimed_id", "");
87 if(claimed_id && *claimed_id)
88 return claimed_id_parse(claimed_id, "cloud.conf");
89 }
90 return UUID_ZERO;
91 }
92
93 static ND_UUID claimed_id_load(void) {
94 ND_UUID uuid = claimed_id_get_from_cloud_conf();
95 if(UUIDiszero(uuid))
96 uuid = claimed_id_load_from_file();
97
98 return uuid;
99 }
100
101 bool is_agent_claimed(void) {
102 ND_UUID uuid = claim_id_get_uuid();
103 return !UUIDiszero(uuid);
104 }
105
106 // --------------------------------------------------------------------------------------------------------------------
107
108 bool claim_id_matches(const char *claim_id) {
109 ND_UUID this_one = UUID_ZERO;
110 if(uuid_parse_flexi(claim_id, this_one.uuid) != 0 || UUIDiszero(this_one))
111 return false;
112
113 ND_UUID having = claim_id_get_uuid();
114 if(!UUIDiszero(having) && UUIDeq(having, this_one))
115 return true;
116
117 return false;
118 }
119
120 bool claim_id_matches_any(const char *claim_id) {
121 ND_UUID this_one = UUID_ZERO;
122 if(uuid_parse_flexi(claim_id, this_one.uuid) != 0 || UUIDiszero(this_one))
123 return false;
124
125 ND_UUID having = claim_id_get_uuid();
126 if(!UUIDiszero(having) && UUIDeq(having, this_one))
127 return true;
128
129 having = localhost->aclk.claim_id_of_parent;
130 if(!UUIDiszero(having) && UUIDeq(having, this_one))
131 return true;
132
133 having = localhost->aclk.claim_id_of_origin;
134 if(!UUIDiszero(having) && UUIDeq(having, this_one))
135 return true;
136
137 return false;
138 }
139
140 /* Change the claimed state of the agent.
141 *
142 * This only happens when the user has explicitly requested it:
143 * - via the cli tool by reloading the claiming state
144 * - after spawning the claim because of a command-line argument
145 * If this happens with the ACLK active under an old claim then we MUST KILL THE LINK
146 */
147 bool load_claiming_state(void) {
148 if (aclk_online()) {
149 nd_log(NDLS_DAEMON, NDLP_ERR,
150 "CLAIM: agent was already connected to NC - forcing reconnection under new credentials");
151 disconnect_req = ACLK_RELOAD_CONF;
152 }
153 aclk_disable_runtime = 0;
154
155 ND_UUID uuid = claimed_id_load();
156 if(UUIDiszero(uuid)) {
157 // not found
158 if(claim_agent_automatically())
159 uuid = claimed_id_load();
160 }
161
162 bool have_claimed_id = false;
163 if(!UUIDiszero(uuid)) {
164 // we go it somehow
165 claim_id_set(uuid);
166 have_claimed_id = true;
167 }
168
169 invalidate_node_instances(&localhost->host_id.uuid, have_claimed_id ? &uuid.uuid : NULL);
170 metaqueue_store_claim_id(&localhost->host_id.uuid, have_claimed_id ? &uuid.uuid : NULL);
171
172 errno_clear();
173
174 if (!have_claimed_id)
175 nd_log(NDLS_DAEMON, NDLP_ERR,
176 "CLAIM: Unable to find our claimed_id, setting state to AGENT_UNCLAIMED");
177 else
178 nd_log(NDLS_DAEMON, NDLP_INFO,
179 "CLAIM: Found a valid claimed_id, setting state to AGENT_CLAIMED");
180
181 return have_claimed_id;
182 }
183
184 CLOUD_STATUS claim_reload_and_wait_online(void) {
185 nd_log(NDLS_DAEMON, NDLP_INFO,
186 "CLAIM: Reloading Agent Claiming configuration.");
187
188 nd_log_limits_unlimited();
189 cloud_conf_load(0);
190 bool claimed = load_claiming_state();
191 registry_update_cloud_base_url();
192 stream_sender_send_claimed_id(localhost);
193 nd_log_limits_reset();
194
195 CLOUD_STATUS status = cloud_status();
196 if(claimed) {
197 int ms = 0;
198 do {
199 status = cloud_status();
200 if ((status == CLOUD_STATUS_ONLINE) && !UUIDiszero(localhost->node_id))
201 break;
202
203 sleep_usec(50 * USEC_PER_MS);
204 ms += 50;
205 } while (ms < 10000);
206 }
207
208 return status;
209 }