2 * simulator-operations.c
4 * Created on: Mar 9, 2019
8 #include "simulator-operations.h"
10 #include "sysrepo/values.h"
13 #include <linux/limits.h>
17 #define LINE_BUFSIZE 128
19 static CURL *curl; //share the same curl connection for communicating with the Docker Engine API
20 static CURL *curl_odl; //share the same curl connection for mounting servers in ODL
22 static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
24 size_t realsize = size * nmemb;
25 struct MemoryStruct *mem = (struct MemoryStruct *)userp;
27 char *ptr = realloc(mem->memory, mem->size + realsize + 1);
30 printf("not enough memory (realloc returned NULL)\n");
35 memcpy(&(mem->memory[mem->size]), contents, realsize);
36 mem->size += realsize;
37 mem->memory[mem->size] = 0;
42 static void set_curl_common_info()
44 struct curl_slist *chunk = NULL;
45 chunk = curl_slist_append(chunk, "Content-Type: application/json");
46 chunk = curl_slist_append(chunk, "Accept: application/json");
48 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
50 curl_easy_setopt(curl, CURLOPT_UNIX_SOCKET_PATH, "/var/run/docker.sock");
52 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
53 curl_easy_setopt(curl_odl, CURLOPT_CONNECTTIMEOUT, 2L); // seconds timeout for a connection
54 curl_easy_setopt(curl_odl, CURLOPT_TIMEOUT, 5L); //seconds timeout for an operation
56 curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
59 static void set_curl_common_info_odl()
61 struct curl_slist *chunk = NULL;
62 chunk = curl_slist_append(chunk, "Content-Type: application/xml");
63 chunk = curl_slist_append(chunk, "Accept: application/xml");
65 curl_easy_setopt(curl_odl, CURLOPT_HTTPHEADER, chunk);
67 curl_easy_setopt(curl_odl, CURLOPT_CONNECTTIMEOUT, 2L); // seconds timeout for a connection
68 curl_easy_setopt(curl_odl, CURLOPT_TIMEOUT, 5L); //seconds timeout for an operation
70 curl_easy_setopt(curl_odl, CURLOPT_VERBOSE, 1L);
73 static cJSON* get_docker_container_bindings(void)
75 struct MemoryStruct curl_response_mem;
77 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
78 curl_response_mem.size = 0; /* no data at this point */
82 curl_easy_reset(curl);
83 set_curl_common_info();
86 sprintf(url, "http:/v%s/containers/NTS_Manager/json", getenv("DOCKER_ENGINE_VERSION"));
88 curl_easy_setopt(curl, CURLOPT_URL, url);
90 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
91 curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
93 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
95 res = curl_easy_perform(curl);
103 cJSON *json_response = cJSON_Parse(curl_response_mem.memory);
105 printf("%lu bytes retrieved\n", (unsigned long)curl_response_mem.size);
107 if (json_response == NULL)
109 printf("Could not parse JSON response for url=\"%s\"\n", url);
113 cJSON *hostConfig = cJSON_GetObjectItemCaseSensitive(json_response, "HostConfig");
115 if (hostConfig == NULL)
117 printf("Could not get HostConfig object\n");
121 cJSON *binds = cJSON_GetObjectItemCaseSensitive(hostConfig, "Binds");
125 printf("Could not get Binds object\n");
129 cJSON *bindsCopy = cJSON_Duplicate(binds, 1);
131 cJSON_Delete(json_response);
139 static char* create_docker_container_curl(int base_netconf_port, cJSON* managerBinds)
141 if (managerBinds == NULL)
143 printf("Could not retrieve JSON object: Binds\n");
146 cJSON *binds = cJSON_Duplicate(managerBinds, 1);
148 struct MemoryStruct curl_response_mem;
150 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
151 curl_response_mem.size = 0; /* no data at this point */
155 curl_easy_reset(curl);
156 set_curl_common_info();
159 sprintf(url, "http:/v%s/containers/create", getenv("DOCKER_ENGINE_VERSION"));
161 // the docker image name to be used is defined in the Dockerfile of the NTS Manager,
162 // under the MODELS_IMAGE env variable
164 sprintf(models_var, "%s", getenv("MODELS_IMAGE"));
166 curl_easy_setopt(curl, CURLOPT_URL, url);
168 cJSON *postDataJson = cJSON_CreateObject();
170 if (cJSON_AddStringToObject(postDataJson, "Image", models_var) == NULL)
172 printf("Could not create JSON object: Image\n");
176 cJSON *hostConfig = cJSON_CreateObject();
177 if (hostConfig == NULL)
179 printf("Could not create JSON object: HostConfig\n");
183 cJSON_AddItemToObject(postDataJson, "HostConfig", hostConfig);
185 cJSON *portBindings = cJSON_CreateObject();
186 if (portBindings == NULL)
188 printf("Could not create JSON object: PortBindings\n");
192 cJSON_AddItemToObject(hostConfig, "PortBindings", portBindings);
194 for (int i = 0; i < NETCONF_CONNECTIONS_PER_DEVICE; ++i)
196 cJSON *port = cJSON_CreateArray();
199 printf("Could not create JSON object: port\n");
203 char dockerContainerPort[20];
204 sprintf(dockerContainerPort, "%d/tcp", 830 + i);
206 cJSON_AddItemToObject(portBindings, dockerContainerPort, port);
208 cJSON *hostPort = cJSON_CreateObject();
209 if (hostPort == NULL)
211 printf("Could not create JSON object: HostPort\n");
215 char dockerHostPort[10];
216 sprintf(dockerHostPort, "%d", base_netconf_port + i);
217 if (cJSON_AddStringToObject(hostPort, "HostPort", dockerHostPort) == NULL)
219 printf("Could not create JSON object: HostPortString\n");
222 if (cJSON_AddStringToObject(hostPort, "HostIp", getenv("NTS_IP")) == NULL)
224 printf("Could not create JSON object: HostIpString\n");
228 cJSON_AddItemToArray(port, hostPort);
231 cJSON *labels = cJSON_CreateObject();
234 printf("Could not create JSON object: Labels\n");
238 cJSON_AddItemToObject(postDataJson, "Labels", labels);
240 if (cJSON_AddStringToObject(labels, "NTS", "") == NULL)
242 printf("Could not create JSON object: NTS\n");
246 cJSON *env_variables_array = cJSON_CreateArray();
247 if (env_variables_array == NULL)
249 printf("Could not create JSON object: Env array\n");
253 cJSON_AddItemToObject(postDataJson, "Env", env_variables_array);
255 char environment_var[50];
256 sprintf(environment_var, "NTS_IP=%s", getenv("NTS_IP"));
258 cJSON *env_var_obj = cJSON_CreateString(environment_var);
259 if (env_var_obj == NULL)
261 printf("Could not create JSON object: Env array object NTS_IP\n");
264 cJSON_AddItemToArray(env_variables_array, env_var_obj);
266 sprintf(environment_var, "NETCONF_BASE=%d", base_netconf_port);
267 cJSON *env_var_obj_2 = cJSON_CreateString(environment_var);
268 if (env_var_obj_2 == NULL)
270 printf("Could not create JSON object: Env array object NETCONF_BASE\n");
273 cJSON_AddItemToArray(env_variables_array, env_var_obj_2);
275 char scripts_dir[200];
276 sprintf(scripts_dir, "SCRIPTS_DIR=%s", getenv("SCRIPTS_DIR"));
277 cJSON *env_var_obj_3 = cJSON_CreateString(scripts_dir);
278 if (env_var_obj_3 == NULL)
280 printf("Could not create JSON object: Env array object SCRIPTS_DIR\n");
283 cJSON_AddItemToArray(env_variables_array, env_var_obj_3);
285 cJSON_AddItemToObject(hostConfig, "Binds", binds);
287 char *post_data_string = NULL;
289 post_data_string = cJSON_PrintUnformatted(postDataJson);
291 printf("Post data JSON:\n%s\n", post_data_string);
293 if (postDataJson != NULL)
295 cJSON_Delete(postDataJson);
298 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data_string);
300 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
302 res = curl_easy_perform(curl);
310 cJSON *json_response = cJSON_Parse(curl_response_mem.memory);
311 const cJSON *container_id = NULL;
313 printf("%lu bytes retrieved\n", (unsigned long)curl_response_mem.size);
315 container_id = cJSON_GetObjectItemCaseSensitive(json_response, "Id");
317 if (cJSON_IsString(container_id) && (container_id->valuestring != NULL))
319 printf("Container id: \"%s\"\n", container_id->valuestring);
321 char container_id_short[13];
323 memset(container_id_short, '\0', sizeof(container_id_short));
324 strncpy(container_id_short, container_id->valuestring, 12);
326 printf("Container id short: \"%s\"\n", container_id_short);
328 cJSON_Delete(json_response);
329 return strdup(container_id_short);
332 cJSON_Delete(json_response);
338 static int start_docker_container_curl(char *container_id)
340 struct MemoryStruct curl_response_mem;
342 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
343 curl_response_mem.size = 0; /* no data at this point */
347 curl_easy_reset(curl);
348 set_curl_common_info();
351 sprintf(url, "http:/v%s/containers/%s/start", getenv("DOCKER_ENGINE_VERSION"), container_id);
353 curl_easy_setopt(curl, CURLOPT_URL, url);
355 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
357 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
359 res = curl_easy_perform(curl);
363 return SR_ERR_OPERATION_FAILED;
367 printf("Container %s started successfully!\n", container_id);
373 static int kill_and_remove_docker_container_curl(char *container_id)
375 struct MemoryStruct curl_response_mem;
377 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
378 curl_response_mem.size = 0; /* no data at this point */
382 curl_easy_reset(curl);
383 set_curl_common_info();
386 sprintf(url, "http:/v%s/containers/%s?force=true", getenv("DOCKER_ENGINE_VERSION"), container_id);
388 curl_easy_setopt(curl, CURLOPT_URL, url);
390 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
391 curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
393 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
395 res = curl_easy_perform(curl);
399 return SR_ERR_OPERATION_FAILED;
403 printf("Container %s removed successfully!\n", container_id);
409 static int send_mount_device_instance_ssh(char *url, char *credentials, char *device_name, int device_port)
413 curl_easy_reset(curl_odl);
414 set_curl_common_info_odl();
416 char url_for_curl[200];
417 sprintf(url_for_curl, "%s%s_%d", url, device_name, device_port);
419 curl_easy_setopt(curl_odl, CURLOPT_URL, url_for_curl);
421 char post_data_xml[1500];
423 sprintf(post_data_xml,
424 "<node xmlns=\"urn:TBD:params:xml:ns:yang:network-topology\">"
425 "<node-id>%s_%d</node-id>"
426 "<host xmlns=\"urn:opendaylight:netconf-node-topology\">%s</host>"
427 "<port xmlns=\"urn:opendaylight:netconf-node-topology\">%d</port>"
428 "<username xmlns=\"urn:opendaylight:netconf-node-topology\">%s</username>"
429 "<password xmlns=\"urn:opendaylight:netconf-node-topology\">%s</password>"
430 "<tcp-only xmlns=\"urn:opendaylight:netconf-node-topology\">false</tcp-only>"
431 "<keepalive-delay xmlns=\"urn:opendaylight:netconf-node-topology\">120</keepalive-delay>"
432 "<reconnect-on-changed-schema xmlns=\"urn:opendaylight:netconf-node-topology\">false</reconnect-on-changed-schema>"
433 "<sleep-factor xmlns=\"urn:opendaylight:netconf-node-topology\">1.5</sleep-factor>"
434 "<connection-timeout-millis xmlns=\"urn:opendaylight:netconf-node-topology\">20000</connection-timeout-millis>"
435 "<max-connection-attempts xmlns=\"urn:opendaylight:netconf-node-topology\">100</max-connection-attempts>"
436 "<between-attempts-timeout-millis xmlns=\"urn:opendaylight:netconf-node-topology\">2000</between-attempts-timeout-millis>"
438 device_name, device_port, getenv("NTS_IP"), device_port, "netconf", "netconf");
440 printf("Post data:\n%s\n", post_data_xml);
442 curl_easy_setopt(curl_odl, CURLOPT_POSTFIELDS, post_data_xml);
443 curl_easy_setopt(curl_odl, CURLOPT_CUSTOMREQUEST, "PUT");
444 curl_easy_setopt(curl_odl, CURLOPT_USERPWD, credentials);
446 res = curl_easy_perform(curl_odl);
449 printf("cURL failed to url=%s\n", url_for_curl);
452 long http_response_code = 0;
453 curl_easy_getinfo (curl_odl, CURLINFO_RESPONSE_CODE, &http_response_code);
454 if (http_response_code >= 200 && http_response_code <= 226 && http_response_code != CURLE_ABORTED_BY_CALLBACK)
456 printf("cURL succeeded to url=%s\n", url_for_curl);
460 printf("cURL to url=%s failed with code=%ld\n", url_for_curl, http_response_code);
461 return SR_ERR_OPERATION_FAILED;
467 static int send_mount_device_instance_tls(char *url, char *credentials, char *device_name, int device_port)
471 curl_easy_reset(curl_odl);
472 set_curl_common_info_odl();
474 char url_for_curl[200];
475 sprintf(url_for_curl, "%s%s_%d", url, device_name, device_port);
477 curl_easy_setopt(curl_odl, CURLOPT_URL, url_for_curl);
479 char post_data_xml[1500];
481 sprintf(post_data_xml,
482 "<node xmlns=\"urn:TBD:params:xml:ns:yang:network-topology\">"
483 "<protocol xmlns=\"urn:opendaylight:netconf-node-topology\">"
486 "<node-id>%s_%d</node-id>"
487 "<host xmlns=\"urn:opendaylight:netconf-node-topology\">%s</host>"
488 "<key-based xmlns=\"urn:opendaylight:netconf-node-topology\">"
489 "<username>%s</username>"
490 "<key-id>device-key</key-id>"
492 "<port xmlns=\"urn:opendaylight:netconf-node-topology\">%d</port>"
493 "<tcp-only xmlns=\"urn:opendaylight:netconf-node-topology\">false</tcp-only>"
494 "<keepalive-delay xmlns=\"urn:opendaylight:netconf-node-topology\">120</keepalive-delay>"
495 "<reconnect-on-changed-schema xmlns=\"urn:opendaylight:netconf-node-topology\">false</reconnect-on-changed-schema>"
496 "<sleep-factor xmlns=\"urn:opendaylight:netconf-node-topology\">1.5</sleep-factor>"
497 "<connection-timeout-millis xmlns=\"urn:opendaylight:netconf-node-topology\">20000</connection-timeout-millis>"
498 "<max-connection-attempts xmlns=\"urn:opendaylight:netconf-node-topology\">100</max-connection-attempts>"
499 "<between-attempts-timeout-millis xmlns=\"urn:opendaylight:netconf-node-topology\">2000</between-attempts-timeout-millis>"
501 device_name, device_port, getenv("NTS_IP"), "netconf", device_port);
503 printf("Post data:\n%s\n", post_data_xml);
505 curl_easy_setopt(curl_odl, CURLOPT_POSTFIELDS, post_data_xml);
506 curl_easy_setopt(curl_odl, CURLOPT_CUSTOMREQUEST, "PUT");
507 curl_easy_setopt(curl_odl, CURLOPT_USERPWD, credentials);
509 res = curl_easy_perform(curl_odl);
512 printf("cURL failed to url=%s\n", url_for_curl);
515 long http_response_code = 0;
516 curl_easy_getinfo (curl_odl, CURLINFO_RESPONSE_CODE, &http_response_code);
517 if (http_response_code >= 200 && http_response_code <= 226 && http_response_code != CURLE_ABORTED_BY_CALLBACK)
519 printf("cURL succeeded to url=%s\n", url_for_curl);
523 printf("cURL to url=%s failed with code=%ld\n", url_for_curl, http_response_code);
524 return SR_ERR_OPERATION_FAILED;
530 static int send_unmount_device_instance(char *url, char *credentials, char *device_name, int device_port)
534 curl_easy_reset(curl_odl);
535 set_curl_common_info_odl();
537 char url_for_curl[200];
538 sprintf(url_for_curl, "%s%s_%d", url, device_name, device_port);
540 curl_easy_setopt(curl_odl, CURLOPT_URL, url_for_curl);
542 curl_easy_setopt(curl_odl, CURLOPT_POSTFIELDS, "");
543 curl_easy_setopt(curl_odl, CURLOPT_CUSTOMREQUEST, "DELETE");
544 curl_easy_setopt(curl_odl, CURLOPT_USERPWD, credentials);
546 res = curl_easy_perform(curl_odl);
549 printf("cURL failed to url=%s\n", url_for_curl);
552 long http_response_code = 0;
553 curl_easy_getinfo (curl_odl, CURLINFO_RESPONSE_CODE, &http_response_code);
554 if (http_response_code == 200 && http_response_code != CURLE_ABORTED_BY_CALLBACK)
556 printf("cURL succeeded to url=%s\n", url_for_curl);
560 printf("cURL to url=%s failed with code=%ld\n", url_for_curl, http_response_code);
561 return SR_ERR_OPERATION_FAILED;
569 static int send_mount_device(device_t *current_device, controller_t controller_details)
572 bool is_mounted = true;
574 //This is where we hardcoded: 7 devices will have SSH connections and 3 devices will have TLS connections
575 for (int port = 0; port < NETCONF_CONNECTIONS_PER_DEVICE - 3; ++port)
577 rc = send_mount_device_instance_ssh(controller_details.url, controller_details.credentials,
578 current_device->device_id, current_device->netconf_port + port);
584 for (int port = NETCONF_CONNECTIONS_PER_DEVICE - 3; port < NETCONF_CONNECTIONS_PER_DEVICE; ++port)
586 rc = send_mount_device_instance_tls(controller_details.url, controller_details.credentials,
587 current_device->device_id, current_device->netconf_port + port);
594 current_device->is_mounted = is_mounted;
599 static int send_unmount_device(device_t *current_device, controller_t controller_details)
603 for (int port = 0; port < NETCONF_CONNECTIONS_PER_DEVICE; ++port)
605 rc = send_unmount_device_instance(controller_details.url, controller_details.credentials,
606 current_device->device_id, current_device->netconf_port + port);
609 printf("Could not send unmount for ODL with url=\"%s\", for device=\"%s\" and port=%d\n",
610 controller_details.url, current_device->device_id, current_device->netconf_port);
613 current_device->is_mounted = false;
618 device_stack_t *new_device_stack(void)
620 device_stack_t *stack = malloc(sizeof(*stack));
624 stack->stack_size = 0;
629 void push_device(device_stack_t *theStack, char *dev_id, int port)
631 device_t *new_dev = malloc(sizeof(*new_dev));
634 new_dev->device_id = strdup(dev_id);
635 new_dev->netconf_port = port;
636 new_dev->is_mounted = false;
637 new_dev->operational_state = strdup("not-specified");
639 new_dev->next = theStack->head;
641 theStack->head = new_dev;
642 theStack->stack_size++;
646 void pop_device(device_stack_t *theStack)
648 if (theStack && theStack->head) {
649 device_t *temp = theStack->head;
650 theStack->head = theStack->head->next;
652 free(temp->device_id);
653 free(temp->operational_state);
655 theStack->stack_size--;
659 int get_netconf_port_next(device_stack_t *theStack)
661 if (theStack && theStack->stack_size > 0) {
662 return theStack->head->netconf_port + NETCONF_CONNECTIONS_PER_DEVICE;
665 return get_netconf_port_base();
668 int get_netconf_port_base()
670 int netconf_port_base = 0, rc;
672 char *netconf_base_string = getenv("NETCONF_BASE");
674 if (netconf_base_string != NULL)
676 rc = sscanf(netconf_base_string, "%d", &netconf_port_base);
679 printf("Could not get the NETCONF_BASE port! Using the default 30.000...\n");
680 netconf_port_base = 30000;
684 return netconf_port_base;
688 char *get_id_last_device(device_stack_t *theStack)
690 if (theStack && theStack->head) {
691 return theStack->head->device_id;
696 int get_current_number_of_mounted_devices(device_stack_t *theStack)
698 int mounted_devices = 0;
700 if (theStack && theStack->head)
702 device_t *current_device = theStack->head;
704 while (current_device != NULL)
706 if (current_device->is_mounted)
710 current_device = current_device->next;
714 return mounted_devices;
717 int get_current_number_of_devices(device_stack_t *theStack)
719 struct MemoryStruct curl_response_mem;
721 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
722 curl_response_mem.size = 0; /* no data at this point */
726 curl_easy_reset(curl);
727 set_curl_common_info();
730 sprintf(url, "http:/v%s/containers/json?all=true&filters={\"label\":[\"NTS\"],\"status\":[\"running\"]}",
731 getenv("DOCKER_ENGINE_VERSION"));
733 curl_easy_setopt(curl, CURLOPT_URL, url);
735 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
736 curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
738 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
740 res = curl_easy_perform(curl);
744 return SR_ERR_OPERATION_FAILED;
748 cJSON *json_response = cJSON_Parse(curl_response_mem.memory);
750 printf("%lu bytes retrieved\n", (unsigned long)curl_response_mem.size);
752 if (json_response == NULL || !cJSON_IsArray(json_response))
754 printf("Could not parse JSON response for url=\"%s\"\n", url);
755 return SR_ERR_OPERATION_FAILED;
758 int num_of_devices = cJSON_GetArraySize(json_response);
759 cJSON_Delete(json_response);
761 return num_of_devices;
767 static int set_operational_state_of_device(device_stack_t *theStack, char *device_id, char *operational_state)
769 if (theStack && theStack->head)
771 device_t *current_device = theStack->head;
773 while (current_device != NULL)
775 if (strcmp(current_device->device_id, device_id) == 0)
777 free(current_device->operational_state);
778 current_device->operational_state = strdup(operational_state);
783 current_device = current_device->next;
787 printf("Could not find device with uuid=\"%s\"\n", device_id);
788 return SR_ERR_OPERATION_FAILED;
791 char* get_docker_container_operational_state(device_stack_t *theStack, char *container_id)
793 if (theStack && theStack->head)
795 device_t *current_device = theStack->head;
797 while (current_device != NULL)
799 if (strcmp(current_device->device_id, container_id) == 0)
801 return current_device->operational_state;
804 current_device = current_device->next;
811 int start_device(device_stack_t *theStack)
814 static cJSON* managerBindings = NULL;
816 if (managerBindings == NULL)
818 managerBindings = get_docker_container_bindings();
821 int netconf_base = get_netconf_port_next(theStack);
823 char *dev_id = create_docker_container_curl(netconf_base, managerBindings);
825 push_device(theStack, dev_id, netconf_base);
827 rc = start_docker_container_curl(dev_id);
830 printf("Could not start device with device_id=\"%s\"\n", dev_id);
842 curl = curl_easy_init();
845 printf("cURL initialization error! Aborting call!\n");
846 return SR_ERR_OPERATION_FAILED;
856 curl_easy_cleanup(curl);
864 curl_odl = curl_easy_init();
866 if (curl_odl == NULL) {
867 printf("cURL initialization error! Aborting call!\n");
868 return SR_ERR_OPERATION_FAILED;
874 int cleanup_curl_odl()
876 if (curl_odl != NULL)
878 curl_easy_cleanup(curl_odl);
884 int stop_device(device_stack_t *theStack)
887 char *last_id = get_id_last_device(theStack);
889 rc = kill_and_remove_docker_container_curl(last_id);
892 printf("Could not kill and remove docker container with uuid=\"%s\"\n", last_id);
895 pop_device(theStack);
900 int mount_device(device_stack_t *theStack, controller_t controller_details)
904 if (theStack && theStack->head)
906 device_t *current_device = theStack->head;
907 while (current_device != NULL && current_device->is_mounted == true)
909 printf("Device \"%s\" is already mounted, skipping...\n", current_device->device_id);
910 current_device = current_device->next;
913 if (current_device != NULL)
915 printf("Sending mount device for device \"%s\"...\n", current_device->device_id);
916 rc = send_mount_device(current_device, controller_details);
919 return SR_ERR_OPERATION_FAILED;
927 int unmount_device(device_stack_t *theStack, controller_t controller_list)
931 if (theStack && theStack->head)
933 device_t *current_device = theStack->head;
934 while (current_device != NULL && current_device->is_mounted == false)
936 printf("Device \"%s\" is already unmounted, skipping...\n", current_device->device_id);
937 current_device = current_device->next;
940 if (current_device != NULL)
942 printf("Sending unmount device for device \"%s\"...\n", current_device->device_id);
943 rc = send_unmount_device(current_device, controller_list);
946 return SR_ERR_OPERATION_FAILED;
954 int get_docker_containers_operational_state_curl(device_stack_t *theStack)
957 struct MemoryStruct curl_response_mem;
959 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
960 curl_response_mem.size = 0; /* no data at this point */
964 curl_easy_reset(curl);
965 set_curl_common_info();
968 sprintf(url, "http:/v%s/containers/json?all=true&filters={\"label\":[\"NTS\"]}", getenv("DOCKER_ENGINE_VERSION"));
970 curl_easy_setopt(curl, CURLOPT_URL, url);
972 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
973 curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
975 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
977 res = curl_easy_perform(curl);
981 return SR_ERR_OPERATION_FAILED;
985 cJSON *json_response = cJSON_Parse(curl_response_mem.memory);
986 const cJSON *container = NULL;
988 printf("%lu bytes retrieved\n", (unsigned long)curl_response_mem.size);
990 if (json_response == NULL || !cJSON_IsArray(json_response))
992 printf("Could not parse JSON response for url=\"%s\"\n", url);
993 return SR_ERR_OPERATION_FAILED;
996 cJSON_ArrayForEach(container, json_response)
998 cJSON *container_id_long = cJSON_GetObjectItemCaseSensitive(container, "Id");
999 cJSON *state = cJSON_GetObjectItemCaseSensitive(container, "State");
1001 if (cJSON_IsString(container_id_long) && (container_id_long->valuestring != NULL))
1003 char container_id_short[13];
1005 memset(container_id_short, '\0', sizeof(container_id_short));
1006 strncpy(container_id_short, container_id_long->valuestring, 12);
1008 if (cJSON_IsString(state) && (state->valuestring != NULL))
1010 rc = set_operational_state_of_device(theStack, container_id_short, state->valuestring);
1011 if (rc != SR_ERR_OK)
1013 printf("Could not set the operational state for the device with uuid=\"%s\"\n", container_id_short);
1019 cJSON_Delete(json_response);
1025 char* get_docker_container_resource_stats(device_stack_t *theStack)
1027 char line[LINE_BUFSIZE];
1031 /* Get a pipe where the output from the scripts comes in */
1033 sprintf(script, "%s/docker_stats.sh", getenv("SCRIPTS_DIR"));
1035 pipe = popen(script, "r");
1036 if (pipe == NULL) { /* check for errors */
1037 printf("Could not open script.\n");
1038 return NULL; /* return with exit code indicating error */
1041 /* Read script output from the pipe line by line */
1043 while (fgets(line, LINE_BUFSIZE, pipe) != NULL) {
1044 printf("Script output line %d: %s", linenr, line);
1047 pclose(pipe); /* Close the pipe */
1048 return strdup(line);
1051 /* Once here, out of the loop, the script has ended. */
1052 pclose(pipe); /* Close the pipe */
1053 return NULL; /* return with exit code indicating success. */
1056 int notification_delay_period_changed(int period)
1058 char *stringConfiguration = readConfigFileInString();
1060 if (stringConfiguration == NULL)
1062 printf("Could not read configuration file!\n");
1063 return SR_ERR_OPERATION_FAILED;
1066 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
1067 if (jsonConfig == NULL)
1069 free(stringConfiguration);
1070 const char *error_ptr = cJSON_GetErrorPtr();
1071 if (error_ptr != NULL)
1073 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1075 return SR_ERR_OPERATION_FAILED;
1077 //we don't need the string anymore
1078 free(stringConfiguration);
1079 stringConfiguration = NULL;
1081 cJSON *notifConfig = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
1082 if (!cJSON_IsObject(notifConfig))
1084 printf("Configuration JSON is not as expected: notification-config is not an object");
1086 return SR_ERR_OPERATION_FAILED;
1089 cJSON *faultNotifDelay = cJSON_GetObjectItemCaseSensitive(notifConfig, "fault-notification-delay-period");
1090 if (!cJSON_IsNumber(faultNotifDelay))
1092 printf("Configuration JSON is not as expected: fault-notification-delay-period is not an object");
1094 return SR_ERR_OPERATION_FAILED;
1097 //we set the value of the fault-notification-delay-period object
1098 cJSON_SetNumberValue(faultNotifDelay, period);
1100 //writing the new JSON to the configuration file
1101 stringConfiguration = cJSON_Print(jsonConfig);
1102 writeConfigFile(stringConfiguration);
1109 int ves_heartbeat_period_changed(int period)
1111 char *stringConfiguration = readConfigFileInString();
1113 if (stringConfiguration == NULL)
1115 printf("Could not read configuration file!\n");
1116 return SR_ERR_OPERATION_FAILED;
1119 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
1120 if (jsonConfig == NULL)
1122 free(stringConfiguration);
1123 const char *error_ptr = cJSON_GetErrorPtr();
1124 if (error_ptr != NULL)
1126 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1128 return SR_ERR_OPERATION_FAILED;
1130 //we don't need the string anymore
1131 free(stringConfiguration);
1132 stringConfiguration = NULL;
1134 cJSON *notifConfig = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
1135 if (!cJSON_IsObject(notifConfig))
1137 printf("Configuration JSON is not as expected: notification-config is not an object");
1139 return SR_ERR_OPERATION_FAILED;
1142 cJSON *vesHeartbeatPeriod = cJSON_GetObjectItemCaseSensitive(notifConfig, "ves-heartbeat-period");
1143 if (!cJSON_IsNumber(vesHeartbeatPeriod))
1145 printf("Configuration JSON is not as expected: ves-heartbeat-period is not an object");
1147 return SR_ERR_OPERATION_FAILED;
1150 //we set the value of the fault-notification-delay-period object
1151 cJSON_SetNumberValue(vesHeartbeatPeriod, period);
1153 //writing the new JSON to the configuration file
1154 stringConfiguration = cJSON_Print(jsonConfig);
1155 writeConfigFile(stringConfiguration);
1162 static int add_keystore_entry_odl(char *url, char *credentials)
1166 curl_easy_reset(curl_odl);
1167 set_curl_common_info_odl();
1169 char url_for_curl[200];
1170 sprintf(url_for_curl, "%s", url);
1172 curl_easy_setopt(curl_odl, CURLOPT_URL, url_for_curl);
1174 char post_data_xml[2000];
1176 sprintf(post_data_xml,
1177 "<input xmlns=\"urn:opendaylight:netconf:keystore\">"
1179 "<key-id>device-key</key-id>"
1180 "<private-key>MIIEpAIBAAKCAQEAueCQaNQWoNmFK6LKu1p8U8ZWdWg/PvDdLsJyzfzl/Qw4UA68"
1181 "SfFNaY06zZl8QB9W02nr5kWeeMY0VA3adrPgOlvfx3oWlFbkETnMaN4OT3WTQ0Wt"
1182 "6jAWZDzVfopwpJPAzRPxACDftIqFGagYcF32hZlVNqqnVdbXh0S0EViweqp/dbG4"
1183 "VDUHSNVbglc+u4UbEzNIFXMdEFsJZpkynOmSiTsIATqIhb+2srkVgLwhfkC2qkuH"
1184 "QwAHdubuB07ObM2z01UhyEdDvEYGHwtYAGDBL2TAcsI0oGeVkRyuOkV0QY0UN7UE"
1185 "FI1yTYw+xZ42HgFx3uGwApCImxhbj69GBYWFqwIDAQABAoIBAQCZN9kR8DGu6V7y"
1186 "t0Ax68asL8O5B/OKaHWKQ9LqpVrXmikZJOxkbzoGldow/CIFoU+q+Zbwu9aDa65a"
1187 "0wiP7Hoa4Py3q5XNNUrOQDyU/OYC7cI0I83WS0lJ2zOJGYj8wKae5Z81IeQFKGHK"
1188 "4lsy1OGPAvPRGh7RjUUgRavA2MCwe07rWRuDb/OJFe4Oh56UMEjwMiNBtMNtncog"
1189 "j1vr/qgRJdf9tf0zlJmLvUJ9+HSFFV9I/97LJyFhb95gAfHkjdVroLVgT3Cho+4P"
1190 "WtZaKCIGD0OwfOG2nLV4leXvRUk62/LMlB8NI9+JF7Xm+HCKbaWHNWC7mvWSLV58"
1191 "Zl4AbUWRAoGBANyJ6SFHFRHSPDY026SsdMzXR0eUxBAK7G70oSBKKhY+O1j0ocLE"
1192 "jI2krHJBhHbLlnvJVyMUaCUOTS5m0uDw9hgSsAqeSL3hL38kxVZw+KNG9Ouno1Fl"
1193 "KnE/xXHlPQyeGs/P8nAMzHZxQtEsQdQayJEhK2XXHTsy7Q3MxDisfVJ1AoGBANfD"
1194 "34gB+OMx6pwj7zk3qWbYXSX8xjCZMR0ciko+h4xeMP2N8B0oyoqC+v1ABMAtJ3wG"
1195 "sGZd0hV9gwM7OUM3SEwkn6oeg1GemWLcn4rlSmTnZc4aeVwrEWlnSNFX3s4g9l4u"
1196 "k8Ugu4MVJYqH8HuDQ5Ggl6/QAwPzMSEdCW0O+jOfAoGAIBRbegC5+t6m7Yegz4Ja"
1197 "dxV1g98K6f58x+MDsQu4tYWV4mmrQgaPH2dtwizvlMwmdpkh+LNWNtWuumowkJHc"
1198 "akIFo3XExQIFg6wYnGtQb4e5xrGa2xMpKlIJaXjb+YLiCYqJDG2ALFZrTrvuU2kV"
1199 "9a5qfqTc1qigvNolTM0iaaUCgYApmrZWhnLUdEKV2wP813PNxfioI4afxlpHD8LG"
1200 "sCn48gymR6E+Lihn7vuwq5B+8fYEH1ISWxLwW+RQUjIneNhy/jjfV8TgjyFqg7or"
1201 "0Sy4KjpiNI6kLBXOakELRNNMkeSPopGR2E7v5rr3bGD9oAD+aqX1G7oJH/KgPPYd"
1202 "Vl7+ZwKBgQDcHyWYrimjyUgKaQD2GmoO9wdcJYQ59ke9K+OuGlp4ti5arsi7N1tP"
1203 "B4f09aeELM2ASIuk8Q/Mx0jQFnm8lzRFXdewgvdPoZW/7VufM9O7dGPOc41cm2Dh"
1204 "yrTcXx/VmUBb+/fnXVEgCv7gylp/wtdTGHQBQJHR81jFBz0lnLj+gg==</private-key>"
1205 "<passphrase></passphrase>"
1209 printf("Post data:\n%s\n", post_data_xml);
1211 curl_easy_setopt(curl_odl, CURLOPT_POSTFIELDS, post_data_xml);
1212 curl_easy_setopt(curl_odl, CURLOPT_CUSTOMREQUEST, "POST");
1213 curl_easy_setopt(curl_odl, CURLOPT_USERPWD, credentials);
1215 res = curl_easy_perform(curl_odl);
1216 if (res != CURLE_OK)
1218 printf("cURL failed to url=%s\n", url_for_curl);
1221 long http_response_code = 0;
1222 curl_easy_getinfo (curl_odl, CURLINFO_RESPONSE_CODE, &http_response_code);
1223 if (http_response_code >= 200 && http_response_code <= 226 && http_response_code != CURLE_ABORTED_BY_CALLBACK)
1225 printf("cURL succeeded to url=%s\n", url_for_curl);
1229 printf("cURL to url=%s failed with code=%ld\n", url_for_curl, http_response_code);
1230 return SR_ERR_OPERATION_FAILED;
1236 static int add_private_key_odl(char *url, char *credentials)
1240 curl_easy_reset(curl_odl);
1241 set_curl_common_info_odl();
1243 char url_for_curl[200];
1244 sprintf(url_for_curl, "%s", url);
1246 curl_easy_setopt(curl_odl, CURLOPT_URL, url_for_curl);
1248 char post_data_xml[4000];
1250 sprintf(post_data_xml,
1251 "<input xmlns=\"urn:opendaylight:netconf:keystore\">"
1253 "<name>device-key</name>"
1254 "<data>MIIEpAIBAAKCAQEAueCQaNQWoNmFK6LKu1p8U8ZWdWg/PvDdLsJyzfzl/Qw4UA68SfFNaY06zZl8QB9W02nr5kWeeMY0VA3adrPgOlvfx3oWlFbkETnMaN4OT3WTQ0Wt6jAWZDzVfopwpJPAzRPxACDftIqFGagYcF32hZlVNqqnVdbXh0S0EViweqp/dbG4VDUHSNVbglc+u4UbEzNIFXMdEFsJZpkynOmSiTsIATqIhb+2srkVgLwhfkC2qkuHQwAHdubuB07ObM2z01UhyEdDvEYGHwtYAGDBL2TAcsI0oGeVkRyuOkV0QY0UN7UEFI1yTYw+xZ42HgFx3uGwApCImxhbj69GBYWFqwIDAQABAoIBAQCZN9kR8DGu6V7yt0Ax68asL8O5B/OKaHWKQ9LqpVrXmikZJOxkbzoGldow/CIFoU+q+Zbwu9aDa65a0wiP7Hoa4Py3q5XNNUrOQDyU/OYC7cI0I83WS0lJ2zOJGYj8wKae5Z81IeQFKGHK4lsy1OGPAvPRGh7RjUUgRavA2MCwe07rWRuDb/OJFe4Oh56UMEjwMiNBtMNtncogj1vr/qgRJdf9tf0zlJmLvUJ9+HSFFV9I/97LJyFhb95gAfHkjdVroLVgT3Cho+4PWtZaKCIGD0OwfOG2nLV4leXvRUk62/LMlB8NI9+JF7Xm+HCKbaWHNWC7mvWSLV58Zl4AbUWRAoGBANyJ6SFHFRHSPDY026SsdMzXR0eUxBAK7G70oSBKKhY+O1j0ocLEjI2krHJBhHbLlnvJVyMUaCUOTS5m0uDw9hgSsAqeSL3hL38kxVZw+KNG9Ouno1FlKnE/xXHlPQyeGs/P8nAMzHZxQtEsQdQayJEhK2XXHTsy7Q3MxDisfVJ1AoGBANfD34gB+OMx6pwj7zk3qWbYXSX8xjCZMR0ciko+h4xeMP2N8B0oyoqC+v1ABMAtJ3wGsGZd0hV9gwM7OUM3SEwkn6oeg1GemWLcn4rlSmTnZc4aeVwrEWlnSNFX3s4g9l4uk8Ugu4MVJYqH8HuDQ5Ggl6/QAwPzMSEdCW0O+jOfAoGAIBRbegC5+t6m7Yegz4JadxV1g98K6f58x+MDsQu4tYWV4mmrQgaPH2dtwizvlMwmdpkh+LNWNtWuumowkJHcakIFo3XExQIFg6wYnGtQb4e5xrGa2xMpKlIJaXjb+YLiCYqJDG2ALFZrTrvuU2kV9a5qfqTc1qigvNolTM0iaaUCgYApmrZWhnLUdEKV2wP813PNxfioI4afxlpHD8LGsCn48gymR6E+Lihn7vuwq5B+8fYEH1ISWxLwW+RQUjIneNhy/jjfV8TgjyFqg7or0Sy4KjpiNI6kLBXOakELRNNMkeSPopGR2E7v5rr3bGD9oAD+aqX1G7oJH/KgPPYdVl7+ZwKBgQDcHyWYrimjyUgKaQD2GmoO9wdcJYQ59ke9K+OuGlp4ti5arsi7N1tPB4f09aeELM2ASIuk8Q/Mx0jQFnm8lzRFXdewgvdPoZW/7VufM9O7dGPOc41cm2DhyrTcXx/VmUBb+/fnXVEgCv7gylp/wtdTGHQBQJHR81jFBz0lnLj+gg==</data>"
1255 "<certificate-chain>MIIECTCCAvGgAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBjDELMAkGA1UEBhMCQ1oxFjAUBgNVBAgMDVNvdXRoIE1vcmF2aWExDTALBgNVBAcMBEJybm8xDzANBgNVBAoMBkNFU05FVDEMMAoGA1UECwwDVE1DMRMwEQYDVQQDDApleGFtcGxlIENBMSIwIAYJKoZIhvcNAQkBFhNleGFtcGxlY2FAbG9jYWxob3N0MB4XDTE1MDczMDA3MjcxOFoXDTM1MDcyNTA3MjcxOFowgYUxCzAJBgNVBAYTAkNaMRYwFAYDVQQIDA1Tb3V0aCBNb3JhdmlhMQ8wDQYDVQQKDAZDRVNORVQxDDAKBgNVBAsMA1RNQzEXMBUGA1UEAwwOZXhhbXBsZSBjbGllbnQxJjAkBgkqhkiG9w0BCQEWF2V4YW1wbGVjbGllbnRAbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAueCQaNQWoNmFK6LKu1p8U8ZWdWg/PvDdLsJyzfzl/Qw4UA68SfFNaY06zZl8QB9W02nr5kWeeMY0VA3adrPgOlvfx3oWlFbkETnMaN4OT3WTQ0Wt6jAWZDzVfopwpJPAzRPxACDftIqFGagYcF32hZlVNqqnVdbXh0S0EViweqp/dbG4VDUHSNVbglc+u4UbEzNIFXMdEFsJZpkynOmSiTsIATqIhb+2srkVgLwhfkC2qkuHQwAHdubuB07ObM2z01UhyEdDvEYGHwtYAGDBL2TAcsI0oGeVkRyuOkV0QY0UN7UEFI1yTYw+xZ42HgFx3uGwApCImxhbj69GBYWFqwIDAQABo3sweTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUXGpLeLnh2cSDARAVA7KrBxGYpo8wHwYDVR0jBBgwFoAUc1YQIqjZsHVwlea0AB4N+ilNI2gwDQYJKoZIhvcNAQELBQADggEBAJPV3RTXFRtNyOU4rjPpYeBAIAFp2aqGc4t2J1c7oPp/1n+lZvjnwtlJpZHxMM783e2ryDQ6dkvXDf8kpwKlg3U3mkJ3xKkDdWrM4QwghXdCN519aa9qmu0zdFL+jUAaWlQ5tsceOrvbusCcbMqiFGk/QfpHqPv52SVWbYyUx7IX7DE+UjgsLHycfV/tlcx4ZE6soTzl9VdgSL/zmzG3rjsr58J80rXckLgBhvijgBlIAJvWfC7D0vaouvBInSFXymdPVoUDZ30cdGLf+hI/i/TfsEMOinLrXVdkSGNo6FXAHKSvXeB9oFKSzhQ7OPyRyqvEPycUSw/qD6FVr80oDDc=</certificate-chain>"
1259 printf("Post data:\n%s\n", post_data_xml);
1261 curl_easy_setopt(curl_odl, CURLOPT_POSTFIELDS, post_data_xml);
1262 curl_easy_setopt(curl_odl, CURLOPT_CUSTOMREQUEST, "POST");
1263 curl_easy_setopt(curl_odl, CURLOPT_USERPWD, credentials);
1265 res = curl_easy_perform(curl_odl);
1266 if (res != CURLE_OK)
1268 printf("cURL failed to url=%s\n", url_for_curl);
1271 long http_response_code = 0;
1272 curl_easy_getinfo (curl_odl, CURLINFO_RESPONSE_CODE, &http_response_code);
1273 if (http_response_code >= 200 && http_response_code <= 226 && http_response_code != CURLE_ABORTED_BY_CALLBACK)
1275 printf("cURL succeeded to url=%s\n", url_for_curl);
1279 printf("cURL to url=%s failed with code=%ld\n", url_for_curl, http_response_code);
1280 return SR_ERR_OPERATION_FAILED;
1286 static int add_trusted_ca_odl(char *url, char *credentials)
1290 curl_easy_reset(curl_odl);
1291 set_curl_common_info_odl();
1293 char url_for_curl[200];
1294 sprintf(url_for_curl, "%s", url);
1296 curl_easy_setopt(curl_odl, CURLOPT_URL, url_for_curl);
1298 char post_data_xml[2000];
1300 sprintf(post_data_xml,
1301 "<input xmlns=\"urn:opendaylight:netconf:keystore\">"
1302 "<trusted-certificate>"
1303 "<name>test_trusted_cert</name>"
1304 "<certificate>MIID7TCCAtWgAwIBAgIJAMtE1NGAR5KoMA0GCSqGSIb3DQEBBQUAMIGMMQswCQYDVQQGEwJDWjEWMBQGA1UECAwNU291dGggTW9yYXZpYTENMAsGA1UEBwwEQnJubzEPMA0GA1UECgwGQ0VTTkVUMQwwCgYDVQQLDANUTUMxEzARBgNVBAMMCmV4YW1wbGUgQ0ExIjAgBgkqhkiG9w0BCQEWE2V4YW1wbGVjYUBsb2NhbGhvc3QwHhcNMTQwNzI0MTQxOTAyWhcNMjQwNzIxMTQxOTAyWjCBjDELMAkGA1UEBhMCQ1oxFjAUBgNVBAgMDVNvdXRoIE1vcmF2aWExDTALBgNVBAcMBEJybm8xDzANBgNVBAoMBkNFU05FVDEMMAoGA1UECwwDVE1DMRMwEQYDVQQDDApleGFtcGxlIENBMSIwIAYJKoZIhvcNAQkBFhNleGFtcGxlY2FAbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArD3TDHPAMT2Z84orK4lMlarbgooIUCcRZyLe+QM+8KY8Hn+mGaxPEOTSL3ywszqefB/Utm2hPKLHX684iRC14ID9WDGHxPjvoPArhgFhfV+qnPfxKTgxZC12uOj4u1V9y+SkTCocFbRfXVBGpojrBuDHXkDMDEWNvr8/52YCv7bGaiBwUHolcLCUbmtKILCG0RNJyTaJpXQdAeq5Z1SJotpbfYFFtAXB32hVoLug1dzl2tjG9sb1wq3QaDExcbC5w6P65qOkNoyym9ne6QlQagCqVDyFn3vcqkRaTjvZmxauCeUxXgJoXkyWcm0lM1KMHdoTArmchw2Dz0yHHSyDAQIDAQABo1AwTjAdBgNVHQ4EFgQUc1YQIqjZsHVwlea0AB4N+ilNI2gwHwYDVR0jBBgwFoAUc1YQIqjZsHVwlea0AB4N+ilNI2gwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAI/1KH60qnw9Xs2RGfi0/IKf5EynXt4bQX8EIyVKwSkYKe04zZxYfLIl/Q2HOPYoFmm3daj5ddr0ZS1i4p4fTUhstjsYWvXs3W/HhVmFUslakkn3PrswhP77fCk6eEJLxdfyJ1C7Uudq2m1isZbKih+XF0mG1LxJaDMocSz4eAya7M5brwjy8DoOmA1TnLQFCVcpn+sCr7VC4wE/JqxyVhBCk/MuGqqM3B1j90bGFZ112ZOecyE0EDSr6IbiRBtmeNbEwOFjKXhNLYdxpBZ9D8A/368OckZkCrVLGuJNxK9UwCVTe8IhotHUqU9EqFDmxdV8oIdU/OzUwwNPA/Bd/9g==</certificate>"
1305 "</trusted-certificate>"
1308 printf("Post data:\n%s\n", post_data_xml);
1310 curl_easy_setopt(curl_odl, CURLOPT_POSTFIELDS, post_data_xml);
1311 curl_easy_setopt(curl_odl, CURLOPT_CUSTOMREQUEST, "POST");
1312 curl_easy_setopt(curl_odl, CURLOPT_USERPWD, credentials);
1314 res = curl_easy_perform(curl_odl);
1315 if (res != CURLE_OK)
1317 printf("cURL failed to url=%s\n", url_for_curl);
1320 long http_response_code = 0;
1321 curl_easy_getinfo (curl_odl, CURLINFO_RESPONSE_CODE, &http_response_code);
1322 if (http_response_code >= 200 && http_response_code <= 226 && http_response_code != CURLE_ABORTED_BY_CALLBACK)
1324 printf("cURL succeeded to url=%s\n", url_for_curl);
1328 printf("cURL to url=%s failed with code=%ld\n", url_for_curl, http_response_code);
1329 return SR_ERR_OPERATION_FAILED;
1335 int add_key_pair_to_odl(controller_t *controller_list, int controller_list_size)
1339 rc = add_keystore_entry_odl(controller_list[0].url_for_keystore_add, controller_list[0].credentials);
1340 if (rc != SR_ERR_OK)
1342 printf("Failed to add keystore entry to ODL.\n");
1345 rc = add_private_key_odl(controller_list[0].url_for_private_key_add, controller_list[0].credentials);
1346 if (rc != SR_ERR_OK)
1348 printf("Failed to add private key entry to ODL.\n");
1351 rc = add_trusted_ca_odl(controller_list[0].url_for_trusted_ca_add, controller_list[0].credentials);
1352 if (rc != SR_ERR_OK)
1354 printf("Failed to add trusted CA entry to ODL.\n");
1360 int ves_ip_changed(char *new_ip)
1362 char *stringConfiguration = readConfigFileInString();
1364 if (stringConfiguration == NULL)
1366 printf("Could not read configuration file!\n");
1367 return SR_ERR_OPERATION_FAILED;
1370 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
1371 if (jsonConfig == NULL)
1373 free(stringConfiguration);
1374 const char *error_ptr = cJSON_GetErrorPtr();
1375 if (error_ptr != NULL)
1377 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1379 return SR_ERR_OPERATION_FAILED;
1381 //we don't need the string anymore
1382 free(stringConfiguration);
1383 stringConfiguration = NULL;
1385 cJSON *vesDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ves-endpoint-details");
1386 if (!cJSON_IsObject(vesDetails))
1388 printf("Configuration JSON is not as expected: ves-endpoint-details is not an object");
1390 return SR_ERR_OPERATION_FAILED;
1393 cJSON *vesIp = cJSON_GetObjectItemCaseSensitive(vesDetails, "ves-endpoint-ip");
1394 if (!cJSON_IsString(vesIp))
1396 printf("Configuration JSON is not as expected: ves-endpoint-ip is not a string");
1398 return SR_ERR_OPERATION_FAILED;
1401 //we set the value of the fault-notification-delay-period object
1402 cJSON_ReplaceItemInObject(vesDetails, "ves-endpoint-ip", cJSON_CreateString(new_ip));
1404 //writing the new JSON to the configuration file
1405 stringConfiguration = cJSON_Print(jsonConfig);
1406 writeConfigFile(stringConfiguration);
1413 int ves_port_changed(int new_port)
1415 char *stringConfiguration = readConfigFileInString();
1417 if (stringConfiguration == NULL)
1419 printf("Could not read configuration file!\n");
1420 return SR_ERR_OPERATION_FAILED;
1423 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
1424 if (jsonConfig == NULL)
1426 free(stringConfiguration);
1427 const char *error_ptr = cJSON_GetErrorPtr();
1428 if (error_ptr != NULL)
1430 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1432 return SR_ERR_OPERATION_FAILED;
1434 //we don't need the string anymore
1435 free(stringConfiguration);
1436 stringConfiguration = NULL;
1438 cJSON *vesDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ves-endpoint-details");
1439 if (!cJSON_IsObject(vesDetails))
1441 printf("Configuration JSON is not as expected: ves-endpoint-details is not an object");
1443 return SR_ERR_OPERATION_FAILED;
1446 cJSON *vesPort = cJSON_GetObjectItemCaseSensitive(vesDetails, "ves-endpoint-port");
1447 if (!cJSON_IsNumber(vesPort))
1449 printf("Configuration JSON is not as expected: ves-endpoint-port is not a number.");
1451 return SR_ERR_OPERATION_FAILED;
1454 //we set the value of the fault-notification-delay-period object
1455 cJSON_SetNumberValue(vesPort, new_port);
1457 //writing the new JSON to the configuration file
1458 stringConfiguration = cJSON_Print(jsonConfig);
1459 writeConfigFile(stringConfiguration);
1466 int ves_registration_changed(cJSON_bool new_bool)
1468 char *stringConfiguration = readConfigFileInString();
1470 if (stringConfiguration == NULL)
1472 printf("Could not read configuration file!\n");
1473 return SR_ERR_OPERATION_FAILED;
1476 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
1477 if (jsonConfig == NULL)
1479 free(stringConfiguration);
1480 const char *error_ptr = cJSON_GetErrorPtr();
1481 if (error_ptr != NULL)
1483 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1485 return SR_ERR_OPERATION_FAILED;
1487 //we don't need the string anymore
1488 free(stringConfiguration);
1489 stringConfiguration = NULL;
1491 cJSON *vesDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ves-endpoint-details");
1492 if (!cJSON_IsObject(vesDetails))
1494 printf("Configuration JSON is not as expected: ves-endpoint-details is not an object");
1496 return SR_ERR_OPERATION_FAILED;
1499 cJSON *vesRegistration = cJSON_GetObjectItemCaseSensitive(vesDetails, "ves-registration");
1500 if (!cJSON_IsBool(vesRegistration))
1502 printf("Configuration JSON is not as expected: ves-registration is not a bool.");
1504 return SR_ERR_OPERATION_FAILED;
1507 //we set the value of the ves-registration object
1508 cJSON_ReplaceItemInObject(vesDetails, "ves-registration", cJSON_CreateBool(new_bool));
1510 //writing the new JSON to the configuration file
1511 stringConfiguration = cJSON_Print(jsonConfig);
1512 writeConfigFile(stringConfiguration);
1519 int is_netconf_available_changed(cJSON_bool new_bool)
1521 char *stringConfiguration = readConfigFileInString();
1523 if (stringConfiguration == NULL)
1525 printf("Could not read configuration file!\n");
1526 return SR_ERR_OPERATION_FAILED;
1529 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
1530 if (jsonConfig == NULL)
1532 free(stringConfiguration);
1533 const char *error_ptr = cJSON_GetErrorPtr();
1534 if (error_ptr != NULL)
1536 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1538 return SR_ERR_OPERATION_FAILED;
1540 //we don't need the string anymore
1541 free(stringConfiguration);
1542 stringConfiguration = NULL;
1544 cJSON *notifConfig = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
1545 if (!cJSON_IsObject(notifConfig))
1547 printf("Configuration JSON is not as expected: notification-config is not an object");
1549 return SR_ERR_OPERATION_FAILED;
1552 cJSON *isNetconfAvailable = cJSON_GetObjectItemCaseSensitive(notifConfig, "is-netconf-available");
1553 if (!cJSON_IsBool(isNetconfAvailable))
1555 printf("Configuration JSON is not as expected: is-netconf-available is not a bool.");
1557 return SR_ERR_OPERATION_FAILED;
1560 //we set the value of the ves-registration object
1561 cJSON_ReplaceItemInObject(notifConfig, "is-netconf-available", cJSON_CreateBool(new_bool));
1563 //writing the new JSON to the configuration file
1564 stringConfiguration = cJSON_Print(jsonConfig);
1565 writeConfigFile(stringConfiguration);
1572 int is_ves_available_changed(cJSON_bool new_bool)
1574 char *stringConfiguration = readConfigFileInString();
1576 if (stringConfiguration == NULL)
1578 printf("Could not read configuration file!\n");
1579 return SR_ERR_OPERATION_FAILED;
1582 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
1583 if (jsonConfig == NULL)
1585 free(stringConfiguration);
1586 const char *error_ptr = cJSON_GetErrorPtr();
1587 if (error_ptr != NULL)
1589 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1591 return SR_ERR_OPERATION_FAILED;
1593 //we don't need the string anymore
1594 free(stringConfiguration);
1595 stringConfiguration = NULL;
1597 cJSON *notifConfig = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
1598 if (!cJSON_IsObject(notifConfig))
1600 printf("Configuration JSON is not as expected: notification-config is not an object");
1602 return SR_ERR_OPERATION_FAILED;
1605 cJSON *isVesAvailable = cJSON_GetObjectItemCaseSensitive(notifConfig, "is-ves-available");
1606 if (!cJSON_IsBool(isVesAvailable))
1608 printf("Configuration JSON is not as expected: is-ves-available is not a bool.");
1610 return SR_ERR_OPERATION_FAILED;
1613 //we set the value of the ves-registration object
1614 cJSON_ReplaceItemInObject(notifConfig, "is-ves-available", cJSON_CreateBool(new_bool));
1616 //writing the new JSON to the configuration file
1617 stringConfiguration = cJSON_Print(jsonConfig);
1618 writeConfigFile(stringConfiguration);