Add NETCONF CallHome via TLS feature.
[sim/o1-interface.git] / ntsimulator / ntsim-ng / core / app / manager_sysrepo.c
1 /*************************************************************************
2 *
3 * Copyright 2020 highstreet technologies GmbH and others
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 ***************************************************************************/
17
18 #define _GNU_SOURCE
19
20 #include "manager.h"
21 #include "utils/log_utils.h"
22 #include "utils/sys_utils.h"
23 #include <stdio.h>
24 #include <assert.h>
25
26 #include "core/framework.h"
27 #include "core/session.h"
28 #include "core/xpath.h"
29
30 static int manager_context_sync = 0;
31
32 int manager_sr_get_context_sync(void) {
33     return manager_context_sync;
34 }
35
36 int manager_sr_update_context(manager_context_t *ctx) {
37     assert(ctx);
38     assert_session();
39
40     char xpath[512];
41     char int_to_str[30];
42
43     //setup sdn-controller defaults
44     sprintf(xpath, NTS_MANAGER_FUNCTION_LIST_SCHEMA_XPATH"[function-type='%s']/started-instances", ctx->function_type);
45     sprintf(int_to_str, "%d", ctx->started_instances);
46     int rc = sr_set_item_str(session_running, xpath, (const char*)int_to_str, 0, 0);
47     if(rc != SR_ERR_OK) {
48         log_error("sr_set_item_str failed\n");
49         return NTS_ERR_FAILED;
50     }
51
52     sprintf(xpath, NTS_MANAGER_FUNCTION_LIST_SCHEMA_XPATH"[function-type='%s']/mounted-instances", ctx->function_type);
53     sprintf(int_to_str, "%d", ctx->mounted_instances);
54     rc = sr_set_item_str(session_running, xpath, (const char*)int_to_str, 0, 0);
55     if(rc != SR_ERR_OK) {
56         log_error("sr_set_item_str failed\n");
57         return NTS_ERR_FAILED;
58     }
59
60     manager_context_sync = 1;
61
62     //apply all changes
63     rc = sr_apply_changes(session_running, 0, 0);
64     if(rc != SR_ERR_OK) {
65         log_error("sr_apply_changes failed\n");
66         return NTS_ERR_FAILED;
67     }
68
69     manager_context_sync = 0;
70
71     return NTS_ERR_OK;
72 }
73
74 int manager_sr_on_last_operation_status(const char *status, const char *errmsg) {
75     assert(status);
76
77     int rc = sr_set_item_str(session_operational, NTS_MANAGER_SIMULATION_SCHEMA_XPATH"/last-operation-status", status, 0, 0);
78     if(rc != SR_ERR_OK) {
79         log_error("sr_set_item_str failed\n");
80         return NTS_ERR_FAILED;
81     }
82
83     //apply all changes
84     rc = sr_apply_changes(session_operational, 0, 0);
85     if(rc != SR_ERR_OK) {
86         log_error("sr_apply_changes failed\n");
87         return NTS_ERR_FAILED;
88     }
89
90     //push notification
91     const struct lys_module *manager_module = ly_ctx_get_module(session_context, NTS_MANAGER_MODULE, 0, 0);
92     if(manager_module == 0) {
93         log_error("ly_ctx_get_module failed\n");
94         return NTS_ERR_FAILED;
95     }
96
97     struct lyd_node *notif = lyd_new(0, manager_module, "operation-status-changed");
98     if(notif == 0) {
99         log_error("lyd_new failed\n");
100         return NTS_ERR_FAILED;
101     }
102
103     lyd_new_leaf(notif, manager_module, "operation-status", status);
104     if(errmsg && errmsg[0]) {
105         lyd_new_leaf(notif, manager_module, "error-message", errmsg);
106     }
107
108     rc = sr_event_notif_send_tree(session_running, notif);
109     if(rc != SR_ERR_OK) {
110         log_error("sr_event_notif_send_tree failed\n");
111         return NTS_ERR_FAILED;
112     }
113
114     return NTS_ERR_OK;
115 }
116
117 int manager_sr_notif_send_instance_changed(const char *status, const char *function_type, const char *name, const manager_network_function_instance_t* instance) {
118     assert(status);
119     assert(function_type);
120     assert(name);
121
122     //push notification
123     const struct lys_module *manager_module = ly_ctx_get_module(session_context, NTS_MANAGER_MODULE, 0, 0);
124     if(manager_module == 0) {
125         log_error("ly_ctx_get_module failed\n");
126         return NTS_ERR_FAILED;
127     }
128
129     struct lyd_node *notif = lyd_new(0, manager_module, "instance-changed");
130     if(notif == 0) {
131         log_error("lyd_new failed\n");
132         return NTS_ERR_FAILED;
133     }
134
135     if(lyd_new_leaf(notif, manager_module, "change-status", status) == 0) {
136         log_error("lyd_new_leaf error\n");
137         return NTS_ERR_FAILED;
138     }
139
140     if(lyd_new_leaf(notif, manager_module, "function-type", function_type) == 0) {
141         log_error("lyd_new_leaf error\n");
142         return NTS_ERR_FAILED;
143     }
144
145     if(lyd_new_leaf(notif, manager_module, "name", name) == 0) {
146         log_error("lyd_new_leaf error\n");
147         return NTS_ERR_FAILED;
148     }
149
150     if(instance) {
151         if(manager_sr_populate_networking(notif, instance) != NTS_ERR_OK) {
152             log_error("manager_sr_populate_networking error\n");
153             return NTS_ERR_FAILED;
154         }
155     }
156
157     int rc = sr_event_notif_send_tree(session_running, notif);
158     if(rc != SR_ERR_OK) {
159         log_error("sr_event_notif_send_tree failed\n");
160         return NTS_ERR_FAILED;
161     }
162     
163     return NTS_ERR_OK;
164 }
165
166
167 int manager_sr_update_static_stats(void) {
168     assert_session();
169     char int_to_str[30];
170     int rc;
171
172     sprintf(int_to_str, "%d", framework_environment.host.ssh_base_port);
173     rc = sr_set_item_str(session_operational, NTS_MANAGER_SIMULATION_SCHEMA_XPATH"/ports/netconf-ssh-port", (const char*)int_to_str, 0, 0);
174     if(rc != SR_ERR_OK) {
175         log_error("sr_set_item_str failed\n");
176         return NTS_ERR_FAILED;
177     }
178
179     sprintf(int_to_str, "%d", framework_environment.host.tls_base_port);
180     rc = sr_set_item_str(session_operational, NTS_MANAGER_SIMULATION_SCHEMA_XPATH"/ports/netconf-tls-port", (const char*)int_to_str, 0, 0);
181     if(rc != SR_ERR_OK) {
182         log_error("sr_set_item_str failed\n");
183         return NTS_ERR_FAILED;
184     }
185
186     sprintf(int_to_str, "%d", framework_environment.host.ftp_base_port);
187     rc = sr_set_item_str(session_operational, NTS_MANAGER_SIMULATION_SCHEMA_XPATH"/ports/transport-ftp-port", (const char*)int_to_str, 0, 0);
188     if(rc != SR_ERR_OK) {
189         log_error("sr_set_item_str failed\n");
190         return NTS_ERR_FAILED;
191     }
192
193     sprintf(int_to_str, "%d", framework_environment.host.sftp_base_port);
194     rc = sr_set_item_str(session_operational, NTS_MANAGER_SIMULATION_SCHEMA_XPATH"/ports/transport-sftp-port", (const char*)int_to_str, 0, 0);
195     if(rc != SR_ERR_OK) {
196         log_error("sr_set_item_str failed\n");
197         return NTS_ERR_FAILED;
198     }
199
200     sprintf(int_to_str, "%d", framework_environment.settings.ssh_connections);
201     rc = sr_set_item_str(session_operational, NTS_MANAGER_SIMULATION_SCHEMA_XPATH"/ssh-connections", (const char*)int_to_str, 0, 0);
202     if(rc != SR_ERR_OK) {
203         log_error("sr_set_item_str failed\n");
204         return NTS_ERR_FAILED;
205     }
206
207     sprintf(int_to_str, "%d", framework_environment.settings.tls_connections);
208     rc = sr_set_item_str(session_operational, NTS_MANAGER_SIMULATION_SCHEMA_XPATH"/tls-connections", (const char*)int_to_str, 0, 0);
209     if(rc != SR_ERR_OK) {
210         log_error("sr_set_item_str failed\n");
211         return NTS_ERR_FAILED;
212     }
213
214     //apply all changes
215     rc = sr_apply_changes(session_operational, 0, 0);
216     if(rc != SR_ERR_OK) {
217         log_error("sr_apply_changes failed: %s\n", sr_strerror(rc));
218         return NTS_ERR_FAILED;
219     }
220
221     return NTS_ERR_OK;
222 }
223
224 int manager_sr_stats_get_items_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, const char *request_xpath, uint32_t request_id, struct lyd_node **parent, void *private_data) {
225     char value[128];
226
227     *parent = lyd_new_path(NULL, sr_get_context(sr_session_get_connection(session)), NTS_MANAGER_SIMULATION_SCHEMA_XPATH, 0, 0, 0);
228     if(*parent == 0) {
229         log_error("lyd_new_path failed\n");
230         return SR_ERR_OPERATION_FAILED;
231     }
232
233     int docker_instances_count = 0;
234     for(int i = 0; i < docker_context_count; i++) {
235         docker_instances_count += manager_context[i].started_instances;
236     }
237
238     const char **instances_id = malloc(sizeof(char *) * docker_instances_count);
239     if(instances_id == 0) {
240         log_error("malloc failed\n");
241         return SR_ERR_OPERATION_FAILED;
242     }
243
244     int k = 0;
245     for(int i = 0; i < docker_context_count; i++) {
246         for(int j = 0; j < manager_context[i].started_instances; j++) {
247             instances_id[k] = manager_context[i].instance[j].container.id;
248             k++;
249         }
250     }
251
252     docker_usage_t usage;
253     int rc = docker_usage_get(instances_id, docker_instances_count, &usage);
254     free(instances_id);
255     if(rc != NTS_ERR_OK) {
256         log_error("docker_usage_get failed\n");
257         return SR_ERR_OPERATION_FAILED;
258     }
259
260     sprintf(value, "%.2f", usage.cpu);
261     if(lyd_new_path(*parent, NULL, NTS_MANAGER_SIMULATION_SCHEMA_XPATH"/cpu-usage", value, 0, 0) == 0) {
262         log_error("lyd_new_path failed\n");
263         return SR_ERR_OPERATION_FAILED;
264     }
265
266     sprintf(value, "%.0f", usage.mem);
267     if(lyd_new_path(*parent, NULL, NTS_MANAGER_SIMULATION_SCHEMA_XPATH"/mem-usage", value, 0, 0) == 0) {
268         log_error("lyd_new_path failed\n");
269         return SR_ERR_OPERATION_FAILED;
270     }
271
272     return SR_ERR_OK;
273 }
274
275 int manager_sr_populate_networking(struct lyd_node *parent, const manager_network_function_instance_t* instance) {
276     assert(instance);
277     assert(parent);
278
279
280     struct lyd_node *networking = lyd_new(parent, parent->schema->module, "networking");
281     if(networking == 0) {
282         log_error("lyd_new failed\n");
283         return NTS_ERR_FAILED;
284     }
285
286     if(lyd_new_leaf(networking, parent->schema->module, "docker-ip", instance->container.docker_ip) == 0) {
287         log_error("lyd_new_leaf failed\n");
288         return NTS_ERR_FAILED;
289     }
290
291     if(lyd_new_leaf(networking, parent->schema->module, "host-ip", instance->container.host_ip) == 0) {
292         log_error("lyd_new_leaf failed\n");
293         return NTS_ERR_FAILED;
294     }
295
296     //netconf ssh ports
297     for(int k = 0; k < framework_environment.settings.ssh_connections; k++) {
298         char value[128];
299         
300         struct lyd_node *ports = lyd_new(networking, parent->schema->module, "docker-ports");
301         if(ports == 0) {
302             log_error("lyd_new failed\n");
303             return NTS_ERR_FAILED;
304         }
305
306         sprintf(value, "%d", instance->container.docker_netconf_ssh_port + k);
307         if(lyd_new_leaf(ports, ports->schema->module, "port", value) == 0) {
308             log_error("lyd_new_leaf failed\n");
309             return NTS_ERR_FAILED;
310         }
311
312         if(lyd_new_leaf(ports, ports->schema->module, "protocol", "nts-common:NTS_PROTOCOL_TYPE_NETCONF_SSH") == 0) {
313             log_error("lyd_new_leaf failed\n");
314             return NTS_ERR_FAILED;
315         }
316
317
318         ports = lyd_new(networking, parent->schema->module, "host-ports");
319         if(ports == 0) {
320             log_error("lyd_new failed\n");
321             return NTS_ERR_FAILED;
322         }
323
324         sprintf(value, "%d", instance->container.host_netconf_ssh_port + k);
325         if(lyd_new_leaf(ports, ports->schema->module, "port", value) == 0) {
326             log_error("lyd_new_leaf failed\n");
327             return NTS_ERR_FAILED;
328         }
329
330         if(lyd_new_leaf(ports, ports->schema->module, "protocol", "nts-common:NTS_PROTOCOL_TYPE_NETCONF_SSH") == 0) {
331             log_error("lyd_new_leaf failed\n");
332             return NTS_ERR_FAILED;
333         }
334     }
335
336     //netconf tls ports
337     for(int k = 0; k < framework_environment.settings.tls_connections; k++) {
338         char value[128];
339         
340         struct lyd_node *ports = lyd_new(networking, parent->schema->module, "docker-ports");
341         if(ports == 0) {
342             log_error("lyd_new failed\n");
343             return NTS_ERR_FAILED;
344         }
345
346         sprintf(value, "%d", instance->container.docker_netconf_tls_port + k);
347         if(lyd_new_leaf(ports, ports->schema->module, "port", value) == 0) {
348             log_error("lyd_new_leaf failed\n");
349             return NTS_ERR_FAILED;
350         }
351
352         if(lyd_new_leaf(ports, ports->schema->module, "protocol", "nts-common:NTS_PROTOCOL_TYPE_NETCONF_TLS") == 0) {
353             log_error("lyd_new_leaf failed\n");
354             return NTS_ERR_FAILED;
355         }
356
357
358         ports = lyd_new(networking, parent->schema->module, "host-ports");
359         if(ports == 0) {
360             log_error("lyd_new failed\n");
361             return NTS_ERR_FAILED;
362         }
363
364         sprintf(value, "%d", instance->container.host_netconf_tls_port + k);
365         if(lyd_new_leaf(ports, ports->schema->module, "port", value) == 0) {
366             log_error("lyd_new_leaf failed\n");
367             return NTS_ERR_FAILED;
368         }
369
370         if(lyd_new_leaf(ports, ports->schema->module, "protocol", "nts-common:NTS_PROTOCOL_TYPE_NETCONF_TLS") == 0) {
371             log_error("lyd_new_leaf failed\n");
372             return NTS_ERR_FAILED;
373         }
374     }
375
376     //ftp ports
377     for(int k = 0; k < framework_environment.settings.ftp_connections; k++) {
378         char value[128];
379         
380         struct lyd_node *ports = lyd_new(networking, parent->schema->module, "docker-ports");
381         if(ports == 0) {
382             log_error("lyd_new failed\n");
383             return NTS_ERR_FAILED;
384         }
385
386         sprintf(value, "%d", instance->container.docker_ftp_port + k);
387         if(lyd_new_leaf(ports, ports->schema->module, "port", value) == 0) {
388             log_error("lyd_new_leaf failed\n");
389             return NTS_ERR_FAILED;
390         }
391
392         if(lyd_new_leaf(ports, ports->schema->module, "protocol", "nts-common:NTS_PROTOCOL_TYPE_FTP") == 0) {
393             log_error("lyd_new_leaf failed\n");
394             return NTS_ERR_FAILED;
395         }
396
397
398         ports = lyd_new(networking, parent->schema->module, "host-ports");
399         if(ports == 0) {
400             log_error("lyd_new failed\n");
401             return NTS_ERR_FAILED;
402         }
403
404         sprintf(value, "%d", instance->container.host_ftp_port + k);
405         if(lyd_new_leaf(ports, ports->schema->module, "port", value) == 0) {
406             log_error("lyd_new_leaf failed\n");
407             return NTS_ERR_FAILED;
408         }
409
410         if(lyd_new_leaf(ports, ports->schema->module, "protocol", "nts-common:NTS_PROTOCOL_TYPE_FTP") == 0) {
411             log_error("lyd_new_leaf failed\n");
412             return NTS_ERR_FAILED;
413         }
414     }
415
416     //sftp ports
417     for(int k = 0; k < framework_environment.settings.sftp_connections; k++) {
418         char value[128];
419         
420         struct lyd_node *ports = lyd_new(networking, parent->schema->module, "docker-ports");
421         if(ports == 0) {
422             log_error("lyd_new failed\n");
423             return NTS_ERR_FAILED;
424         }
425
426         sprintf(value, "%d", instance->container.docker_sftp_port + k);
427         if(lyd_new_leaf(ports, ports->schema->module, "port", value) == 0) {
428             log_error("lyd_new_leaf failed\n");
429             return NTS_ERR_FAILED;
430         }
431
432         if(lyd_new_leaf(ports, ports->schema->module, "protocol", "nts-common:NTS_PROTOCOL_TYPE_SFTP") == 0) {
433             log_error("lyd_new_leaf failed\n");
434             return NTS_ERR_FAILED;
435         }
436
437
438         ports = lyd_new(networking, parent->schema->module, "host-ports");
439         if(ports == 0) {
440             log_error("lyd_new failed\n");
441             return NTS_ERR_FAILED;
442         }
443
444         sprintf(value, "%d", instance->container.host_sftp_port + k);
445         if(lyd_new_leaf(ports, ports->schema->module, "port", value) == 0) {
446             log_error("lyd_new_leaf failed\n");
447             return NTS_ERR_FAILED;
448         }
449
450         if(lyd_new_leaf(ports, ports->schema->module, "protocol", "nts-common:NTS_PROTOCOL_TYPE_SFTP") == 0) {
451             log_error("lyd_new_leaf failed\n");
452             return NTS_ERR_FAILED;
453         }
454     }
455
456     return NTS_ERR_OK;
457 }