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