1 /*************************************************************************
3 * Copyright 2020 highstreet technologies GmbH and others
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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 ***************************************************************************/
21 #include "utils/log_utils.h"
22 #include "utils/sys_utils.h"
27 #include <sysrepo/values.h>
29 #include "core/framework.h"
30 #include "core/session.h"
31 #include "core/context.h"
32 #include "core/docker.h"
34 #define NTS_MANAGER_MODULE "nts-manager"
35 #define NTS_SIMULATION_SCHEMA_XPATH "/nts-manager:simulation"
36 #define NTS_FUNCTION_LIST_SCHEMA_XPATH "/nts-manager:simulation/network-functions/network-function"
37 #define NTS_SDN_CONTROLLER_CONFIG_XPATH "/nts-manager:simulation/sdn-controller"
38 #define NTS_VES_ENDPOINT_CONFIG_XPATH "/nts-manager:simulation/ves-endpoint"
40 #define NTS_NETWORK_FUNCTION_FTYPE_SCHEMA_XPATH "/nts-network-function:simulation/network-function/function-type"
42 static manager_network_function_type *manager_context = 0;
43 static int manager_installed_function_types_count = 0;
45 static int manager_populate_sysrepo_network_function_list(void);
46 static int manager_populate_static_status(void);
48 static void manager_context_free(manager_network_function_type *context);
50 static int manager_process_change(int context_index, manager_network_function_type *new_context);
51 static int manager_change_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, sr_event_t event, uint32_t request_id, void *private_data);
52 static int manager_instances_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);
53 static int manager_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);
55 int manager_run(void) {
58 log_message(1, LOG_COLOR_BOLD_YELLOW"\nrunning as MANAGER daemon...\n"LOG_COLOR_RESET);
60 manager_operations_init();
63 //get installed function types
64 struct lys_node_leaf *elem = (struct lys_node_leaf *)ly_ctx_get_node(session_context, 0, NTS_FUNCTION_LIST_SCHEMA_XPATH"/function-type", 0);
66 log_error("ly_ctx_get_node failed for xpath: %s", NTS_FUNCTION_LIST_SCHEMA_XPATH"/function-type");
67 return NTS_ERR_FAILED;
70 struct lys_ident **found = 0;
71 manager_installed_function_types_count = context_get_identity_leafs_of_type(elem->type.info.ident.ref[0], &found);
72 if(!manager_installed_function_types_count) {
73 log_error("error network functions");
74 return NTS_ERR_FAILED;
77 //initial list population
78 manager_context = (manager_network_function_type *)malloc(sizeof(manager_network_function_type) * manager_installed_function_types_count);
79 for(int i = 0; i < manager_installed_function_types_count; i++) {
80 manager_context[i].instance = 0;
82 manager_context[i].function_type = found[i];
83 asprintf(&manager_context[i].function_type_string, "%s:%s", found[i]->module->name, found[i]->name);
84 manager_context[i].docker_image_name = manager_context[i].function_type->ref;
85 manager_context[i].started_instances = 0;
86 manager_context[i].mounted_instances = 0;
87 manager_context[i].mount_point_addressing_method = strdup("docker-mapping");
88 manager_context[i].docker_instance_name = strdup(manager_context[i].function_type->name);
89 manager_context[i].docker_version_tag = strdup("latest");
90 manager_context[i].docker_repository = strdup("local");
94 //do initial sysrepo list population
95 int rc = manager_populate_sysrepo_network_function_list();
96 if(rc != NTS_ERR_OK) {
97 log_error("manager_populate_sysrepo_network_function_list failed");
98 return NTS_ERR_FAILED;
101 rc = manager_populate_static_status();
102 if(rc != NTS_ERR_OK) {
103 log_error("manager_populate_static_status failed");
104 return NTS_ERR_FAILED;
107 //subscribe to any changes on the list
108 rc = sr_module_change_subscribe(session_running, NTS_MANAGER_MODULE, NTS_SIMULATION_SCHEMA_XPATH, manager_change_cb, NULL, 0, SR_SUBSCR_CTX_REUSE, &session_subscription);
109 if(rc != SR_ERR_OK) {
110 log_error("could not subscribe to simulation changes");
111 return NTS_ERR_FAILED;
114 rc = sr_oper_get_items_subscribe(session_running, NTS_MANAGER_MODULE, NTS_FUNCTION_LIST_SCHEMA_XPATH, manager_instances_get_items_cb, NULL, SR_SUBSCR_CTX_REUSE, &session_subscription);
115 if(rc != SR_ERR_OK) {
116 log_error("could not subscribe to oper faults");
120 rc = sr_oper_get_items_subscribe(session_running, NTS_MANAGER_MODULE, NTS_SIMULATION_SCHEMA_XPATH, manager_stats_get_items_cb, NULL, SR_SUBSCR_CTX_REUSE, &session_subscription);
121 if(rc != SR_ERR_OK) {
122 log_error("could not subscribe to oper faults");
127 while(!framework_sigint) {
131 for(int i = 0; i < manager_installed_function_types_count; i++) {
132 while(manager_context[i].started_instances) {
133 manager_stop_instance(&manager_context[i]);
135 manager_context_free(&manager_context[i]);
138 free(manager_context);
143 static int manager_populate_sysrepo_network_function_list(void) {
144 //check whether everything is already populated, read and update (if previously ran)
145 sr_val_t *values = 0;
146 size_t value_count = 0;
147 int rc = sr_get_items(session_running, NTS_FUNCTION_LIST_SCHEMA_XPATH, 0, 0, &values, &value_count);
148 if(rc != SR_ERR_OK) {
149 log_error("get items failed");
150 return NTS_ERR_FAILED;
153 //either get values, or if data inconclusive, delete everything
155 log_message(2, "nts-manager instances found (%d). cleaning up for fresh start...\n", value_count);
157 for(int i = 0; i < value_count; i++) {
158 rc = sr_delete_item(session_running, values[i].xpath, 0);
159 if(rc != SR_ERR_OK) {
160 log_error("sr_delete_item failed");
161 return NTS_ERR_FAILED;
164 rc = sr_apply_changes(session_running, 0, 0);
165 if(rc != SR_ERR_OK) {
166 log_error("sr_apply_changes failed");
167 return NTS_ERR_FAILED;
171 //populate everything if needed
172 for(int i = 0; i < manager_installed_function_types_count; i++) {
175 asprintf(&xpath, "%s[function-type='%s']/function-type", NTS_FUNCTION_LIST_SCHEMA_XPATH, manager_context[i].function_type_string);
176 rc = sr_set_item_str(session_running, xpath, (const char *)manager_context[i].function_type_string, 0, 0);
177 if(rc != SR_ERR_OK) {
178 log_error("sr_set_item_str failed");
179 return NTS_ERR_FAILED;
183 asprintf(&xpath, "%s[function-type='%s']/started-instances", NTS_FUNCTION_LIST_SCHEMA_XPATH, manager_context[i].function_type_string);
184 rc = sr_set_item_str(session_running, xpath, "0", 0, 0);
185 if(rc != SR_ERR_OK) {
186 log_error("sr_set_item_str failed");
187 return NTS_ERR_FAILED;
191 asprintf(&xpath, "%s[function-type='%s']/mounted-instances", NTS_FUNCTION_LIST_SCHEMA_XPATH, manager_context[i].function_type_string);
192 rc = sr_set_item_str(session_running, xpath, "0", 0, 0);
193 if(rc != SR_ERR_OK) {
194 log_error("sr_set_item_str failed");
195 return NTS_ERR_FAILED;
199 asprintf(&xpath, "%s[function-type='%s']/mount-point-addressing-method", NTS_FUNCTION_LIST_SCHEMA_XPATH, manager_context[i].function_type_string);
200 rc = sr_set_item_str(session_running, xpath, (const char*)manager_context[i].mount_point_addressing_method, 0, 0);
201 if(rc != SR_ERR_OK) {
202 log_error("sr_set_item_str failed");
203 return NTS_ERR_FAILED;
207 asprintf(&xpath, "%s[function-type='%s']/docker-instance-name", NTS_FUNCTION_LIST_SCHEMA_XPATH, manager_context[i].function_type_string);
208 rc = sr_set_item_str(session_running, xpath, (const char*)manager_context[i].docker_instance_name, 0, 0);
209 if(rc != SR_ERR_OK) {
210 log_error("sr_set_item_str failed");
211 return NTS_ERR_FAILED;
215 asprintf(&xpath, "%s[function-type='%s']/docker-version-tag", NTS_FUNCTION_LIST_SCHEMA_XPATH, manager_context[i].function_type_string);
216 rc = sr_set_item_str(session_running, xpath, (const char*)manager_context[i].docker_version_tag, 0, 0);
217 if(rc != SR_ERR_OK) {
218 log_error("sr_set_item_str failed");
219 return NTS_ERR_FAILED;
223 asprintf(&xpath, "%s[function-type='%s']/docker-repository", NTS_FUNCTION_LIST_SCHEMA_XPATH, manager_context[i].function_type_string);
224 rc = sr_set_item_str(session_running, xpath, (const char*)manager_context[i].docker_repository, 0, 0);
225 if(rc != SR_ERR_OK) {
226 log_error("sr_set_item_str failed");
227 return NTS_ERR_FAILED;
234 //setup sdn-controller defaults
235 if(strlen(framework_environment.sdn_controller_ip)) {
236 rc = sr_set_item_str(session_running, NTS_SDN_CONTROLLER_CONFIG_XPATH"/controller-ip", (const char*)framework_environment.sdn_controller_ip, 0, 0);
237 if(rc != SR_ERR_OK) {
238 log_error("sr_set_item_str failed");
239 return NTS_ERR_FAILED;
243 sprintf(int_to_str, "%d", framework_environment.sdn_controller_port);
244 rc = sr_set_item_str(session_running, NTS_SDN_CONTROLLER_CONFIG_XPATH"/controller-port", (const char*)int_to_str, 0, 0);
245 if(rc != SR_ERR_OK) {
246 log_error("sr_set_item_str failed");
247 return NTS_ERR_FAILED;
250 sprintf(int_to_str, "%d", framework_environment.sdn_controller_callhome_port);
251 rc = sr_set_item_str(session_running, NTS_SDN_CONTROLLER_CONFIG_XPATH"/controller-netconf-call-home-port", (const char*)int_to_str, 0, 0);
252 if(rc != SR_ERR_OK) {
253 log_error("sr_set_item_str failed");
254 return NTS_ERR_FAILED;
257 if(strlen(framework_environment.sdn_controller_username)) {
258 rc = sr_set_item_str(session_running, NTS_SDN_CONTROLLER_CONFIG_XPATH"/controller-username", (const char*)framework_environment.sdn_controller_username, 0, 0);
259 if(rc != SR_ERR_OK) {
260 log_error("sr_set_item_str failed");
261 return NTS_ERR_FAILED;
265 if(strlen(framework_environment.sdn_controller_password)) {
266 rc = sr_set_item_str(session_running, NTS_SDN_CONTROLLER_CONFIG_XPATH"/controller-password", (const char*)framework_environment.sdn_controller_password, 0, 0);
267 if(rc != SR_ERR_OK) {
268 log_error("sr_set_item_str failed");
269 return NTS_ERR_FAILED;
273 //setup ves-endpoint details
274 if(strlen(framework_environment.ves_endpoint_protocol)) {
275 rc = sr_set_item_str(session_running, NTS_VES_ENDPOINT_CONFIG_XPATH"/ves-endpoint-protocol", (const char*)framework_environment.ves_endpoint_protocol, 0, 0);
276 if(rc != SR_ERR_OK) {
277 log_error("sr_set_item_str failed");
278 return NTS_ERR_FAILED;
282 if(strlen(framework_environment.ves_endpoint_ip)) {
283 rc = sr_set_item_str(session_running, NTS_VES_ENDPOINT_CONFIG_XPATH"/ves-endpoint-ip", (const char*)framework_environment.ves_endpoint_ip, 0, 0);
284 if(rc != SR_ERR_OK) {
285 log_error("sr_set_item_str failed");
286 return NTS_ERR_FAILED;
290 sprintf(int_to_str, "%d", framework_environment.ves_endpoint_port);
291 rc = sr_set_item_str(session_running, NTS_VES_ENDPOINT_CONFIG_XPATH"/ves-endpoint-port", (const char*)int_to_str, 0, 0);
292 if(rc != SR_ERR_OK) {
293 log_error("sr_set_item_str failed");
294 return NTS_ERR_FAILED;
297 if(strlen(framework_environment.ves_endpoint_auth_method)) {
298 rc = sr_set_item_str(session_running, NTS_VES_ENDPOINT_CONFIG_XPATH"/ves-endpoint-auth-method", (const char*)framework_environment.ves_endpoint_auth_method, 0, 0);
299 if(rc != SR_ERR_OK) {
300 log_error("sr_set_item_str failed");
301 return NTS_ERR_FAILED;
305 if(strlen(framework_environment.ves_endpoint_username)) {
306 rc = sr_set_item_str(session_running, NTS_VES_ENDPOINT_CONFIG_XPATH"/ves-endpoint-username", (const char*)framework_environment.ves_endpoint_username, 0, 0);
307 if(rc != SR_ERR_OK) {
308 log_error("sr_set_item_str failed");
309 return NTS_ERR_FAILED;
313 if(strlen(framework_environment.ves_endpoint_password)) {
314 rc = sr_set_item_str(session_running, NTS_VES_ENDPOINT_CONFIG_XPATH"/ves-endpoint-password", (const char*)framework_environment.ves_endpoint_password, 0, 0);
315 if(rc != SR_ERR_OK) {
316 log_error("sr_set_item_str failed");
317 return NTS_ERR_FAILED;
321 if(strlen(framework_environment.ves_endpoint_certificate)) {
322 rc = sr_set_item_str(session_running, NTS_VES_ENDPOINT_CONFIG_XPATH"/ves-endpoint-certificate", (const char*)framework_environment.ves_endpoint_certificate, 0, 0);
323 if(rc != SR_ERR_OK) {
324 log_error("sr_set_item_str failed");
325 return NTS_ERR_FAILED;
329 rc = sr_set_item_str(session_running, NTS_NETWORK_FUNCTION_FTYPE_SCHEMA_XPATH, "NTS_FUNCTION_TYPE_MANAGER", 0, 0);
330 if(rc != SR_ERR_OK) {
331 log_error("sr_set_item_str failed");
332 return NTS_ERR_FAILED;
337 rc = sr_apply_changes(session_running, 0, 0);
338 if(rc != SR_ERR_OK) {
339 log_error("sr_apply_changes failed: %s", sr_strerror(rc));
340 return NTS_ERR_FAILED;
346 static int manager_populate_static_status(void) {
351 //setup sdn-controller defaults
352 sprintf(int_to_str, "%d", framework_environment.host_base_port);
353 int rc = sr_set_item_str(session_operational, NTS_SIMULATION_SCHEMA_XPATH"/base-port", (const char*)int_to_str, 0, 0);
354 if(rc != SR_ERR_OK) {
355 log_error("sr_set_item_str failed");
356 return NTS_ERR_FAILED;
359 sprintf(int_to_str, "%d", framework_environment.ssh_connections);
360 rc = sr_set_item_str(session_operational, NTS_SIMULATION_SCHEMA_XPATH"/ssh-connections", (const char*)int_to_str, 0, 0);
361 if(rc != SR_ERR_OK) {
362 log_error("sr_set_item_str failed");
363 return NTS_ERR_FAILED;
366 sprintf(int_to_str, "%d", framework_environment.tls_connections);
367 rc = sr_set_item_str(session_operational, NTS_SIMULATION_SCHEMA_XPATH"/tls-connections", (const char*)int_to_str, 0, 0);
368 if(rc != SR_ERR_OK) {
369 log_error("sr_set_item_str failed");
370 return NTS_ERR_FAILED;
374 rc = sr_apply_changes(session_operational, 0, 0);
375 if(rc != SR_ERR_OK) {
376 log_error("sr_apply_changes failed");
377 return NTS_ERR_FAILED;
383 static void manager_context_free(manager_network_function_type *context) {
386 free(context->function_type_string);
387 free(context->mount_point_addressing_method);
388 free(context->docker_instance_name);
389 free(context->docker_version_tag);
390 free(context->docker_repository);
393 //take note that this happens in the sysrepo thread
394 static int manager_process_change(int context_index, manager_network_function_type *new_context) {
395 assert(context_index < manager_installed_function_types_count);
398 manager_network_function_type *current_context = &manager_context[context_index];
401 current_context->data_changed |= new_context->data_changed;
403 //process changes, and update data in current_context to resemble new_context
404 if(new_context->docker_instance_name != 0) {
405 free(current_context->docker_instance_name);
406 current_context->docker_instance_name = strdup(new_context->docker_instance_name);
409 if(new_context->docker_version_tag != 0) {
410 free(current_context->docker_version_tag);
411 current_context->docker_version_tag = strdup(new_context->docker_version_tag);
414 if(new_context->docker_repository != 0) {
415 free(current_context->docker_repository);
416 current_context->docker_repository = strdup(new_context->docker_repository);
419 if(new_context->mount_point_addressing_method != 0) {
420 free(current_context->mount_point_addressing_method);
421 current_context->mount_point_addressing_method = strdup(new_context->mount_point_addressing_method);
424 if(new_context->started_instances != -1) {
425 if(new_context->started_instances < current_context->started_instances) {
426 //remove started instances
427 while(current_context->started_instances > new_context->started_instances) {
428 log_message(2, "stopping instance of type %s\n", current_context->function_type_string);
429 rc = manager_stop_instance(current_context);
430 if(rc != NTS_ERR_OK) {
431 log_error("manager_stop_instance failed");
432 return NTS_ERR_FAILED;
437 else if(new_context->started_instances > current_context->started_instances) {
438 //add started instances
439 while(current_context->started_instances < new_context->started_instances) {
440 log_message(2, "staring instance of type %s\n", current_context->function_type_string);
441 rc = manager_start_instance(current_context);
442 if(rc != NTS_ERR_OK) {
443 log_error("manager_start_instance failed");
444 return NTS_ERR_FAILED;
451 if(new_context->mounted_instances != -1) {
452 if(new_context->mounted_instances < current_context->mounted_instances) {
453 //remove mounted instances
454 while(current_context->mounted_instances > new_context->mounted_instances) {
455 log_message(2, "unmounting instance of type %s\n", current_context->function_type_string);
456 rc = manager_unmount_instance(current_context);
457 if(rc != NTS_ERR_OK) {
458 log_error("manager_unmount_instance failed");
463 else if(new_context->mounted_instances > current_context->mounted_instances) {
464 //add mounted instances
465 while(current_context->mounted_instances < new_context->mounted_instances) {
466 log_message(2, "mouting instance of type %s\n", current_context->function_type_string);
467 rc = manager_mount_instance(current_context);
468 if(rc != NTS_ERR_OK) {
469 log_error("manager_mount_instance failed");
479 static int manager_change_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, sr_event_t event, uint32_t request_id, void *private_data) {
480 sr_change_iter_t *it = 0;
482 sr_change_oper_t oper;
483 sr_val_t *old_value = 0;
484 sr_val_t *new_value = 0;
486 if(event == SR_EV_CHANGE) {
487 manager_network_function_type new_context;
488 new_context.function_type = 0; //not to be used. use only from current_context
489 new_context.function_type_string = 0; //not to be used. use only from current_context
492 rc = sr_get_changes_iter(session, NTS_FUNCTION_LIST_SCHEMA_XPATH"//.", &it);
493 if(rc != SR_ERR_OK) {
494 log_error("sr_get_changes_iter failed");
495 return SR_ERR_VALIDATION_FAILED;
498 while((rc = sr_get_change_next(session, it, &oper, &old_value, &new_value)) == SR_ERR_OK) {
499 char *ov = sr_val_to_str(old_value);
500 char *nv = sr_val_to_str(new_value);
502 //get function type and index
503 char *function_type_string = strdup(strstr(new_value->xpath, "function-type='") + 15);
504 *strchr(function_type_string, '\'') = 0;
507 if((new_context.function_type_string == 0) || (strcmp(new_context.function_type_string, function_type_string) != 0)) {
509 if(new_context.function_type_string != 0) {
510 if(manager_process_change(index, &new_context) != NTS_ERR_OK) {
511 manager_context_free(&new_context);
512 return SR_ERR_VALIDATION_FAILED;
515 manager_context_free(&new_context);
519 new_context.function_type_string = function_type_string;
520 new_context.started_instances = -1;
521 new_context.mounted_instances = -1;
522 new_context.mount_point_addressing_method = 0;
523 new_context.docker_instance_name = 0;
524 new_context.docker_version_tag = 0;
525 new_context.docker_repository = 0;
527 new_context.data_changed = false;
529 //find intex in manager_context[]
530 for(int i = 0; i < manager_installed_function_types_count; i++) {
531 if(strcmp(function_type_string, manager_context[i].function_type_string) == 0) {
538 char *leaf_path = strdup(strstr(new_value->xpath, "']/") + 3);
539 if(strcmp(leaf_path, "started-instances") == 0) {
540 new_context.started_instances = new_value->data.uint16_val;
542 else if(strcmp(leaf_path, "mounted-instances") == 0) {
543 new_context.mounted_instances = new_value->data.uint16_val;
545 else if(strcmp(leaf_path, "mount-point-addressing-method") == 0) {
546 new_context.mount_point_addressing_method = strdup(nv);
548 else if(strcmp(leaf_path, "docker-instance-name") == 0) {
549 new_context.docker_instance_name = strdup(nv);
551 else if(strcmp(leaf_path, "docker-version-tag") == 0) {
552 new_context.docker_version_tag = strdup(nv);
554 else if(strcmp(leaf_path, "docker-repository") == 0) {
555 new_context.docker_repository = strdup(nv);
558 new_context.data_changed = true;
564 sr_free_val(old_value);
565 sr_free_val(new_value);
568 sr_free_change_iter(it);
571 if(manager_process_change(index, &new_context) != NTS_ERR_OK) {
572 manager_context_free(&new_context);
573 return SR_ERR_VALIDATION_FAILED;
576 manager_context_free(&new_context);
579 else if(event == SR_EV_DONE) {
580 bool global_change = true;
582 rc = sr_get_changes_iter(session, NTS_SIMULATION_SCHEMA_XPATH"//.", &it);
583 if(rc != SR_ERR_OK) {
584 log_error("sr_get_changes_iter failed");
585 return SR_ERR_VALIDATION_FAILED;
588 while((rc = sr_get_change_next(session, it, &oper, &old_value, &new_value)) == SR_ERR_OK) {
589 if(strstr(new_value->xpath, NTS_FUNCTION_LIST_SCHEMA_XPATH) == new_value->xpath) {
590 global_change = false;
591 sr_free_val(old_value);
592 sr_free_val(new_value);
596 sr_free_val(old_value);
597 sr_free_val(new_value);
600 sr_free_change_iter(it);
602 // commit all updates
603 for(int i = 0; i < manager_installed_function_types_count; i++) {
604 for(int j = 0; j < manager_context[i].started_instances; j++) {
605 if(global_change || manager_context[i].data_changed || (manager_context[i].instance[j].is_configured == false)) {
606 log_message(2, "configuring instance %d of type %s\n", j, manager_context[i].function_type_string);
607 rc = manager_config_instance(&manager_context[i], &manager_context[i].instance[j]);
608 if(rc != NTS_ERR_OK) {
609 log_error("manager_config_instance failed");
614 manager_context[i].data_changed = false;
616 global_change = false;
622 static int manager_instances_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) {
626 *parent = lyd_new_path(NULL, sr_get_context(sr_session_get_connection(session)), NTS_FUNCTION_LIST_SCHEMA_XPATH, 0, 0, 0);
628 log_error("lyd_new_path failed");
629 return SR_ERR_OPERATION_FAILED;
632 for(int i = 0; i < manager_installed_function_types_count; i++) {
633 char *ftype_path = 0;
634 asprintf(&ftype_path, "%s[function-type='%s']/instances/instance", NTS_FUNCTION_LIST_SCHEMA_XPATH, manager_context[i].function_type_string);
635 for(int j = 0; j < manager_context[i].started_instances; j++) {
636 char *instance_path = 0;
637 asprintf(&instance_path, "%s[name='%s']", ftype_path, manager_context[i].instance[j].name);
641 asprintf(&full_path, "%s/mount-point-addressing-method", instance_path);
642 if(lyd_new_path(*parent, NULL, full_path, manager_context[i].instance[j].mount_point_addressing_method, 0, 0) == 0) {
643 log_error("lyd_new_path failed");
644 return SR_ERR_OPERATION_FAILED;
648 asprintf(&full_path, "%s/networking/docker-ip", instance_path);
649 if(lyd_new_path(*parent, NULL, full_path, manager_context[i].instance[j].docker_ip, 0, 0) == 0) {
650 log_error("lyd_new_path failed");
651 return SR_ERR_OPERATION_FAILED;
655 asprintf(&full_path, "%s/networking/docker-port", instance_path);
656 sprintf(value, "%d", manager_context[i].instance[j].docker_port);
657 if(lyd_new_path(*parent, NULL, full_path, value, 0, 0) == 0) {
658 log_error("lyd_new_path failed");
659 return SR_ERR_OPERATION_FAILED;
663 asprintf(&full_path, "%s/networking/host-ip", instance_path);
664 if(lyd_new_path(*parent, NULL, full_path, manager_context[i].instance[j].host_ip, 0, 0) == 0) {
665 log_error("lyd_new_path failed");
666 return SR_ERR_OPERATION_FAILED;
670 asprintf(&full_path, "%s/networking/host-port", instance_path);
671 sprintf(value, "%d", manager_context[i].instance[j].host_port);
672 if(lyd_new_path(*parent, NULL, full_path, value, 0, 0) == 0) {
673 log_error("lyd_new_path failed");
674 return SR_ERR_OPERATION_FAILED;
686 static int manager_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) {
689 *parent = lyd_new_path(NULL, sr_get_context(sr_session_get_connection(session)), NTS_SIMULATION_SCHEMA_XPATH, 0, 0, 0);
691 return SR_ERR_OPERATION_FAILED;
694 docker_usage_t usage = docker_usage_get(manager_context, manager_installed_function_types_count);
696 sprintf(value, "%.2f", usage.cpu);
697 if(lyd_new_path(*parent, NULL, NTS_SIMULATION_SCHEMA_XPATH"/cpu-usage", value, 0, 0) == 0) {
698 return SR_ERR_OPERATION_FAILED;
701 sprintf(value, "%.0f", usage.mem);
702 if(lyd_new_path(*parent, NULL, NTS_SIMULATION_SCHEMA_XPATH"/mem-usage", value, 0, 0) == 0) {
703 return SR_ERR_OPERATION_FAILED;
706 //setup sdn-controller defaults
707 sprintf(value, "%d", framework_environment.host_base_port);
708 if(lyd_new_path(*parent, NULL, NTS_SIMULATION_SCHEMA_XPATH"/base-port", value, 0, 0) == 0) {
709 return SR_ERR_OPERATION_FAILED;
712 sprintf(value, "%d", framework_environment.ssh_connections);
713 if(lyd_new_path(*parent, NULL, NTS_SIMULATION_SCHEMA_XPATH"/ssh-connections", value, 0, 0) == 0) {
714 return SR_ERR_OPERATION_FAILED;
717 sprintf(value, "%d", framework_environment.tls_connections);
718 if(lyd_new_path(*parent, NULL, NTS_SIMULATION_SCHEMA_XPATH"/tls-connections", value, 0, 0) == 0) {
719 return SR_ERR_OPERATION_FAILED;