Bug fix.
[sim/o1-interface.git] / ntsimulator / src / ntsimulator-manager / ntsimulator-manager.c
1 /*************************************************************************
2 *
3 * Copyright 2019 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
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <signal.h>
23 #include <inttypes.h>
24 #include <limits.h>
25 #include <string.h>
26
27 #include "sysrepo.h"
28 #include "sysrepo/values.h"
29
30 #include "utils.h"
31 #include "simulator-operations.h"
32
33 volatile int exit_application = 0;
34
35 volatile unsigned int simulated_devices_config = 0;
36 volatile unsigned int mounted_devices_config = 0;
37
38
39 static device_stack_t *device_list = NULL;
40
41 controller_t controller_details;
42
43 #define XPATH_MAX_LEN 500
44 #define CONTROLLER_LIST_MAX_LEN 1
45
46 static void
47 print_current_config(sr_session_ctx_t *session, const char *module_name)
48 {
49     sr_val_t *values = NULL;
50     size_t count = 0;
51     int rc = SR_ERR_OK;
52     char xpath[XPATH_MAX_LEN] = {0};
53     snprintf(xpath, XPATH_MAX_LEN, "/%s:*//.", module_name);
54
55     sr_val_t *odl_ip = NULL;
56     sr_val_t *odl_port = NULL;
57     sr_val_t *odl_username = NULL;
58     sr_val_t *odl_password = NULL;
59
60     rc = sr_get_items(session, xpath, &values, &count);
61     if (SR_ERR_OK != rc) {
62         printf("Error by sr_get_items: %s\n", sr_strerror(rc));
63         return;
64     }
65     for (size_t i = 0; i < count; i++){
66
67         sr_print_val(&values[i]);
68
69         if (sr_xpath_node_name_eq(values[i].xpath, "controller-ip"))
70         {
71                 rc = sr_dup_val(&values[i], &odl_ip);
72         }
73         else if (sr_xpath_node_name_eq(values[i].xpath, "controller-port"))
74         {
75                 rc = sr_dup_val(&values[i], &odl_port);
76         }
77         else if (sr_xpath_node_name_eq(values[i].xpath, "controller-username"))
78         {
79                 rc = sr_dup_val(&values[i], &odl_username);
80         }
81         else if (sr_xpath_node_name_eq(values[i].xpath, "controller-password"))
82         {
83                 rc = sr_dup_val(&values[i], &odl_password);
84         }
85     }
86
87     char *ipv6 = strchr(odl_ip->data.string_val, ':');
88     char odl_ip_string[URL_AND_CREDENTIALS_MAX_LEN];
89     if (ipv6 != NULL)
90     {
91         sprintf(odl_ip_string, "[%s]", odl_ip->data.string_val);
92     }
93     else
94     {
95         sprintf(odl_ip_string, "%s", odl_ip->data.string_val);
96     }
97
98
99     //URL used for mounting/unmounting a device; the device name needs to be appended
100    char url[URL_AND_CREDENTIALS_MAX_LEN];
101    sprintf(url, "http://%s:%d/restconf/config/network-topology:network-topology/topology/"
102                  "topology-netconf/node/",
103                  odl_ip_string, odl_port->data.uint32_val);
104
105    char credentials[URL_AND_CREDENTIALS_MAX_LEN];
106    sprintf(credentials, "%s:%s", odl_username->data.string_val, odl_password->data.string_val);
107
108    //URLs used for adding key pair to ODL, for TLS connections
109    char url_for_keystore_add[URL_AND_CREDENTIALS_MAX_LEN];
110    sprintf(url_for_keystore_add, "http://%s:%d/restconf/operations/netconf-keystore:add-keystore-entry",
111                          odl_ip_string, odl_port->data.uint32_val);
112
113    char url_for_private_key_add[URL_AND_CREDENTIALS_MAX_LEN];
114    sprintf(url_for_private_key_add, "http://%s:%d/restconf/operations/netconf-keystore:add-private-key",
115                          odl_ip_string, odl_port->data.uint32_val);
116
117    char url_for_trusted_ca_add[URL_AND_CREDENTIALS_MAX_LEN];
118    sprintf(url_for_trusted_ca_add, "http://%s:%d/restconf/operations/netconf-keystore:add-trusted-certificate",
119                          odl_ip_string, odl_port->data.uint32_val);
120
121    strcpy(controller_details.url, url);
122    strcpy(controller_details.credentials, credentials);
123    strcpy(controller_details.url_for_keystore_add, url_for_keystore_add);
124    strcpy(controller_details.url_for_private_key_add, url_for_private_key_add);
125    strcpy(controller_details.url_for_trusted_ca_add, url_for_trusted_ca_add);
126
127    sr_free_val(odl_ip);
128    sr_free_val(odl_port);
129    sr_free_val(odl_username);
130    sr_free_val(odl_password);
131
132    sr_free_values(values, count);
133 }
134
135 static void clean_current_docker_configuration(void);
136
137 static int simulated_devices_changed(int new_value)
138 {
139         int rc = SR_ERR_OK;
140
141     if (strcmp(getenv("K8S_DEPLOYMENT"), "true") == 0)
142     {
143         if (new_value != simulated_devices_config)
144         {
145             simulated_devices_config = new_value;
146             rc = send_k8s_scale(new_value);
147             if (rc != SR_ERR_OK)
148             {
149                 printf("Could not send new_scale=%d to k8s cluster.\n", new_value);
150             }
151         }
152         return SR_ERR_OK;
153     }
154
155     if (simulated_devices_config > new_value)
156     {
157         //we are configuring less elements that currently
158         for (int i = 0; i < simulated_devices_config - new_value; ++i)
159         {
160                 rc = stop_device(device_list);
161         }
162     }
163     else if (simulated_devices_config < new_value)
164     {
165         //we are configuring more elements that currently
166         for (int i = 0; i < new_value - simulated_devices_config; ++i)
167         {
168                 rc = start_device(device_list);
169             if (rc != SR_ERR_OK)
170             {
171                 printf("ERROR: Could not start simulated device. Ignoring, trying with the next simulated device, if any...\n");
172             }
173         }
174     }
175
176     simulated_devices_config = new_value;
177
178     return rc;
179 }
180
181 int mounted_devices_changed(sr_session_ctx_t *session, int new_value)
182 {
183         int rc = SR_ERR_OK;
184
185         if (mounted_devices_config > new_value)
186         {
187           //we need have less mounted elements
188           for (int i = 0; i < mounted_devices_config - new_value; ++i)
189           {
190                   printf("Sending unmount device...\n");
191                   rc = unmount_device(device_list, controller_details);
192           }
193         }
194         else if (mounted_devices_config < new_value)
195         {
196           //we are configuring more elements that currently
197           for (int i = 0; i < new_value - mounted_devices_config; ++i)
198           {
199                   printf("Sending mount device...\n");
200                   rc = mount_device(device_list, controller_details);
201           }
202         }
203
204         mounted_devices_config = new_value;
205
206     return rc;
207 }
208
209 static int
210 simulator_config_change_cb(sr_session_ctx_t *session, const char *module_name, sr_notif_event_t event, void *private_ctx)
211 {
212         int rc;
213
214     printf("\n\n ========== CONFIG HAS CHANGED, CURRENT RUNNING CONFIG %s: ==========\n\n", module_name);
215     print_current_config(session, module_name);
216
217     sr_val_t *val = NULL;
218
219     /* get the value from sysrepo, we do not care if the value did not change in our case */
220     rc = sr_get_item(session, "/network-topology-simulator:simulator-config/simulated-devices", &val);
221     if (rc != SR_ERR_OK) {
222         goto sr_error;
223     }
224
225     rc = simulated_devices_changed(val->data.uint32_val);
226     if (rc != SR_ERR_OK) {
227         goto sr_error;
228     }
229
230     sr_free_val(val);
231         val = NULL;
232
233     /* get the value from sysrepo, we do not care if the value did not change in our case */
234     rc = sr_get_item(session, "/network-topology-simulator:simulator-config/mounted-devices", &val);
235     if (rc != SR_ERR_OK) {
236         goto sr_error;
237     }
238
239     if (mounted_devices_config != val->data.uint32_val)
240     {
241         if (val->data.uint32_val > simulated_devices_config)
242         {
243                 printf("Cannot set mount value greater than number of simulated devices.\n");
244                 sr_free_val(val);
245                         val = NULL;
246                 return SR_ERR_OK;
247         }
248
249                 rc = mounted_devices_changed(session, val->data.uint32_val);
250                 if (rc != SR_ERR_OK) {
251                         goto sr_error;
252                 }
253     }
254
255     sr_free_val(val);
256         val = NULL;
257
258     size_t count = 0;
259
260     /* get the value from sysrepo, we do not care if the value did not change in our case */
261     rc = sr_get_items(session, "/network-topology-simulator:simulator-config/notification-config/fault-notification-delay-period", &val, &count);
262     if (rc != SR_ERR_OK) {
263         goto sr_error;
264     }
265
266     rc = notification_delay_period_changed(val, count);
267     if (rc != SR_ERR_OK) {
268         goto sr_error;
269     }
270     sr_free_values(val, count);
271         val = NULL;
272
273     /* get the value from sysrepo, we do not care if the value did not change in our case */
274         rc = sr_get_item(session, "/network-topology-simulator:simulator-config/notification-config/ves-heartbeat-period", &val);
275         if (rc != SR_ERR_OK) {
276                 goto sr_error;
277         }
278
279         rc = ves_heartbeat_period_changed(val->data.uint32_val);
280         if (rc != SR_ERR_OK) {
281                 goto sr_error;
282         }
283
284         sr_free_val(val);
285         val = NULL;
286
287     /* get the value from sysrepo, we do not care if the value did not change in our case */
288     rc = sr_get_item(session, "/network-topology-simulator:simulator-config/ves-endpoint-details/ves-endpoint-ip", &val);
289     if (rc != SR_ERR_OK) {
290         goto sr_error;
291     }
292
293     rc = ves_ip_changed(val->data.string_val);
294     if (rc != SR_ERR_OK) {
295         goto sr_error;
296     }
297
298     sr_free_val(val);
299     val = NULL;
300
301     /* get the value from sysrepo, we do not care if the value did not change in our case */
302     rc = sr_get_item(session, "/network-topology-simulator:simulator-config/ves-endpoint-details/ves-endpoint-auth-method", &val);
303     if (rc != SR_ERR_OK) {
304         goto sr_error;
305     }
306
307     rc = ves_auth_method_changed(val->data.enum_val);
308     if (rc != SR_ERR_OK) {
309         goto sr_error;
310     }
311
312     sr_free_val(val);
313     val = NULL;
314
315     /* get the value from sysrepo, we do not care if the value did not change in our case */
316     rc = sr_get_item(session, "/network-topology-simulator:simulator-config/ves-endpoint-details/ves-endpoint-username", &val);
317     if (rc != SR_ERR_OK) {
318         goto sr_error;
319     }
320
321     rc = ves_username_changed(val->data.string_val);
322     if (rc != SR_ERR_OK) {
323         goto sr_error;
324     }
325
326     sr_free_val(val);
327     val = NULL;
328
329     /* get the value from sysrepo, we do not care if the value did not change in our case */
330     rc = sr_get_item(session, "/network-topology-simulator:simulator-config/ves-endpoint-details/ves-endpoint-password", &val);
331     if (rc != SR_ERR_OK) {
332         goto sr_error;
333     }
334
335     rc = ves_password_changed(val->data.string_val);
336     if (rc != SR_ERR_OK) {
337         goto sr_error;
338     }
339
340     sr_free_val(val);
341     val = NULL;
342
343         /* get the value from sysrepo, we do not care if the value did not change in our case */
344         rc = sr_get_item(session, "/network-topology-simulator:simulator-config/ves-endpoint-details/ves-endpoint-port", &val);
345         if (rc != SR_ERR_OK) {
346                 goto sr_error;
347         }
348
349         rc = ves_port_changed(val->data.uint16_val);
350         if (rc != SR_ERR_OK) {
351                 goto sr_error;
352         }
353
354         sr_free_val(val);
355         val = NULL;
356
357         /* get the value from sysrepo, we do not care if the value did not change in our case */
358         rc = sr_get_item(session, "/network-topology-simulator:simulator-config/ves-endpoint-details/ves-registration", &val);
359         if (rc != SR_ERR_OK) {
360                 goto sr_error;
361         }
362
363         rc = ves_registration_changed(val->data.bool_val);
364         if (rc != SR_ERR_OK) {
365                 goto sr_error;
366         }
367
368         sr_free_val(val);
369         val = NULL;
370
371         /* get the value from sysrepo, we do not care if the value did not change in our case */
372         rc = sr_get_item(session, "/network-topology-simulator:simulator-config/notification-config/is-netconf-available", &val);
373         if (rc != SR_ERR_OK) {
374                 goto sr_error;
375         }
376
377         rc = is_netconf_available_changed(val->data.bool_val);
378         if (rc != SR_ERR_OK) {
379                 goto sr_error;
380         }
381
382         sr_free_val(val);
383         val = NULL;
384
385     /* get the value from sysrepo, we do not care if the value did not change in our case */
386     rc = sr_get_item(session, "/network-topology-simulator:simulator-config/notification-config/is-ves-available", &val);
387     if (rc != SR_ERR_OK) {
388         goto sr_error;
389     }
390
391     rc = is_ves_available_changed(val->data.bool_val);
392     if (rc != SR_ERR_OK) {
393         goto sr_error;
394     }
395
396     sr_free_val(val);
397     val = NULL;
398
399     /* get the value from sysrepo, we do not care if the value did not change in our case */
400     rc = sr_get_item(session, "/network-topology-simulator:simulator-config/netconf-call-home", &val);
401     if (rc != SR_ERR_OK) {
402         goto sr_error;
403     }
404
405     rc = netconf_call_home_changed(val->data.bool_val);
406     if (rc != SR_ERR_OK) {
407         goto sr_error;
408     }
409
410     sr_free_val(val);
411     val = NULL;
412
413     /* get the value from sysrepo, we do not care if the value did not change in our case */
414     rc = sr_get_item(session, "/network-topology-simulator:simulator-config/controller-details/controller-ip", &val);
415     if (rc != SR_ERR_OK) {
416         goto sr_error;
417     }
418
419     rc = controller_ip_changed(val->data.string_val);
420     if (rc != SR_ERR_OK) {
421         goto sr_error;
422     }
423
424     sr_free_val(val);
425     val = NULL;
426
427     /* get the value from sysrepo, we do not care if the value did not change in our case */
428     rc = sr_get_item(session, "/network-topology-simulator:simulator-config/controller-details/controller-port", &val);
429     if (rc != SR_ERR_OK) {
430         goto sr_error;
431     }
432
433     rc = controller_port_changed(val->data.uint16_val);
434     if (rc != SR_ERR_OK) {
435         goto sr_error;
436     }
437
438     sr_free_val(val);
439     val = NULL;
440
441     /* get the value from sysrepo, we do not care if the value did not change in our case */
442     rc = sr_get_item(session, "/network-topology-simulator:simulator-config/controller-details/netconf-call-home-port", &val);
443     if (rc != SR_ERR_OK) {
444         goto sr_error;
445     }
446
447     rc = controller_netconf_call_home_port_changed(val->data.uint16_val);
448     if (rc != SR_ERR_OK) {
449         goto sr_error;
450     }
451
452     sr_free_val(val);
453     val = NULL;
454
455     /* get the value from sysrepo, we do not care if the value did not change in our case */
456     rc = sr_get_item(session, "/network-topology-simulator:simulator-config/controller-details/controller-username", &val);
457     if (rc != SR_ERR_OK) {
458         goto sr_error;
459     }
460
461     rc = controller_username_changed(val->data.string_val);
462     if (rc != SR_ERR_OK) {
463         goto sr_error;
464     }
465
466     sr_free_val(val);
467     val = NULL;
468
469     /* get the value from sysrepo, we do not care if the value did not change in our case */
470     rc = sr_get_item(session, "/network-topology-simulator:simulator-config/controller-details/controller-password", &val);
471     if (rc != SR_ERR_OK) {
472         goto sr_error;
473     }
474
475     rc = controller_password_changed(val->data.string_val);
476     if (rc != SR_ERR_OK) {
477         goto sr_error;
478     }
479
480     sr_free_val(val);
481     val = NULL;
482
483     return SR_ERR_OK;
484
485 sr_error:
486         printf("NTSimulator config change callback failed: %s.", sr_strerror(rc));
487         if (val != NULL)
488         {
489                 sr_free_val(val);
490                 val = NULL;
491         }
492         return rc;
493 }
494
495 static int
496 simulator_status_cb(const char *xpath, sr_val_t **values, size_t *values_cnt,
497         uint64_t request_id, const char *original_xpath, void *private_ctx)
498 {
499         int rc;
500
501         // printf("\n\n ========== Called simulator_status_cb for xpath: %s ==========\n\n", xpath);
502
503     counterAlarms ves_counter, netconf_counter;
504     rc = compute_notifications_count(&ves_counter, &netconf_counter);
505     if (rc != SR_ERR_OK)
506     {
507         printf("Could not compute the total number of notification count.\n");
508     }
509
510         if (sr_xpath_node_name_eq(xpath, "simulated-devices-list")) 
511     {
512                 sr_val_t *v;
513                 size_t current_num_of_values= 0;
514
515                 if (simulated_devices_config == 0) //nothing to return if no devices are running
516                 {
517                         *values = NULL;
518                         *values_cnt = 0;
519
520                         return SR_ERR_OK;
521                 }
522
523         rc = get_docker_containers_operational_state_curl(device_list);
524         if (rc != SR_ERR_OK)
525         {
526             printf("Could not get the operational state for the devices simulated.\n");
527             return SR_ERR_OPERATION_FAILED;
528         }
529
530                 device_t *current_device = device_list->head;
531
532                 while (current_device != NULL)
533                 {
534             counterAlarms vesCount, netconfCount;
535             rc = getDeviceCounters(current_device->device_id, &vesCount, &netconfCount);
536             if (rc != SR_ERR_OK)
537             {
538                 printf("Could not get Notification Counters for device with uuid=\"%s\"", current_device->device_id);
539             }
540
541             char device_name[200];
542             sprintf(device_name, "%s-%d", getenv("CONTAINER_NAME"), current_device->device_number);            
543
544                         CREATE_NEW_VALUE(rc, v, current_num_of_values);
545
546                         sr_val_build_xpath(&v[current_num_of_values - 1], "%s[uuid='%s']/%s", xpath, device_name, "device-ip");
547                         v[current_num_of_values - 1].type = SR_STRING_T;
548                         v[current_num_of_values - 1].data.string_val = getenv("NTS_IP");
549
550                         for (int i = 0; i < NETCONF_CONNECTIONS_PER_DEVICE; ++i)
551                         {
552                                 CREATE_NEW_VALUE(rc, v, current_num_of_values);
553
554                                 sr_val_build_xpath(&v[current_num_of_values - 1], "%s[uuid='%s']/%s", xpath, device_name, "device-port");
555                                 v[current_num_of_values - 1].type = SR_UINT32_T;
556                                 v[current_num_of_values - 1].data.uint32_val = current_device->netconf_port + i;
557                         }
558
559                         CREATE_NEW_VALUE(rc, v, current_num_of_values);
560
561                         sr_val_build_xpath(&v[current_num_of_values - 1], "%s[uuid='%s']/%s", xpath, device_name, "is-mounted");
562                         v[current_num_of_values - 1].type = SR_BOOL_T;
563                         v[current_num_of_values - 1].data.bool_val = current_device->is_mounted;
564
565                         char *operational_state = get_docker_container_operational_state(device_list, current_device->device_id);
566
567                         CREATE_NEW_VALUE(rc, v, current_num_of_values);
568
569                         sr_val_build_xpath(&v[current_num_of_values - 1], "%s[uuid='%s']/%s", xpath, device_name, "operational-state");
570                         sr_val_build_str_data(&v[current_num_of_values - 1], SR_ENUM_T, "%s", operational_state);
571
572             CREATE_NEW_VALUE(rc, v, current_num_of_values);
573
574             sr_val_build_xpath(&v[current_num_of_values - 1], "%s[uuid='%s']/notification-count/ves-notifications/%s", xpath, device_name, "normal");
575             v[current_num_of_values - 1].type = SR_UINT32_T;
576             v[current_num_of_values - 1].data.uint32_val = vesCount.normal;
577
578             CREATE_NEW_VALUE(rc, v, current_num_of_values);
579
580             sr_val_build_xpath(&v[current_num_of_values - 1], "%s[uuid='%s']/notification-count/ves-notifications/%s", xpath, device_name, "warning");
581             v[current_num_of_values - 1].type = SR_UINT32_T;
582             v[current_num_of_values - 1].data.uint32_val = vesCount.warning;
583
584             CREATE_NEW_VALUE(rc, v, current_num_of_values);
585
586             sr_val_build_xpath(&v[current_num_of_values - 1], "%s[uuid='%s']/notification-count/ves-notifications/%s", xpath, device_name, "minor");
587             v[current_num_of_values - 1].type = SR_UINT32_T;
588             v[current_num_of_values - 1].data.uint32_val = vesCount.minor;
589
590             CREATE_NEW_VALUE(rc, v, current_num_of_values);
591
592             sr_val_build_xpath(&v[current_num_of_values - 1], "%s[uuid='%s']/notification-count/ves-notifications/%s", xpath, device_name, "major");
593             v[current_num_of_values - 1].type = SR_UINT32_T;
594             v[current_num_of_values - 1].data.uint32_val = vesCount.major;
595
596             CREATE_NEW_VALUE(rc, v, current_num_of_values);
597
598             sr_val_build_xpath(&v[current_num_of_values - 1], "%s[uuid='%s']/notification-count/ves-notifications/%s", xpath, device_name, "critical");
599             v[current_num_of_values - 1].type = SR_UINT32_T;
600             v[current_num_of_values - 1].data.uint32_val = vesCount.critical;
601
602             CREATE_NEW_VALUE(rc, v, current_num_of_values);
603
604             sr_val_build_xpath(&v[current_num_of_values - 1], "%s[uuid='%s']/notification-count/netconf-notifications/%s", xpath, device_name, "normal");
605             v[current_num_of_values - 1].type = SR_UINT32_T;
606             v[current_num_of_values - 1].data.uint32_val = netconfCount.normal;
607
608             CREATE_NEW_VALUE(rc, v, current_num_of_values);
609
610             sr_val_build_xpath(&v[current_num_of_values - 1], "%s[uuid='%s']/notification-count/netconf-notifications/%s", xpath, device_name, "warning");
611             v[current_num_of_values - 1].type = SR_UINT32_T;
612             v[current_num_of_values - 1].data.uint32_val = netconfCount.warning;
613
614             CREATE_NEW_VALUE(rc, v, current_num_of_values);
615
616             sr_val_build_xpath(&v[current_num_of_values - 1], "%s[uuid='%s']/notification-count/netconf-notifications/%s", xpath, device_name, "minor");
617             v[current_num_of_values - 1].type = SR_UINT32_T;
618             v[current_num_of_values - 1].data.uint32_val = netconfCount.minor;
619
620             CREATE_NEW_VALUE(rc, v, current_num_of_values);
621
622             sr_val_build_xpath(&v[current_num_of_values - 1], "%s[uuid='%s']/notification-count/netconf-notifications/%s", xpath, device_name, "major");
623             v[current_num_of_values - 1].type = SR_UINT32_T;
624             v[current_num_of_values - 1].data.uint32_val = netconfCount.major;
625
626             CREATE_NEW_VALUE(rc, v, current_num_of_values);
627
628             sr_val_build_xpath(&v[current_num_of_values - 1], "%s[uuid='%s']/notification-count/netconf-notifications/%s", xpath, device_name, "critical");
629             v[current_num_of_values - 1].type = SR_UINT32_T;
630             v[current_num_of_values - 1].data.uint32_val = netconfCount.critical;
631
632                         current_device = current_device->next;
633                 }
634
635                 //return the values that we have just created
636                 *values = v;
637                 *values_cnt = current_num_of_values;
638          }
639          else if (sr_xpath_node_name_eq(xpath, "simulation-usage-details"))
640          {
641                 float cpu_usage = 0.0, mem_usage = 0.0;
642
643                 char *resource_usage_from_script = get_docker_container_resource_stats();
644
645                 if (resource_usage_from_script != NULL)
646                 {
647                         printf("Received line: %s\n", resource_usage_from_script);
648                         sscanf(resource_usage_from_script, "CPU=%f%%;RAM=%fMiB", &cpu_usage, &mem_usage);
649                         printf("Read cpu=\"%f\" and mem=\"%f\"\n", cpu_usage, mem_usage);
650                         free(resource_usage_from_script);
651                 }
652
653                 sr_val_t *v;
654                 /* convenient functions such as this can be found in sysrepo/values.h */
655                 size_t current_num_of_values= 0;
656
657                 CREATE_NEW_VALUE(rc, v, current_num_of_values);
658
659                 sr_val_build_xpath(&v[current_num_of_values - 1], "%s/%s", xpath, "running-simulated-devices");
660                 v[current_num_of_values - 1].type = SR_UINT32_T;
661                 v[current_num_of_values - 1].data.uint32_val = get_current_number_of_devices(device_list);
662
663                 CREATE_NEW_VALUE(rc, v, current_num_of_values);
664
665                 sr_val_build_xpath(&v[current_num_of_values - 1], "%s/%s", xpath, "running-mounted-devices");
666                 v[current_num_of_values - 1].type = SR_UINT32_T;
667                 v[current_num_of_values - 1].data.uint32_val = get_current_number_of_mounted_devices(device_list);
668
669                 CREATE_NEW_VALUE(rc, v, current_num_of_values);
670
671                 sr_val_build_xpath(&v[current_num_of_values - 1], "%s/%s", xpath, "base-netconf-port");
672                 v[current_num_of_values - 1].type = SR_UINT32_T;
673                 v[current_num_of_values - 1].data.uint32_val = get_netconf_port_base();
674
675                 CREATE_NEW_VALUE(rc, v, current_num_of_values);
676
677                 sr_val_build_xpath(&v[current_num_of_values - 1], "%s/%s", xpath, "cpu-usage");
678                 v[current_num_of_values - 1].type = SR_DECIMAL64_T;
679                 v[current_num_of_values - 1].data.decimal64_val = cpu_usage;
680
681                 CREATE_NEW_VALUE(rc, v, current_num_of_values);
682
683                 sr_val_build_xpath(&v[current_num_of_values - 1], "%s/%s", xpath, "mem-usage");
684                 v[current_num_of_values - 1].type = SR_UINT32_T;
685                 v[current_num_of_values - 1].data.uint32_val = (int)mem_usage;
686
687         CREATE_NEW_VALUE(rc, v, current_num_of_values);
688
689         sr_val_build_xpath(&v[current_num_of_values - 1], "%s/%s", xpath, "ssh-connections");
690         v[current_num_of_values - 1].type = SR_UINT32_T;
691         v[current_num_of_values - 1].data.uint32_val = getSshConnectionsFromConfigJson();
692
693         CREATE_NEW_VALUE(rc, v, current_num_of_values);
694
695         sr_val_build_xpath(&v[current_num_of_values - 1], "%s/%s", xpath, "tls-connections");
696         v[current_num_of_values - 1].type = SR_UINT32_T;
697         v[current_num_of_values - 1].data.uint32_val = getTlsConnectionsFromConfigJson();
698
699                 //return the values that we have just created
700                 *values = v;
701                 *values_cnt = current_num_of_values;
702          }
703      else if (sr_xpath_node_name_eq(xpath, "total-ves-notifications"))
704      {
705         sr_val_t *v;
706         /* convenient functions such as this can be found in sysrepo/values.h */
707         size_t current_num_of_values= 0;
708
709         CREATE_NEW_VALUE(rc, v, current_num_of_values);
710
711         sr_val_build_xpath(&v[current_num_of_values - 1], "%s/%s", xpath, "normal");
712         v[current_num_of_values - 1].type = SR_UINT32_T;
713         v[current_num_of_values - 1].data.uint32_val = ves_counter.normal;
714
715         CREATE_NEW_VALUE(rc, v, current_num_of_values);
716
717         sr_val_build_xpath(&v[current_num_of_values - 1], "%s/%s", xpath, "warning");
718         v[current_num_of_values - 1].type = SR_UINT32_T;
719         v[current_num_of_values - 1].data.uint32_val = ves_counter.warning;
720
721         CREATE_NEW_VALUE(rc, v, current_num_of_values);
722
723         sr_val_build_xpath(&v[current_num_of_values - 1], "%s/%s", xpath, "minor");
724         v[current_num_of_values - 1].type = SR_UINT32_T;
725         v[current_num_of_values - 1].data.uint32_val = ves_counter.minor;
726
727         CREATE_NEW_VALUE(rc, v, current_num_of_values);
728
729         sr_val_build_xpath(&v[current_num_of_values - 1], "%s/%s", xpath, "major");
730         v[current_num_of_values - 1].type = SR_UINT32_T;
731         v[current_num_of_values - 1].data.uint32_val = ves_counter.major;
732
733         CREATE_NEW_VALUE(rc, v, current_num_of_values);
734
735         sr_val_build_xpath(&v[current_num_of_values - 1], "%s/%s", xpath, "critical");
736         v[current_num_of_values - 1].type = SR_UINT32_T;
737         v[current_num_of_values - 1].data.uint32_val = ves_counter.critical;
738
739         //return the values that we have just created
740         *values = v;
741         *values_cnt = current_num_of_values;
742      }
743      else if (sr_xpath_node_name_eq(xpath, "total-netconf-notifications"))
744      {
745         sr_val_t *v;
746         /* convenient functions such as this can be found in sysrepo/values.h */
747         size_t current_num_of_values= 0;
748
749         CREATE_NEW_VALUE(rc, v, current_num_of_values);
750
751         sr_val_build_xpath(&v[current_num_of_values - 1], "%s/%s", xpath, "normal");
752         v[current_num_of_values - 1].type = SR_UINT32_T;
753         v[current_num_of_values - 1].data.uint32_val = netconf_counter.normal;
754
755         CREATE_NEW_VALUE(rc, v, current_num_of_values);
756
757         sr_val_build_xpath(&v[current_num_of_values - 1], "%s/%s", xpath, "warning");
758         v[current_num_of_values - 1].type = SR_UINT32_T;
759         v[current_num_of_values - 1].data.uint32_val = netconf_counter.warning;
760
761         CREATE_NEW_VALUE(rc, v, current_num_of_values);
762
763         sr_val_build_xpath(&v[current_num_of_values - 1], "%s/%s", xpath, "minor");
764         v[current_num_of_values - 1].type = SR_UINT32_T;
765         v[current_num_of_values - 1].data.uint32_val = netconf_counter.minor;
766
767         CREATE_NEW_VALUE(rc, v, current_num_of_values);
768
769         sr_val_build_xpath(&v[current_num_of_values - 1], "%s/%s", xpath, "major");
770         v[current_num_of_values - 1].type = SR_UINT32_T;
771         v[current_num_of_values - 1].data.uint32_val = netconf_counter.major;
772
773         CREATE_NEW_VALUE(rc, v, current_num_of_values);
774
775         sr_val_build_xpath(&v[current_num_of_values - 1], "%s/%s", xpath, "critical");
776         v[current_num_of_values - 1].type = SR_UINT32_T;
777         v[current_num_of_values - 1].data.uint32_val = netconf_counter.critical;
778
779         //return the values that we have just created
780         *values = v;
781         *values_cnt = current_num_of_values;
782      }
783
784     return SR_ERR_OK;
785 }
786
787 static int odl_add_key_pair_cb(const char *xpath, const sr_val_t *input, const size_t input_cnt,
788       sr_val_t **output, size_t *output_cnt, void *private_ctx)
789 {
790     int rc = SR_ERR_OK;
791     controller_t controller_list[CONTROLLER_LIST_MAX_LEN];
792     int controller_list_size = 0;
793
794     controller_list[0] = controller_details;
795     controller_list_size++;
796
797     for (int i = 0; i < controller_list_size; ++i)
798     {
799         printf("%d iteration: Got back url=%s and credentials=%s\n", i, controller_list[i].url, controller_list[i].credentials);
800     }
801
802     rc = add_key_pair_to_odl(controller_list, controller_list_size);
803     if (rc != SR_ERR_OK)
804     {
805         printf("Failed to add key pair to ODL.\n");
806         return SR_ERR_OPERATION_FAILED;
807     }
808
809     return rc;
810 }
811
812 static int invoke_notification_cb(const char *xpath, const sr_val_t *input, const size_t input_cnt,
813       sr_val_t **output, size_t *output_cnt, void *private_ctx)
814 {
815     int rc = SR_ERR_OK;
816
817     char *device_name = NULL, *module_name = NULL, *notification_object = NULL;
818     
819     /* print input values */
820     printf("\n\n ========== RECEIVED RPC REQUEST ==========\n\n");
821     printf(">>> RPC Input:\n\n");
822     
823     device_name = strdup(input[0].data.string_val);
824     module_name = strdup(input[1].data.string_val);
825     notification_object = strdup(input[2].data.string_val);
826
827     rc = sr_new_values(1, output);
828     if (SR_ERR_OK != rc) {
829         return rc;
830     }
831
832     /* set 'output/step-count' leaf */
833     rc = sr_val_set_xpath(&(*output)[0], "/network-topology-simulator:invoke-notification/status");
834     if (SR_ERR_OK != rc) {
835         return rc;
836     }
837
838     rc = invoke_device_notification(device_name, module_name, notification_object);
839     
840     if (rc != SR_ERR_OK)
841     {
842         sr_val_build_str_data(&(*output)[0], SR_ENUM_T, "%s", "ERROR");
843     }
844     else
845     {
846         sr_val_build_str_data(&(*output)[0], SR_ENUM_T, "%s", "SUCCESS");
847     }
848     *output_cnt = 1;
849
850     return SR_ERR_OK;
851 }
852
853
854 static void
855 sigint_handler(int signum)
856 {
857     exit_application = 1;
858 }
859
860 int
861 main(int argc, char **argv)
862 {
863     sr_conn_ctx_t *connection = NULL;
864     sr_session_ctx_t *session = NULL;
865     sr_subscription_ctx_t *subscription = NULL;
866     int rc = SR_ERR_OK;
867
868     setbuf(stdout, NULL);
869
870     rc = _init_curl_k8s();
871     if (rc != SR_ERR_OK)
872     {
873         fprintf(stderr, "Could not initialize cURL for K8S connection: %s\n", sr_strerror(rc));
874     }
875
876     device_list = new_device_stack();
877     rc = _init_curl();
878     if (rc != SR_ERR_OK)
879     {
880         fprintf(stderr, "Could not initialize cURL: %s\n", sr_strerror(rc));
881     }
882
883     rc = writeSkeletonConfigFile();
884     if (rc != SR_ERR_OK)
885     {
886         fprintf(stderr, "Could not initialize configuration JSON file: %s\n", sr_strerror(rc));
887     }
888
889     /* connect to sysrepo */
890     rc = sr_connect("network-topology-simulator", SR_CONN_DEFAULT, &connection);
891     if (SR_ERR_OK != rc) {
892         fprintf(stderr, "Error by sr_connect: %s\n", sr_strerror(rc));
893         goto cleanup;
894     }
895
896     /* start session */
897     rc = sr_session_start(connection, SR_DS_STARTUP, SR_SESS_DEFAULT, &session);
898     if (SR_ERR_OK != rc) {
899         fprintf(stderr, "Error by sr_session_start: %s\n", sr_strerror(rc));
900         goto cleanup;
901     }
902
903     // setting the values that come in an ENV variable as defaults - ves-heartbeat-period
904     int vesHeartbeatPeriod = getIntFromString(getenv("VesHeartbeatPeriod"), 0);
905
906     sr_val_t value = { 0 };
907     value.type = SR_UINT32_T;
908     value.data.uint32_val = vesHeartbeatPeriod;
909     rc = sr_set_item(session, "/network-topology-simulator:simulator-config/notification-config/ves-heartbeat-period", 
910             &value, SR_EDIT_DEFAULT);
911     if (SR_ERR_OK != rc) {
912         printf("Error by sr_set_item: %s\n", sr_strerror(rc));
913         goto cleanup;
914     }
915
916     rc = ves_heartbeat_period_changed(vesHeartbeatPeriod);
917     if (SR_ERR_OK != rc) {
918         printf("Error by ves_heartbeat_period_changed: %s\n", sr_strerror(rc));
919         goto cleanup;
920     }
921
922     // setting the values that come in an ENV variable as defaults - is-netconf-available
923
924     int isNetconfAvailable = 1;
925
926     char *isNetconfAvailablString = getenv("IsNetconfAvailable");
927     if (isNetconfAvailablString != NULL)
928     {
929         if (strcmp(isNetconfAvailablString, "false") == 0)
930         {
931             isNetconfAvailable = 0;
932         }
933     }
934
935     value = (const sr_val_t) { 0 };
936     value.type = SR_BOOL_T;
937     value.data.bool_val = isNetconfAvailable;
938     rc = sr_set_item(session, "/network-topology-simulator:simulator-config/notification-config/is-netconf-available", 
939             &value, SR_EDIT_DEFAULT);
940     if (SR_ERR_OK != rc) {
941         printf("Error by sr_set_item: %s\n", sr_strerror(rc));
942         goto cleanup;
943     }
944
945     rc = is_netconf_available_changed(isNetconfAvailable);
946     if (SR_ERR_OK != rc) {
947         printf("Error by is_netconf_available_changed: %s\n", sr_strerror(rc));
948         goto cleanup;
949     }
950
951     // setting the values that come in an ENV variable as defaults - is-ves-available
952
953     int isVesAvailable = 1;
954
955     char *isVesAvailablString = getenv("IsVesAvailable");
956     if (isVesAvailablString != NULL)
957     {
958         if (strcmp(isVesAvailablString, "false") == 0)
959         {
960             isVesAvailable = 0;
961         }
962     }
963
964     value = (const sr_val_t) { 0 };
965     value.type = SR_BOOL_T;
966     value.data.bool_val = isVesAvailable;
967     rc = sr_set_item(session, "/network-topology-simulator:simulator-config/notification-config/is-ves-available", 
968             &value, SR_EDIT_DEFAULT);
969     if (SR_ERR_OK != rc) {
970         printf("Error by sr_set_item: %s\n", sr_strerror(rc));
971         goto cleanup;
972     }
973
974     rc = is_ves_available_changed(isVesAvailable);
975     if (SR_ERR_OK != rc) {
976         printf("Error by is_ves_available_changed: %s\n", sr_strerror(rc));
977         goto cleanup;
978     }
979
980     // setting the values that come in an ENV variable as defaults - ves-endpoint-port
981
982     int vesEndpointPort = getIntFromString(getenv("VesEndpointPort"), 8080);
983
984     value = (const sr_val_t) { 0 };
985     value.type = SR_UINT16_T;
986     value.data.uint16_val = vesEndpointPort;
987     rc = sr_set_item(session, "/network-topology-simulator:simulator-config/ves-endpoint-details/ves-endpoint-port", 
988             &value, SR_EDIT_DEFAULT);
989     if (SR_ERR_OK != rc) {
990         printf("Error by sr_set_item: %s\n", sr_strerror(rc));
991         goto cleanup;
992     }
993
994     rc = ves_port_changed(vesEndpointPort);
995     if (SR_ERR_OK != rc) {
996         printf("Error by ves_port_changed: %s\n", sr_strerror(rc));
997         goto cleanup;
998     }
999
1000     // setting the values that come in an ENV variable as defaults - ves-endpoint-ip
1001
1002     value = (const sr_val_t) { 0 };
1003     value.type = SR_STRING_T;
1004     value.data.string_val = getenv("VesEndpointIp");
1005     rc = sr_set_item(session, "/network-topology-simulator:simulator-config/ves-endpoint-details/ves-endpoint-ip", 
1006             &value, SR_EDIT_DEFAULT);
1007     if (SR_ERR_OK != rc) {
1008         printf("Error by sr_set_item: %s\n", sr_strerror(rc));
1009         goto cleanup;
1010     }
1011
1012     rc = ves_ip_changed(getenv("VesEndpointIp"));
1013     if (SR_ERR_OK != rc) {
1014         printf("Error by ves_ip_changed: %s\n", sr_strerror(rc));
1015         goto cleanup;
1016     }
1017
1018     // setting the values that come in an ENV variable as defaults - ves-endpoint-auth-method
1019
1020     value = (const sr_val_t) { 0 };
1021     value.type = SR_ENUM_T;
1022     value.data.enum_val = getenv("VesEndpointAuthMethod");
1023     rc = sr_set_item(session, "/network-topology-simulator:simulator-config/ves-endpoint-details/ves-endpoint-auth-method", 
1024             &value, SR_EDIT_DEFAULT);
1025     if (SR_ERR_OK != rc) {
1026         printf("Error by sr_set_item: %s\n", sr_strerror(rc));
1027         goto cleanup;
1028     }
1029
1030     rc = ves_auth_method_changed(getenv("VesEndpointAuthMethod"));
1031     if (SR_ERR_OK != rc) {
1032         printf("Error by ves_auth_method_changed: %s\n", sr_strerror(rc));
1033         goto cleanup;
1034     }
1035
1036     //TODO only basic-auth implemented vor VES
1037     if (strcmp(getenv("VesEndpointAuthMethod"), "basic-auth")  == 0)
1038     {
1039         // setting the values that come in an ENV variable as defaults - ves-endpoint-usename
1040
1041         value = (const sr_val_t) { 0 };
1042         value.type = SR_STRING_T;
1043         value.data.string_val = getenv("VesEndpointUsername");
1044         rc = sr_set_item(session, "/network-topology-simulator:simulator-config/ves-endpoint-details/ves-endpoint-username",
1045                 &value, SR_EDIT_DEFAULT);
1046         if (SR_ERR_OK != rc) {
1047             printf("Error by sr_set_item: %s\n", sr_strerror(rc));
1048             goto cleanup;
1049         }
1050
1051         rc = ves_username_changed(getenv("VesEndpointUsername"));
1052         if (SR_ERR_OK != rc) {
1053             printf("Error by ves_username_changed: %s\n", sr_strerror(rc));
1054             goto cleanup;
1055         }
1056
1057         // setting the values that come in an ENV variable as defaults - ves-endpoint-password
1058
1059         value = (const sr_val_t) { 0 };
1060         value.type = SR_STRING_T;
1061         value.data.string_val = getenv("VesEndpointPassword");
1062         rc = sr_set_item(session, "/network-topology-simulator:simulator-config/ves-endpoint-details/ves-endpoint-password",
1063                 &value, SR_EDIT_DEFAULT);
1064         if (SR_ERR_OK != rc) {
1065             printf("Error by sr_set_item: %s\n", sr_strerror(rc));
1066             goto cleanup;
1067         }
1068
1069         rc = ves_password_changed(getenv("VesEndpointPassword"));
1070         if (SR_ERR_OK != rc) {
1071             printf("Error by ves_password_changed: %s\n", sr_strerror(rc));
1072             goto cleanup;
1073         }
1074     }
1075
1076     // setting the values that come in an ENV variable as defaults - ves-registration
1077
1078     int vesRegistration = 1;
1079
1080     char *vesRegistrationString = getenv("VesRegistration");
1081     if (vesRegistrationString != NULL)
1082     {
1083         if (strcmp(vesRegistrationString, "false") == 0)
1084         {
1085             vesRegistration = 0;
1086         }
1087     }
1088
1089     value = (const sr_val_t) { 0 };
1090     value.type = SR_BOOL_T;
1091     value.data.bool_val = vesRegistration;
1092     rc = sr_set_item(session, "/network-topology-simulator:simulator-config/ves-endpoint-details/ves-registration",
1093             &value, SR_EDIT_DEFAULT);
1094     if (SR_ERR_OK != rc) {
1095         printf("Error by sr_set_item: %s\n", sr_strerror(rc));
1096         goto cleanup;
1097     }
1098
1099     rc = ves_registration_changed(vesRegistration);
1100     if (SR_ERR_OK != rc) {
1101         printf("Error by ves_registration_changed: %s\n", sr_strerror(rc));
1102         goto cleanup;
1103     }
1104
1105     // setting the values that come in an ENV variable as defaults - ssh-connections
1106
1107     int sshConnections = getIntFromString(getenv("SshConnections"), 1);
1108
1109     rc = ssh_connections_changed(sshConnections);
1110     if (SR_ERR_OK != rc) {
1111         printf("Error by ssh_connections_changed: %s\n", sr_strerror(rc));
1112         goto cleanup;
1113     }
1114
1115     // setting the values that come in an ENV variable as defaults - tls-connections
1116
1117     int tlsConnections = getIntFromString(getenv("TlsConnections"), 0);
1118
1119     rc = tls_connections_changed(tlsConnections);
1120     if (SR_ERR_OK != rc) {
1121         printf("Error by tls_connections_changed: %s\n", sr_strerror(rc));
1122         goto cleanup;
1123     }
1124
1125     if (strcmp(getenv("K8S_DEPLOYMENT"), "true") == 0)
1126     {
1127         rc = send_k8s_extend_port();
1128         if (rc != SR_ERR_OK)
1129         {
1130             printf("Could not send the number of ports to k8s cluster\n");
1131         }
1132     }
1133
1134     // setting the values that come in an ENV variable as defaults - controller-ip
1135
1136     value = (const sr_val_t) { 0 };
1137     value.type = SR_STRING_T;
1138     value.data.string_val = getenv("ControllerIp");
1139     rc = sr_set_item(session, "/network-topology-simulator:simulator-config/controller-details/controller-ip", 
1140             &value, SR_EDIT_DEFAULT);
1141     if (SR_ERR_OK != rc) {
1142         printf("Error by sr_set_item: %s\n", sr_strerror(rc));
1143         goto cleanup;
1144     }
1145
1146     rc = controller_ip_changed(getenv("ControllerIp"));
1147     if (SR_ERR_OK != rc) {
1148         printf("Error by controller_ip_changed: %s\n", sr_strerror(rc));
1149         goto cleanup;
1150     }
1151
1152     // setting the values that come in an ENV variable as defaults - controller-port
1153
1154     int controllerPort = getIntFromString(getenv("ControllerPort"), 8181);
1155
1156     value = (const sr_val_t) { 0 };
1157     value.type = SR_UINT16_T;
1158     value.data.uint16_val = controllerPort;
1159     rc = sr_set_item(session, "/network-topology-simulator:simulator-config/controller-details/controller-port", 
1160             &value, SR_EDIT_DEFAULT);
1161     if (SR_ERR_OK != rc) {
1162         printf("Error by sr_set_item: %s\n", sr_strerror(rc));
1163         goto cleanup;
1164     }
1165
1166     rc = controller_port_changed(controllerPort);
1167     if (SR_ERR_OK != rc) {
1168         printf("Error by controller_port_changed: %s\n", sr_strerror(rc));
1169         goto cleanup;
1170     }
1171
1172     // setting the values that come in an ENV variable as defaults - netconf-call-home-port
1173
1174     int netconfCallHomePort = getIntFromString(getenv("NetconfCallHomePort"), 6666);
1175
1176     value = (const sr_val_t) { 0 };
1177     value.type = SR_UINT16_T;
1178     value.data.uint16_val = netconfCallHomePort;
1179     rc = sr_set_item(session, "/network-topology-simulator:simulator-config/controller-details/netconf-call-home-port", 
1180             &value, SR_EDIT_DEFAULT);
1181     if (SR_ERR_OK != rc) {
1182         printf("Error by sr_set_item: %s\n", sr_strerror(rc));
1183         goto cleanup;
1184     }
1185
1186     rc = controller_netconf_call_home_port_changed(netconfCallHomePort);
1187     if (SR_ERR_OK != rc) {
1188         printf("Error by controller_netconf_call_home_port_changed: %s\n", sr_strerror(rc));
1189         goto cleanup;
1190     }
1191
1192     // setting the values that come in an ENV variable as defaults - controller-username
1193
1194     value = (const sr_val_t) { 0 };
1195     value.type = SR_STRING_T;
1196     value.data.string_val = getenv("ControllerUsername");
1197     rc = sr_set_item(session, "/network-topology-simulator:simulator-config/controller-details/controller-username", 
1198             &value, SR_EDIT_DEFAULT);
1199     if (SR_ERR_OK != rc) {
1200         printf("Error by sr_set_item: %s\n", sr_strerror(rc));
1201         goto cleanup;
1202     }
1203
1204     rc = controller_username_changed(getenv("ControllerUsername"));
1205     if (SR_ERR_OK != rc) {
1206         printf("Error by controller_username_changed: %s\n", sr_strerror(rc));
1207         goto cleanup;
1208     }
1209
1210     // setting the values that come in an ENV variable as defaults - controller-password
1211
1212     value = (const sr_val_t) { 0 };
1213     value.type = SR_STRING_T;
1214     value.data.string_val = getenv("ControllerPassword");
1215     rc = sr_set_item(session, "/network-topology-simulator:simulator-config/controller-details/controller-password", 
1216             &value, SR_EDIT_DEFAULT);
1217     if (SR_ERR_OK != rc) {
1218         printf("Error by sr_set_item: %s\n", sr_strerror(rc));
1219         goto cleanup;
1220     }
1221
1222     rc = controller_password_changed(getenv("ControllerPassword"));
1223     if (SR_ERR_OK != rc) {
1224         printf("Error by controller_password_changed: %s\n", sr_strerror(rc));
1225         goto cleanup;
1226     }
1227
1228     // setting the values that come in an ENV variable as defaults - netconf-call-home
1229
1230     int netconfCallHome = 1;
1231
1232     char *netconfCallHomeString = getenv("NetconfCallHome");
1233     if (netconfCallHomeString != NULL)
1234     {
1235         if (strcmp(netconfCallHomeString, "false") == 0)
1236         {
1237             netconfCallHome = 0;
1238         }
1239     }
1240
1241     value = (const sr_val_t) { 0 };
1242     value.type = SR_BOOL_T;
1243     value.data.bool_val = netconfCallHome;
1244     rc = sr_set_item(session, "/network-topology-simulator:simulator-config/netconf-call-home", 
1245             &value, SR_EDIT_DEFAULT);
1246     if (SR_ERR_OK != rc) {
1247         printf("Error by sr_set_item: %s\n", sr_strerror(rc));
1248         goto cleanup;
1249     }
1250
1251     rc = netconf_call_home_changed(netconfCallHome);
1252     if (SR_ERR_OK != rc) {
1253         printf("Error by netconf_call_home_changed: %s\n", sr_strerror(rc));
1254         goto cleanup;
1255     }
1256
1257     //commit the changes that we have done until now
1258     rc = sr_commit(session);
1259     if (SR_ERR_OK != rc) {
1260         printf("Error by sr_commit: %s\n", sr_strerror(rc));
1261         goto cleanup;
1262     }
1263
1264         /* read startup config */
1265         printf("\n\n ========== READING STARTUP CONFIG network-topology-simulator: ==========\n\n");
1266         print_current_config(session, "network-topology-simulator");
1267
1268         /* subscribe for changes in running config */
1269         rc = sr_module_change_subscribe(session, "network-topology-simulator", simulator_config_change_cb, NULL,
1270                         0, SR_SUBSCR_DEFAULT | SR_SUBSCR_APPLY_ONLY, &subscription);
1271         if (SR_ERR_OK != rc) {
1272                 fprintf(stderr, "Error by sr_module_change_subscribe: %s\n", sr_strerror(rc));
1273                 goto cleanup;
1274         }
1275
1276     /* subscribe as state data provider for the ntsimulator state data */
1277     rc = sr_dp_get_items_subscribe(session, "/network-topology-simulator:simulator-status", simulator_status_cb, NULL,
1278                 SR_SUBSCR_CTX_REUSE, &subscription);
1279     if (rc != SR_ERR_OK) {
1280         goto cleanup;
1281     }
1282
1283     rc = notification_delay_period_changed(NULL, 0);
1284     if (rc != SR_ERR_OK) {
1285         printf("Could not write the delay period to file!\n");
1286         goto cleanup;
1287     }
1288
1289     rc = _init_curl_odl();
1290     if (rc != SR_ERR_OK)
1291     {
1292         fprintf(stderr, "Could not initialize cURL for ODL connection: %s\n", sr_strerror(rc));
1293     }
1294
1295     rc = sr_rpc_subscribe(session, "/network-topology-simulator:add-key-pair-to-odl", odl_add_key_pair_cb, (void *)session,
1296                 SR_SUBSCR_CTX_REUSE, &subscription);
1297
1298         printf("\n\n ========== STARTUP CONFIG network-topology-simulator APPLIED AS RUNNING ==========\n\n");
1299
1300     rc = writeSkeletonStatusFile();
1301     if (rc != SR_ERR_OK)
1302     {
1303         fprintf(stderr, "Could not initialize status JSON file: %s\n", sr_strerror(rc));
1304     }
1305
1306     rc = sr_rpc_subscribe(session, "/network-topology-simulator:invoke-notification", invoke_notification_cb,
1307             (void *)session, SR_SUBSCR_DEFAULT, &subscription);
1308     if (SR_ERR_OK != rc) {
1309         fprintf(stderr, "Error by sr_rpc_subscribe: %s\n", sr_strerror(rc));
1310         goto cleanup;
1311     }
1312
1313     rc = pull_docker_image_of_simulated_device();
1314
1315     /* loop until ctrl-c is pressed / SIGINT is received */
1316     signal(SIGINT, sigint_handler);
1317     signal(SIGTERM, sigint_handler);
1318     signal(SIGPIPE, SIG_IGN);
1319
1320     while (!exit_application) {
1321
1322                 sleep(1);  /* or do some more useful work... */
1323     }
1324
1325     printf("Application exit requested, exiting.\n");
1326
1327 cleanup:
1328     if (NULL != subscription) {
1329         sr_unsubscribe(session, subscription);
1330     }
1331     if (NULL != session) {
1332         sr_session_stop(session);
1333     }
1334     if (NULL != connection) {
1335         sr_disconnect(connection);
1336     }
1337
1338     clean_current_docker_configuration();
1339     rc = cleanup_curl();
1340     rc = cleanup_curl_odl();
1341     rc = cleanup_curl_k8s();
1342
1343     return rc;
1344 }
1345
1346 static void clean_current_docker_configuration(void)
1347 {
1348     if (strcmp(getenv("K8S_DEPLOYMENT"), "true"))
1349     {
1350         return;
1351     }
1352
1353         printf("Cleaning docker containers...\n");
1354
1355         if (device_list == NULL)
1356         {
1357                 return;
1358         }
1359
1360         for (int i = 0; i < simulated_devices_config; ++i)
1361         {
1362                 stop_device(device_list);
1363         }
1364
1365         printf("Cleaning completed!\n");
1366 }