1 /*************************************************************************
3 * Copyright 2019 highstreet technologies GmbH and others
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 ***************************************************************************/
18 #include "simulator-operations.h"
20 #include "sysrepo/values.h"
23 #include <linux/limits.h>
27 #define LINE_BUFSIZE 128
29 static CURL *curl; //share the same curl connection for communicating with the Docker Engine API
30 static CURL *curl_odl; //share the same curl connection for mounting servers in ODL
32 static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
34 size_t realsize = size * nmemb;
35 struct MemoryStruct *mem = (struct MemoryStruct *)userp;
37 char *ptr = realloc(mem->memory, mem->size + realsize + 1);
40 printf("not enough memory (realloc returned NULL)\n");
45 memcpy(&(mem->memory[mem->size]), contents, realsize);
46 mem->size += realsize;
47 mem->memory[mem->size] = 0;
52 static void set_curl_common_info()
54 struct curl_slist *chunk = NULL;
55 chunk = curl_slist_append(chunk, "Content-Type: application/json");
56 chunk = curl_slist_append(chunk, "Accept: application/json");
58 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
60 curl_easy_setopt(curl, CURLOPT_UNIX_SOCKET_PATH, "/var/run/docker.sock");
62 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
63 curl_easy_setopt(curl_odl, CURLOPT_CONNECTTIMEOUT, 2L); // seconds timeout for a connection
64 curl_easy_setopt(curl_odl, CURLOPT_TIMEOUT, 5L); //seconds timeout for an operation
66 curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
69 static void set_curl_common_info_odl()
71 struct curl_slist *chunk = NULL;
72 chunk = curl_slist_append(chunk, "Content-Type: application/xml");
73 chunk = curl_slist_append(chunk, "Accept: application/xml");
75 curl_easy_setopt(curl_odl, CURLOPT_HTTPHEADER, chunk);
77 curl_easy_setopt(curl_odl, CURLOPT_CONNECTTIMEOUT, 2L); // seconds timeout for a connection
78 curl_easy_setopt(curl_odl, CURLOPT_TIMEOUT, 5L); //seconds timeout for an operation
80 curl_easy_setopt(curl_odl, CURLOPT_VERBOSE, 1L);
83 static cJSON* get_docker_container_bindings(void)
85 struct MemoryStruct curl_response_mem;
87 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
88 curl_response_mem.size = 0; /* no data at this point */
92 curl_easy_reset(curl);
93 set_curl_common_info();
96 sprintf(url, "http:/v%s/containers/%s/json", getenv("DOCKER_ENGINE_VERSION"), getenv("HOSTNAME"));
98 curl_easy_setopt(curl, CURLOPT_URL, url);
100 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
101 curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
103 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
105 res = curl_easy_perform(curl);
113 cJSON *json_response = cJSON_Parse(curl_response_mem.memory);
115 printf("%lu bytes retrieved\n", (unsigned long)curl_response_mem.size);
117 if (json_response == NULL)
119 printf("Could not parse JSON response for url=\"%s\"\n", url);
123 cJSON *hostConfig = cJSON_GetObjectItemCaseSensitive(json_response, "HostConfig");
125 if (hostConfig == NULL)
127 printf("Could not get HostConfig object\n");
131 cJSON *binds = cJSON_GetObjectItemCaseSensitive(hostConfig, "Binds");
135 printf("Could not get Binds object\n");
139 cJSON *bindsCopy = cJSON_Duplicate(binds, 1);
141 cJSON_Delete(json_response);
149 static char* create_docker_container_curl(int base_netconf_port, cJSON* managerBinds)
151 if (managerBinds == NULL)
153 printf("Could not retrieve JSON object: Binds\n");
156 cJSON *binds = cJSON_Duplicate(managerBinds, 1);
158 struct MemoryStruct curl_response_mem;
160 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
161 curl_response_mem.size = 0; /* no data at this point */
165 curl_easy_reset(curl);
166 set_curl_common_info();
169 sprintf(url, "http:/v%s/containers/create", getenv("DOCKER_ENGINE_VERSION"));
171 // the docker image name to be used is defined in the Dockerfile of the NTS Manager,
172 // under the MODELS_IMAGE env variable
174 sprintf(models_var, "%s", getenv("MODELS_IMAGE"));
176 curl_easy_setopt(curl, CURLOPT_URL, url);
178 cJSON *postDataJson = cJSON_CreateObject();
180 if (cJSON_AddStringToObject(postDataJson, "Image", models_var) == NULL)
182 printf("Could not create JSON object: Image\n");
186 cJSON *hostConfig = cJSON_CreateObject();
187 if (hostConfig == NULL)
189 printf("Could not create JSON object: HostConfig\n");
193 cJSON_AddItemToObject(postDataJson, "HostConfig", hostConfig);
195 cJSON *portBindings = cJSON_CreateObject();
196 if (portBindings == NULL)
198 printf("Could not create JSON object: PortBindings\n");
202 cJSON_AddItemToObject(hostConfig, "PortBindings", portBindings);
204 for (int i = 0; i < NETCONF_CONNECTIONS_PER_DEVICE; ++i)
206 cJSON *port = cJSON_CreateArray();
209 printf("Could not create JSON object: port\n");
213 char dockerContainerPort[20];
214 sprintf(dockerContainerPort, "%d/tcp", 830 + i);
216 cJSON_AddItemToObject(portBindings, dockerContainerPort, port);
218 cJSON *hostPort = cJSON_CreateObject();
219 if (hostPort == NULL)
221 printf("Could not create JSON object: HostPort\n");
225 char dockerHostPort[10];
226 sprintf(dockerHostPort, "%d", base_netconf_port + i);
227 if (cJSON_AddStringToObject(hostPort, "HostPort", dockerHostPort) == NULL)
229 printf("Could not create JSON object: HostPortString\n");
232 if (cJSON_AddStringToObject(hostPort, "HostIp", getenv("NTS_IP")) == NULL)
234 printf("Could not create JSON object: HostIpString\n");
238 cJSON_AddItemToArray(port, hostPort);
241 cJSON *labels = cJSON_CreateObject();
244 printf("Could not create JSON object: Labels\n");
248 cJSON_AddItemToObject(postDataJson, "Labels", labels);
250 if (cJSON_AddStringToObject(labels, "NTS", "") == NULL)
252 printf("Could not create JSON object: NTS\n");
256 if (cJSON_AddStringToObject(labels, "NTS_Manager", getenv("HOSTNAME")) == NULL)
258 printf("Could not create JSON object: NTS Manager\n");
262 cJSON *env_variables_array = cJSON_CreateArray();
263 if (env_variables_array == NULL)
265 printf("Could not create JSON object: Env array\n");
269 cJSON_AddItemToObject(postDataJson, "Env", env_variables_array);
271 char environment_var[50];
272 sprintf(environment_var, "NTS_IP=%s", getenv("NTS_IP"));
274 cJSON *env_var_obj = cJSON_CreateString(environment_var);
275 if (env_var_obj == NULL)
277 printf("Could not create JSON object: Env array object NTS_IP\n");
280 cJSON_AddItemToArray(env_variables_array, env_var_obj);
282 sprintf(environment_var, "NETCONF_BASE=%d", base_netconf_port);
283 cJSON *env_var_obj_2 = cJSON_CreateString(environment_var);
284 if (env_var_obj_2 == NULL)
286 printf("Could not create JSON object: Env array object NETCONF_BASE\n");
289 cJSON_AddItemToArray(env_variables_array, env_var_obj_2);
291 char scripts_dir[200];
292 sprintf(scripts_dir, "SCRIPTS_DIR=%s", getenv("SCRIPTS_DIR"));
293 cJSON *env_var_obj_3 = cJSON_CreateString(scripts_dir);
294 if (env_var_obj_3 == NULL)
296 printf("Could not create JSON object: Env array object SCRIPTS_DIR\n");
299 cJSON_AddItemToArray(env_variables_array, env_var_obj_3);
301 cJSON_AddItemToObject(hostConfig, "Binds", binds);
303 char *post_data_string = NULL;
305 post_data_string = cJSON_PrintUnformatted(postDataJson);
307 printf("Post data JSON:\n%s\n", post_data_string);
309 if (postDataJson != NULL)
311 cJSON_Delete(postDataJson);
314 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data_string);
316 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
318 res = curl_easy_perform(curl);
326 cJSON *json_response = cJSON_Parse(curl_response_mem.memory);
327 const cJSON *container_id = NULL;
329 printf("%lu bytes retrieved\n", (unsigned long)curl_response_mem.size);
331 container_id = cJSON_GetObjectItemCaseSensitive(json_response, "Id");
333 if (cJSON_IsString(container_id) && (container_id->valuestring != NULL))
335 printf("Container id: \"%s\"\n", container_id->valuestring);
337 char container_id_short[13];
339 memset(container_id_short, '\0', sizeof(container_id_short));
340 strncpy(container_id_short, container_id->valuestring, 12);
342 printf("Container id short: \"%s\"\n", container_id_short);
344 cJSON_Delete(json_response);
345 return strdup(container_id_short);
348 cJSON_Delete(json_response);
354 static int start_docker_container_curl(char *container_id)
356 struct MemoryStruct curl_response_mem;
358 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
359 curl_response_mem.size = 0; /* no data at this point */
363 curl_easy_reset(curl);
364 set_curl_common_info();
367 sprintf(url, "http:/v%s/containers/%s/start", getenv("DOCKER_ENGINE_VERSION"), container_id);
369 curl_easy_setopt(curl, CURLOPT_URL, url);
371 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
373 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
375 res = curl_easy_perform(curl);
379 return SR_ERR_OPERATION_FAILED;
383 printf("Container %s started successfully!\n", container_id);
389 static int kill_and_remove_docker_container_curl(char *container_id)
391 struct MemoryStruct curl_response_mem;
393 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
394 curl_response_mem.size = 0; /* no data at this point */
398 curl_easy_reset(curl);
399 set_curl_common_info();
402 sprintf(url, "http:/v%s/containers/%s?force=true", getenv("DOCKER_ENGINE_VERSION"), container_id);
404 curl_easy_setopt(curl, CURLOPT_URL, url);
406 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
407 curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
409 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
411 res = curl_easy_perform(curl);
415 return SR_ERR_OPERATION_FAILED;
419 printf("Container %s removed successfully!\n", container_id);
425 static int send_mount_device_instance_ssh(char *url, char *credentials, char *device_name, int device_port)
429 curl_easy_reset(curl_odl);
430 set_curl_common_info_odl();
432 char url_for_curl[200];
433 sprintf(url_for_curl, "%s%s_%d", url, device_name, device_port);
435 curl_easy_setopt(curl_odl, CURLOPT_URL, url_for_curl);
437 char post_data_xml[1500];
439 sprintf(post_data_xml,
440 "<node xmlns=\"urn:TBD:params:xml:ns:yang:network-topology\">"
441 "<node-id>%s_%d</node-id>"
442 "<host xmlns=\"urn:opendaylight:netconf-node-topology\">%s</host>"
443 "<port xmlns=\"urn:opendaylight:netconf-node-topology\">%d</port>"
444 "<username xmlns=\"urn:opendaylight:netconf-node-topology\">%s</username>"
445 "<password xmlns=\"urn:opendaylight:netconf-node-topology\">%s</password>"
446 "<tcp-only xmlns=\"urn:opendaylight:netconf-node-topology\">false</tcp-only>"
447 "<keepalive-delay xmlns=\"urn:opendaylight:netconf-node-topology\">120</keepalive-delay>"
448 "<reconnect-on-changed-schema xmlns=\"urn:opendaylight:netconf-node-topology\">false</reconnect-on-changed-schema>"
449 "<sleep-factor xmlns=\"urn:opendaylight:netconf-node-topology\">1.5</sleep-factor>"
450 "<connection-timeout-millis xmlns=\"urn:opendaylight:netconf-node-topology\">20000</connection-timeout-millis>"
451 "<max-connection-attempts xmlns=\"urn:opendaylight:netconf-node-topology\">100</max-connection-attempts>"
452 "<between-attempts-timeout-millis xmlns=\"urn:opendaylight:netconf-node-topology\">2000</between-attempts-timeout-millis>"
454 device_name, device_port, getenv("NTS_IP"), device_port, "netconf", "netconf");
456 printf("Post data:\n%s\n", post_data_xml);
458 curl_easy_setopt(curl_odl, CURLOPT_POSTFIELDS, post_data_xml);
459 curl_easy_setopt(curl_odl, CURLOPT_CUSTOMREQUEST, "PUT");
460 curl_easy_setopt(curl_odl, CURLOPT_USERPWD, credentials);
462 res = curl_easy_perform(curl_odl);
465 printf("cURL failed to url=%s\n", url_for_curl);
468 long http_response_code = 0;
469 curl_easy_getinfo (curl_odl, CURLINFO_RESPONSE_CODE, &http_response_code);
470 if (http_response_code >= 200 && http_response_code <= 226 && http_response_code != CURLE_ABORTED_BY_CALLBACK)
472 printf("cURL succeeded to url=%s\n", url_for_curl);
476 printf("cURL to url=%s failed with code=%ld\n", url_for_curl, http_response_code);
477 return SR_ERR_OPERATION_FAILED;
483 static int send_mount_device_instance_tls(char *url, char *credentials, char *device_name, int device_port)
487 curl_easy_reset(curl_odl);
488 set_curl_common_info_odl();
490 char url_for_curl[200];
491 sprintf(url_for_curl, "%s%s_%d", url, device_name, device_port);
493 curl_easy_setopt(curl_odl, CURLOPT_URL, url_for_curl);
495 char post_data_xml[1500];
497 sprintf(post_data_xml,
498 "<node xmlns=\"urn:TBD:params:xml:ns:yang:network-topology\">"
499 "<protocol xmlns=\"urn:opendaylight:netconf-node-topology\">"
502 "<node-id>%s_%d</node-id>"
503 "<host xmlns=\"urn:opendaylight:netconf-node-topology\">%s</host>"
504 "<key-based xmlns=\"urn:opendaylight:netconf-node-topology\">"
505 "<username>%s</username>"
506 "<key-id>device-key</key-id>"
508 "<port xmlns=\"urn:opendaylight:netconf-node-topology\">%d</port>"
509 "<tcp-only xmlns=\"urn:opendaylight:netconf-node-topology\">false</tcp-only>"
510 "<keepalive-delay xmlns=\"urn:opendaylight:netconf-node-topology\">120</keepalive-delay>"
511 "<reconnect-on-changed-schema xmlns=\"urn:opendaylight:netconf-node-topology\">false</reconnect-on-changed-schema>"
512 "<sleep-factor xmlns=\"urn:opendaylight:netconf-node-topology\">1.5</sleep-factor>"
513 "<connection-timeout-millis xmlns=\"urn:opendaylight:netconf-node-topology\">20000</connection-timeout-millis>"
514 "<max-connection-attempts xmlns=\"urn:opendaylight:netconf-node-topology\">100</max-connection-attempts>"
515 "<between-attempts-timeout-millis xmlns=\"urn:opendaylight:netconf-node-topology\">2000</between-attempts-timeout-millis>"
517 device_name, device_port, getenv("NTS_IP"), "netconf", device_port);
519 printf("Post data:\n%s\n", post_data_xml);
521 curl_easy_setopt(curl_odl, CURLOPT_POSTFIELDS, post_data_xml);
522 curl_easy_setopt(curl_odl, CURLOPT_CUSTOMREQUEST, "PUT");
523 curl_easy_setopt(curl_odl, CURLOPT_USERPWD, credentials);
525 res = curl_easy_perform(curl_odl);
528 printf("cURL failed to url=%s\n", url_for_curl);
531 long http_response_code = 0;
532 curl_easy_getinfo (curl_odl, CURLINFO_RESPONSE_CODE, &http_response_code);
533 if (http_response_code >= 200 && http_response_code <= 226 && http_response_code != CURLE_ABORTED_BY_CALLBACK)
535 printf("cURL succeeded to url=%s\n", url_for_curl);
539 printf("cURL to url=%s failed with code=%ld\n", url_for_curl, http_response_code);
540 return SR_ERR_OPERATION_FAILED;
546 static int send_unmount_device_instance(char *url, char *credentials, char *device_name, int device_port)
550 curl_easy_reset(curl_odl);
551 set_curl_common_info_odl();
553 char url_for_curl[200];
554 sprintf(url_for_curl, "%s%s_%d", url, device_name, device_port);
556 curl_easy_setopt(curl_odl, CURLOPT_URL, url_for_curl);
558 curl_easy_setopt(curl_odl, CURLOPT_POSTFIELDS, "");
559 curl_easy_setopt(curl_odl, CURLOPT_CUSTOMREQUEST, "DELETE");
560 curl_easy_setopt(curl_odl, CURLOPT_USERPWD, credentials);
562 res = curl_easy_perform(curl_odl);
565 printf("cURL failed to url=%s\n", url_for_curl);
568 long http_response_code = 0;
569 curl_easy_getinfo (curl_odl, CURLINFO_RESPONSE_CODE, &http_response_code);
570 if (http_response_code == 200 && http_response_code != CURLE_ABORTED_BY_CALLBACK)
572 printf("cURL succeeded to url=%s\n", url_for_curl);
576 printf("cURL to url=%s failed with code=%ld\n", url_for_curl, http_response_code);
577 return SR_ERR_OPERATION_FAILED;
585 static int send_mount_device(device_t *current_device, controller_t controller_details)
588 bool is_mounted = true;
590 //This is where we hardcoded: 7 devices will have SSH connections and 3 devices will have TLS connections
591 for (int port = 0; port < NETCONF_CONNECTIONS_PER_DEVICE - 3; ++port)
593 rc = send_mount_device_instance_ssh(controller_details.url, controller_details.credentials,
594 current_device->device_id, current_device->netconf_port + port);
600 for (int port = NETCONF_CONNECTIONS_PER_DEVICE - 3; port < NETCONF_CONNECTIONS_PER_DEVICE; ++port)
602 rc = send_mount_device_instance_tls(controller_details.url, controller_details.credentials,
603 current_device->device_id, current_device->netconf_port + port);
610 current_device->is_mounted = is_mounted;
615 static int send_unmount_device(device_t *current_device, controller_t controller_details)
619 for (int port = 0; port < NETCONF_CONNECTIONS_PER_DEVICE; ++port)
621 rc = send_unmount_device_instance(controller_details.url, controller_details.credentials,
622 current_device->device_id, current_device->netconf_port + port);
625 printf("Could not send unmount for ODL with url=\"%s\", for device=\"%s\" and port=%d\n",
626 controller_details.url, current_device->device_id, current_device->netconf_port);
629 current_device->is_mounted = false;
634 device_stack_t *new_device_stack(void)
636 device_stack_t *stack = malloc(sizeof(*stack));
640 stack->stack_size = 0;
645 void push_device(device_stack_t *theStack, char *dev_id, int port)
647 device_t *new_dev = malloc(sizeof(*new_dev));
650 new_dev->device_id = strdup(dev_id);
651 new_dev->netconf_port = port;
652 new_dev->is_mounted = false;
653 new_dev->operational_state = strdup("not-specified");
655 new_dev->next = theStack->head;
657 theStack->head = new_dev;
658 theStack->stack_size++;
662 void pop_device(device_stack_t *theStack)
664 if (theStack && theStack->head) {
665 device_t *temp = theStack->head;
666 theStack->head = theStack->head->next;
668 free(temp->device_id);
669 free(temp->operational_state);
671 theStack->stack_size--;
675 int get_netconf_port_next(device_stack_t *theStack)
677 if (theStack && theStack->stack_size > 0) {
678 return theStack->head->netconf_port + NETCONF_CONNECTIONS_PER_DEVICE;
681 return get_netconf_port_base();
684 int get_netconf_port_base()
686 int netconf_port_base = 0, rc;
688 char *netconf_base_string = getenv("NETCONF_BASE");
690 if (netconf_base_string != NULL)
692 rc = sscanf(netconf_base_string, "%d", &netconf_port_base);
695 printf("Could not get the NETCONF_BASE port! Using the default 30.000...\n");
696 netconf_port_base = 30000;
700 return netconf_port_base;
704 char *get_id_last_device(device_stack_t *theStack)
706 if (theStack && theStack->head) {
707 return theStack->head->device_id;
712 int get_current_number_of_mounted_devices(device_stack_t *theStack)
714 int mounted_devices = 0;
716 if (theStack && theStack->head)
718 device_t *current_device = theStack->head;
720 while (current_device != NULL)
722 if (current_device->is_mounted)
726 current_device = current_device->next;
730 return mounted_devices;
733 int get_current_number_of_devices(device_stack_t *theStack)
735 struct MemoryStruct curl_response_mem;
737 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
738 curl_response_mem.size = 0; /* no data at this point */
742 curl_easy_reset(curl);
743 set_curl_common_info();
746 sprintf(url, "http:/v%s/containers/json?all=true&filters={\"label\":[\"NTS\"],\"status\":[\"running\"]}",
747 getenv("DOCKER_ENGINE_VERSION"));
749 curl_easy_setopt(curl, CURLOPT_URL, url);
751 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
752 curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
754 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
756 res = curl_easy_perform(curl);
760 return SR_ERR_OPERATION_FAILED;
764 cJSON *json_response = cJSON_Parse(curl_response_mem.memory);
766 printf("%lu bytes retrieved\n", (unsigned long)curl_response_mem.size);
768 if (json_response == NULL || !cJSON_IsArray(json_response))
770 printf("Could not parse JSON response for url=\"%s\"\n", url);
771 return SR_ERR_OPERATION_FAILED;
774 int num_of_devices = cJSON_GetArraySize(json_response);
775 cJSON_Delete(json_response);
777 return num_of_devices;
783 static int set_operational_state_of_device(device_stack_t *theStack, char *device_id, char *operational_state)
785 if (theStack && theStack->head)
787 device_t *current_device = theStack->head;
789 while (current_device != NULL)
791 if (strcmp(current_device->device_id, device_id) == 0)
793 free(current_device->operational_state);
794 current_device->operational_state = strdup(operational_state);
799 current_device = current_device->next;
803 printf("Could not find device with uuid=\"%s\"\n", device_id);
804 return SR_ERR_OPERATION_FAILED;
807 char* get_docker_container_operational_state(device_stack_t *theStack, char *container_id)
809 if (theStack && theStack->head)
811 device_t *current_device = theStack->head;
813 while (current_device != NULL)
815 if (strcmp(current_device->device_id, container_id) == 0)
817 return current_device->operational_state;
820 current_device = current_device->next;
827 int start_device(device_stack_t *theStack)
830 static cJSON* managerBindings = NULL;
832 if (managerBindings == NULL)
834 managerBindings = get_docker_container_bindings();
837 int netconf_base = get_netconf_port_next(theStack);
839 char *dev_id = create_docker_container_curl(netconf_base, managerBindings);
841 push_device(theStack, dev_id, netconf_base);
843 rc = start_docker_container_curl(dev_id);
846 printf("Could not start device with device_id=\"%s\"\n", dev_id);
858 curl = curl_easy_init();
861 printf("cURL initialization error! Aborting call!\n");
862 return SR_ERR_OPERATION_FAILED;
872 curl_easy_cleanup(curl);
880 curl_odl = curl_easy_init();
882 if (curl_odl == NULL) {
883 printf("cURL initialization error! Aborting call!\n");
884 return SR_ERR_OPERATION_FAILED;
890 int cleanup_curl_odl()
892 if (curl_odl != NULL)
894 curl_easy_cleanup(curl_odl);
900 int stop_device(device_stack_t *theStack)
903 char *last_id = get_id_last_device(theStack);
905 rc = kill_and_remove_docker_container_curl(last_id);
908 printf("Could not kill and remove docker container with uuid=\"%s\"\n", last_id);
911 rc = removeDeviceEntryFromStatusFile(last_id);
914 printf("Could not remove entry from status file for uuid=\"%s\"\n", last_id);
917 pop_device(theStack);
922 int mount_device(device_stack_t *theStack, controller_t controller_details)
926 if (theStack && theStack->head)
928 device_t *current_device = theStack->head;
929 while (current_device != NULL && current_device->is_mounted == true)
931 printf("Device \"%s\" is already mounted, skipping...\n", current_device->device_id);
932 current_device = current_device->next;
935 if (current_device != NULL)
937 printf("Sending mount device for device \"%s\"...\n", current_device->device_id);
938 rc = send_mount_device(current_device, controller_details);
941 return SR_ERR_OPERATION_FAILED;
949 int unmount_device(device_stack_t *theStack, controller_t controller_list)
953 if (theStack && theStack->head)
955 device_t *current_device = theStack->head;
956 while (current_device != NULL && current_device->is_mounted == false)
958 printf("Device \"%s\" is already unmounted, skipping...\n", current_device->device_id);
959 current_device = current_device->next;
962 if (current_device != NULL)
964 printf("Sending unmount device for device \"%s\"...\n", current_device->device_id);
965 rc = send_unmount_device(current_device, controller_list);
968 return SR_ERR_OPERATION_FAILED;
976 int get_docker_containers_operational_state_curl(device_stack_t *theStack)
979 struct MemoryStruct curl_response_mem;
981 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
982 curl_response_mem.size = 0; /* no data at this point */
986 curl_easy_reset(curl);
987 set_curl_common_info();
990 sprintf(url, "http:/v%s/containers/json?all=true&filters={\"label\":[\"NTS\"]}", getenv("DOCKER_ENGINE_VERSION"));
992 curl_easy_setopt(curl, CURLOPT_URL, url);
994 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
995 curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
997 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
999 res = curl_easy_perform(curl);
1001 if (res != CURLE_OK)
1003 return SR_ERR_OPERATION_FAILED;
1007 cJSON *json_response = cJSON_Parse(curl_response_mem.memory);
1008 const cJSON *container = NULL;
1010 printf("%lu bytes retrieved\n", (unsigned long)curl_response_mem.size);
1012 if (json_response == NULL || !cJSON_IsArray(json_response))
1014 printf("Could not parse JSON response for url=\"%s\"\n", url);
1015 return SR_ERR_OPERATION_FAILED;
1018 cJSON_ArrayForEach(container, json_response)
1020 cJSON *container_id_long = cJSON_GetObjectItemCaseSensitive(container, "Id");
1021 cJSON *state = cJSON_GetObjectItemCaseSensitive(container, "State");
1023 if (cJSON_IsString(container_id_long) && (container_id_long->valuestring != NULL))
1025 char container_id_short[13];
1027 memset(container_id_short, '\0', sizeof(container_id_short));
1028 strncpy(container_id_short, container_id_long->valuestring, 12);
1030 if (cJSON_IsString(state) && (state->valuestring != NULL))
1032 rc = set_operational_state_of_device(theStack, container_id_short, state->valuestring);
1033 if (rc != SR_ERR_OK)
1035 printf("Could not set the operational state for the device with uuid=\"%s\"\n", container_id_short);
1036 return SR_ERR_OPERATION_FAILED;
1042 cJSON_Delete(json_response);
1048 char* get_docker_container_resource_stats(device_stack_t *theStack)
1050 char line[LINE_BUFSIZE];
1054 /* Get a pipe where the output from the scripts comes in */
1056 sprintf(script, "%s/docker_stats.sh", getenv("SCRIPTS_DIR"));
1058 pipe = popen(script, "r");
1059 if (pipe == NULL) { /* check for errors */
1060 printf("Could not open script.\n");
1061 return NULL; /* return with exit code indicating error */
1064 /* Read script output from the pipe line by line */
1066 while (fgets(line, LINE_BUFSIZE, pipe) != NULL) {
1067 printf("Script output line %d: %s", linenr, line);
1070 pclose(pipe); /* Close the pipe */
1071 return strdup(line);
1074 /* Once here, out of the loop, the script has ended. */
1075 pclose(pipe); /* Close the pipe */
1076 return NULL; /* return with exit code indicating success. */
1079 int notification_delay_period_changed(sr_val_t *val, size_t count)
1081 char *stringConfiguration = readConfigFileInString();
1083 if (stringConfiguration == NULL)
1085 printf("Could not read configuration file!\n");
1086 return SR_ERR_OPERATION_FAILED;
1089 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
1090 if (jsonConfig == NULL)
1092 free(stringConfiguration);
1093 const char *error_ptr = cJSON_GetErrorPtr();
1094 if (error_ptr != NULL)
1096 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1098 return SR_ERR_OPERATION_FAILED;
1100 //we don't need the string anymore
1101 free(stringConfiguration);
1102 stringConfiguration = NULL;
1104 cJSON *notifConfig = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
1105 if (!cJSON_IsObject(notifConfig))
1107 printf("Configuration JSON is not as expected: notification-config is not an object");
1108 cJSON_Delete(jsonConfig);
1109 return SR_ERR_OPERATION_FAILED;
1112 cJSON *faultNotifDelay = cJSON_GetObjectItemCaseSensitive(notifConfig, "fault-notification-delay-period");
1113 if (!cJSON_IsArray(faultNotifDelay))
1115 printf("Configuration JSON is not as expected: fault-notification-delay-period is not an array.");
1116 cJSON_Delete(jsonConfig);
1117 return SR_ERR_OPERATION_FAILED;
1120 cJSON_DeleteItemFromObject(notifConfig, "fault-notification-delay-period");
1122 faultNotifDelay = NULL;
1124 faultNotifDelay = cJSON_CreateArray();
1125 if (faultNotifDelay == NULL)
1127 cJSON_Delete(jsonConfig);
1128 return SR_ERR_OPERATION_FAILED;
1130 cJSON_AddItemToObject(notifConfig, "fault-notification-delay-period", faultNotifDelay);
1132 if (val != NULL && count > 0)
1134 cJSON *arrayEntry = NULL;
1135 for (size_t i=0; i<count; ++i)
1137 arrayEntry = cJSON_CreateNumber(val[i].data.uint32_val);
1138 if (arrayEntry == NULL)
1140 cJSON_Delete(jsonConfig);
1141 return SR_ERR_OPERATION_FAILED;
1143 cJSON_AddItemToArray(faultNotifDelay, arrayEntry);
1148 cJSON *arrayEntry = cJSON_CreateNumber(0);
1149 if (arrayEntry == NULL)
1151 cJSON_Delete(jsonConfig);
1152 return SR_ERR_OPERATION_FAILED;
1154 cJSON_AddItemToArray(faultNotifDelay, arrayEntry);
1157 //writing the new JSON to the configuration file
1158 stringConfiguration = cJSON_Print(jsonConfig);
1159 writeConfigFile(stringConfiguration);
1161 cJSON_Delete(jsonConfig);
1166 int ves_heartbeat_period_changed(int period)
1168 char *stringConfiguration = readConfigFileInString();
1170 if (stringConfiguration == NULL)
1172 printf("Could not read configuration file!\n");
1173 return SR_ERR_OPERATION_FAILED;
1176 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
1177 if (jsonConfig == NULL)
1179 free(stringConfiguration);
1180 const char *error_ptr = cJSON_GetErrorPtr();
1181 if (error_ptr != NULL)
1183 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1185 return SR_ERR_OPERATION_FAILED;
1187 //we don't need the string anymore
1188 free(stringConfiguration);
1189 stringConfiguration = NULL;
1191 cJSON *notifConfig = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
1192 if (!cJSON_IsObject(notifConfig))
1194 printf("Configuration JSON is not as expected: notification-config is not an object");
1195 cJSON_Delete(jsonConfig);
1196 return SR_ERR_OPERATION_FAILED;
1199 cJSON *vesHeartbeatPeriod = cJSON_GetObjectItemCaseSensitive(notifConfig, "ves-heartbeat-period");
1200 if (!cJSON_IsNumber(vesHeartbeatPeriod))
1202 printf("Configuration JSON is not as expected: ves-heartbeat-period is not an object");
1203 cJSON_Delete(jsonConfig);
1204 return SR_ERR_OPERATION_FAILED;
1207 //we set the value of the fault-notification-delay-period object
1208 cJSON_SetNumberValue(vesHeartbeatPeriod, period);
1210 //writing the new JSON to the configuration file
1211 stringConfiguration = cJSON_Print(jsonConfig);
1212 writeConfigFile(stringConfiguration);
1214 cJSON_Delete(jsonConfig);
1219 static int add_keystore_entry_odl(char *url, char *credentials)
1223 curl_easy_reset(curl_odl);
1224 set_curl_common_info_odl();
1226 char url_for_curl[200];
1227 sprintf(url_for_curl, "%s", url);
1229 curl_easy_setopt(curl_odl, CURLOPT_URL, url_for_curl);
1231 char post_data_xml[2000];
1233 sprintf(post_data_xml,
1234 "<input xmlns=\"urn:opendaylight:netconf:keystore\">"
1236 "<key-id>device-key</key-id>"
1237 "<private-key>MIIEpAIBAAKCAQEAueCQaNQWoNmFK6LKu1p8U8ZWdWg/PvDdLsJyzfzl/Qw4UA68"
1238 "SfFNaY06zZl8QB9W02nr5kWeeMY0VA3adrPgOlvfx3oWlFbkETnMaN4OT3WTQ0Wt"
1239 "6jAWZDzVfopwpJPAzRPxACDftIqFGagYcF32hZlVNqqnVdbXh0S0EViweqp/dbG4"
1240 "VDUHSNVbglc+u4UbEzNIFXMdEFsJZpkynOmSiTsIATqIhb+2srkVgLwhfkC2qkuH"
1241 "QwAHdubuB07ObM2z01UhyEdDvEYGHwtYAGDBL2TAcsI0oGeVkRyuOkV0QY0UN7UE"
1242 "FI1yTYw+xZ42HgFx3uGwApCImxhbj69GBYWFqwIDAQABAoIBAQCZN9kR8DGu6V7y"
1243 "t0Ax68asL8O5B/OKaHWKQ9LqpVrXmikZJOxkbzoGldow/CIFoU+q+Zbwu9aDa65a"
1244 "0wiP7Hoa4Py3q5XNNUrOQDyU/OYC7cI0I83WS0lJ2zOJGYj8wKae5Z81IeQFKGHK"
1245 "4lsy1OGPAvPRGh7RjUUgRavA2MCwe07rWRuDb/OJFe4Oh56UMEjwMiNBtMNtncog"
1246 "j1vr/qgRJdf9tf0zlJmLvUJ9+HSFFV9I/97LJyFhb95gAfHkjdVroLVgT3Cho+4P"
1247 "WtZaKCIGD0OwfOG2nLV4leXvRUk62/LMlB8NI9+JF7Xm+HCKbaWHNWC7mvWSLV58"
1248 "Zl4AbUWRAoGBANyJ6SFHFRHSPDY026SsdMzXR0eUxBAK7G70oSBKKhY+O1j0ocLE"
1249 "jI2krHJBhHbLlnvJVyMUaCUOTS5m0uDw9hgSsAqeSL3hL38kxVZw+KNG9Ouno1Fl"
1250 "KnE/xXHlPQyeGs/P8nAMzHZxQtEsQdQayJEhK2XXHTsy7Q3MxDisfVJ1AoGBANfD"
1251 "34gB+OMx6pwj7zk3qWbYXSX8xjCZMR0ciko+h4xeMP2N8B0oyoqC+v1ABMAtJ3wG"
1252 "sGZd0hV9gwM7OUM3SEwkn6oeg1GemWLcn4rlSmTnZc4aeVwrEWlnSNFX3s4g9l4u"
1253 "k8Ugu4MVJYqH8HuDQ5Ggl6/QAwPzMSEdCW0O+jOfAoGAIBRbegC5+t6m7Yegz4Ja"
1254 "dxV1g98K6f58x+MDsQu4tYWV4mmrQgaPH2dtwizvlMwmdpkh+LNWNtWuumowkJHc"
1255 "akIFo3XExQIFg6wYnGtQb4e5xrGa2xMpKlIJaXjb+YLiCYqJDG2ALFZrTrvuU2kV"
1256 "9a5qfqTc1qigvNolTM0iaaUCgYApmrZWhnLUdEKV2wP813PNxfioI4afxlpHD8LG"
1257 "sCn48gymR6E+Lihn7vuwq5B+8fYEH1ISWxLwW+RQUjIneNhy/jjfV8TgjyFqg7or"
1258 "0Sy4KjpiNI6kLBXOakELRNNMkeSPopGR2E7v5rr3bGD9oAD+aqX1G7oJH/KgPPYd"
1259 "Vl7+ZwKBgQDcHyWYrimjyUgKaQD2GmoO9wdcJYQ59ke9K+OuGlp4ti5arsi7N1tP"
1260 "B4f09aeELM2ASIuk8Q/Mx0jQFnm8lzRFXdewgvdPoZW/7VufM9O7dGPOc41cm2Dh"
1261 "yrTcXx/VmUBb+/fnXVEgCv7gylp/wtdTGHQBQJHR81jFBz0lnLj+gg==</private-key>"
1262 "<passphrase></passphrase>"
1266 printf("Post data:\n%s\n", post_data_xml);
1268 curl_easy_setopt(curl_odl, CURLOPT_POSTFIELDS, post_data_xml);
1269 curl_easy_setopt(curl_odl, CURLOPT_CUSTOMREQUEST, "POST");
1270 curl_easy_setopt(curl_odl, CURLOPT_USERPWD, credentials);
1272 res = curl_easy_perform(curl_odl);
1273 if (res != CURLE_OK)
1275 printf("cURL failed to url=%s\n", url_for_curl);
1278 long http_response_code = 0;
1279 curl_easy_getinfo (curl_odl, CURLINFO_RESPONSE_CODE, &http_response_code);
1280 if (http_response_code >= 200 && http_response_code <= 226 && http_response_code != CURLE_ABORTED_BY_CALLBACK)
1282 printf("cURL succeeded to url=%s\n", url_for_curl);
1286 printf("cURL to url=%s failed with code=%ld\n", url_for_curl, http_response_code);
1287 return SR_ERR_OPERATION_FAILED;
1293 static int add_private_key_odl(char *url, char *credentials)
1297 curl_easy_reset(curl_odl);
1298 set_curl_common_info_odl();
1300 char url_for_curl[200];
1301 sprintf(url_for_curl, "%s", url);
1303 curl_easy_setopt(curl_odl, CURLOPT_URL, url_for_curl);
1305 char post_data_xml[4000];
1307 sprintf(post_data_xml,
1308 "<input xmlns=\"urn:opendaylight:netconf:keystore\">"
1310 "<name>device-key</name>"
1311 "<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>"
1312 "<certificate-chain>MIIECTCCAvGgAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBjDELMAkGA1UEBhMCQ1oxFjAUBgNVBAgMDVNvdXRoIE1vcmF2aWExDTALBgNVBAcMBEJybm8xDzANBgNVBAoMBkNFU05FVDEMMAoGA1UECwwDVE1DMRMwEQYDVQQDDApleGFtcGxlIENBMSIwIAYJKoZIhvcNAQkBFhNleGFtcGxlY2FAbG9jYWxob3N0MB4XDTE1MDczMDA3MjcxOFoXDTM1MDcyNTA3MjcxOFowgYUxCzAJBgNVBAYTAkNaMRYwFAYDVQQIDA1Tb3V0aCBNb3JhdmlhMQ8wDQYDVQQKDAZDRVNORVQxDDAKBgNVBAsMA1RNQzEXMBUGA1UEAwwOZXhhbXBsZSBjbGllbnQxJjAkBgkqhkiG9w0BCQEWF2V4YW1wbGVjbGllbnRAbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAueCQaNQWoNmFK6LKu1p8U8ZWdWg/PvDdLsJyzfzl/Qw4UA68SfFNaY06zZl8QB9W02nr5kWeeMY0VA3adrPgOlvfx3oWlFbkETnMaN4OT3WTQ0Wt6jAWZDzVfopwpJPAzRPxACDftIqFGagYcF32hZlVNqqnVdbXh0S0EViweqp/dbG4VDUHSNVbglc+u4UbEzNIFXMdEFsJZpkynOmSiTsIATqIhb+2srkVgLwhfkC2qkuHQwAHdubuB07ObM2z01UhyEdDvEYGHwtYAGDBL2TAcsI0oGeVkRyuOkV0QY0UN7UEFI1yTYw+xZ42HgFx3uGwApCImxhbj69GBYWFqwIDAQABo3sweTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUXGpLeLnh2cSDARAVA7KrBxGYpo8wHwYDVR0jBBgwFoAUc1YQIqjZsHVwlea0AB4N+ilNI2gwDQYJKoZIhvcNAQELBQADggEBAJPV3RTXFRtNyOU4rjPpYeBAIAFp2aqGc4t2J1c7oPp/1n+lZvjnwtlJpZHxMM783e2ryDQ6dkvXDf8kpwKlg3U3mkJ3xKkDdWrM4QwghXdCN519aa9qmu0zdFL+jUAaWlQ5tsceOrvbusCcbMqiFGk/QfpHqPv52SVWbYyUx7IX7DE+UjgsLHycfV/tlcx4ZE6soTzl9VdgSL/zmzG3rjsr58J80rXckLgBhvijgBlIAJvWfC7D0vaouvBInSFXymdPVoUDZ30cdGLf+hI/i/TfsEMOinLrXVdkSGNo6FXAHKSvXeB9oFKSzhQ7OPyRyqvEPycUSw/qD6FVr80oDDc=</certificate-chain>"
1316 printf("Post data:\n%s\n", post_data_xml);
1318 curl_easy_setopt(curl_odl, CURLOPT_POSTFIELDS, post_data_xml);
1319 curl_easy_setopt(curl_odl, CURLOPT_CUSTOMREQUEST, "POST");
1320 curl_easy_setopt(curl_odl, CURLOPT_USERPWD, credentials);
1322 res = curl_easy_perform(curl_odl);
1323 if (res != CURLE_OK)
1325 printf("cURL failed to url=%s\n", url_for_curl);
1328 long http_response_code = 0;
1329 curl_easy_getinfo (curl_odl, CURLINFO_RESPONSE_CODE, &http_response_code);
1330 if (http_response_code >= 200 && http_response_code <= 226 && http_response_code != CURLE_ABORTED_BY_CALLBACK)
1332 printf("cURL succeeded to url=%s\n", url_for_curl);
1336 printf("cURL to url=%s failed with code=%ld\n", url_for_curl, http_response_code);
1337 return SR_ERR_OPERATION_FAILED;
1343 static int add_trusted_ca_odl(char *url, char *credentials)
1347 curl_easy_reset(curl_odl);
1348 set_curl_common_info_odl();
1350 char url_for_curl[200];
1351 sprintf(url_for_curl, "%s", url);
1353 curl_easy_setopt(curl_odl, CURLOPT_URL, url_for_curl);
1355 char post_data_xml[2000];
1357 sprintf(post_data_xml,
1358 "<input xmlns=\"urn:opendaylight:netconf:keystore\">"
1359 "<trusted-certificate>"
1360 "<name>test_trusted_cert</name>"
1361 "<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>"
1362 "</trusted-certificate>"
1365 printf("Post data:\n%s\n", post_data_xml);
1367 curl_easy_setopt(curl_odl, CURLOPT_POSTFIELDS, post_data_xml);
1368 curl_easy_setopt(curl_odl, CURLOPT_CUSTOMREQUEST, "POST");
1369 curl_easy_setopt(curl_odl, CURLOPT_USERPWD, credentials);
1371 res = curl_easy_perform(curl_odl);
1372 if (res != CURLE_OK)
1374 printf("cURL failed to url=%s\n", url_for_curl);
1377 long http_response_code = 0;
1378 curl_easy_getinfo (curl_odl, CURLINFO_RESPONSE_CODE, &http_response_code);
1379 if (http_response_code >= 200 && http_response_code <= 226 && http_response_code != CURLE_ABORTED_BY_CALLBACK)
1381 printf("cURL succeeded to url=%s\n", url_for_curl);
1385 printf("cURL to url=%s failed with code=%ld\n", url_for_curl, http_response_code);
1386 return SR_ERR_OPERATION_FAILED;
1392 int add_key_pair_to_odl(controller_t *controller_list, int controller_list_size)
1396 rc = add_keystore_entry_odl(controller_list[0].url_for_keystore_add, controller_list[0].credentials);
1397 if (rc != SR_ERR_OK)
1399 printf("Failed to add keystore entry to ODL.\n");
1402 rc = add_private_key_odl(controller_list[0].url_for_private_key_add, controller_list[0].credentials);
1403 if (rc != SR_ERR_OK)
1405 printf("Failed to add private key entry to ODL.\n");
1408 rc = add_trusted_ca_odl(controller_list[0].url_for_trusted_ca_add, controller_list[0].credentials);
1409 if (rc != SR_ERR_OK)
1411 printf("Failed to add trusted CA entry to ODL.\n");
1417 int ves_ip_changed(char *new_ip)
1419 char *stringConfiguration = readConfigFileInString();
1421 if (stringConfiguration == NULL)
1423 printf("Could not read configuration file!\n");
1424 return SR_ERR_OPERATION_FAILED;
1427 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
1428 if (jsonConfig == NULL)
1430 free(stringConfiguration);
1431 const char *error_ptr = cJSON_GetErrorPtr();
1432 if (error_ptr != NULL)
1434 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1436 return SR_ERR_OPERATION_FAILED;
1438 //we don't need the string anymore
1439 free(stringConfiguration);
1440 stringConfiguration = NULL;
1442 cJSON *vesDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ves-endpoint-details");
1443 if (!cJSON_IsObject(vesDetails))
1445 printf("Configuration JSON is not as expected: ves-endpoint-details is not an object");
1446 cJSON_Delete(jsonConfig);
1447 return SR_ERR_OPERATION_FAILED;
1450 cJSON *vesIp = cJSON_GetObjectItemCaseSensitive(vesDetails, "ves-endpoint-ip");
1451 if (!cJSON_IsString(vesIp))
1453 printf("Configuration JSON is not as expected: ves-endpoint-ip is not a string");
1454 cJSON_Delete(jsonConfig);
1455 return SR_ERR_OPERATION_FAILED;
1458 //we set the value of the fault-notification-delay-period object
1459 cJSON_ReplaceItemInObject(vesDetails, "ves-endpoint-ip", cJSON_CreateString(new_ip));
1461 //writing the new JSON to the configuration file
1462 stringConfiguration = cJSON_Print(jsonConfig);
1463 writeConfigFile(stringConfiguration);
1465 cJSON_Delete(jsonConfig);
1470 int ves_port_changed(int new_port)
1472 char *stringConfiguration = readConfigFileInString();
1474 if (stringConfiguration == NULL)
1476 printf("Could not read configuration file!\n");
1477 return SR_ERR_OPERATION_FAILED;
1480 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
1481 if (jsonConfig == NULL)
1483 free(stringConfiguration);
1484 const char *error_ptr = cJSON_GetErrorPtr();
1485 if (error_ptr != NULL)
1487 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1489 return SR_ERR_OPERATION_FAILED;
1491 //we don't need the string anymore
1492 free(stringConfiguration);
1493 stringConfiguration = NULL;
1495 cJSON *vesDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ves-endpoint-details");
1496 if (!cJSON_IsObject(vesDetails))
1498 printf("Configuration JSON is not as expected: ves-endpoint-details is not an object");
1499 cJSON_Delete(jsonConfig);
1500 return SR_ERR_OPERATION_FAILED;
1503 cJSON *vesPort = cJSON_GetObjectItemCaseSensitive(vesDetails, "ves-endpoint-port");
1504 if (!cJSON_IsNumber(vesPort))
1506 printf("Configuration JSON is not as expected: ves-endpoint-port is not a number.");
1507 cJSON_Delete(jsonConfig);
1508 return SR_ERR_OPERATION_FAILED;
1511 //we set the value of the fault-notification-delay-period object
1512 cJSON_SetNumberValue(vesPort, new_port);
1514 //writing the new JSON to the configuration file
1515 stringConfiguration = cJSON_Print(jsonConfig);
1516 writeConfigFile(stringConfiguration);
1518 cJSON_Delete(jsonConfig);
1523 int ves_registration_changed(cJSON_bool new_bool)
1525 char *stringConfiguration = readConfigFileInString();
1527 if (stringConfiguration == NULL)
1529 printf("Could not read configuration file!\n");
1530 return SR_ERR_OPERATION_FAILED;
1533 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
1534 if (jsonConfig == NULL)
1536 free(stringConfiguration);
1537 const char *error_ptr = cJSON_GetErrorPtr();
1538 if (error_ptr != NULL)
1540 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1542 return SR_ERR_OPERATION_FAILED;
1544 //we don't need the string anymore
1545 free(stringConfiguration);
1546 stringConfiguration = NULL;
1548 cJSON *vesDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ves-endpoint-details");
1549 if (!cJSON_IsObject(vesDetails))
1551 printf("Configuration JSON is not as expected: ves-endpoint-details is not an object");
1552 cJSON_Delete(jsonConfig);
1553 return SR_ERR_OPERATION_FAILED;
1556 cJSON *vesRegistration = cJSON_GetObjectItemCaseSensitive(vesDetails, "ves-registration");
1557 if (!cJSON_IsBool(vesRegistration))
1559 printf("Configuration JSON is not as expected: ves-registration is not a bool.");
1560 cJSON_Delete(jsonConfig);
1561 return SR_ERR_OPERATION_FAILED;
1564 //we set the value of the ves-registration object
1565 cJSON_ReplaceItemInObject(vesDetails, "ves-registration", cJSON_CreateBool(new_bool));
1567 //writing the new JSON to the configuration file
1568 stringConfiguration = cJSON_Print(jsonConfig);
1569 writeConfigFile(stringConfiguration);
1571 cJSON_Delete(jsonConfig);
1576 int is_netconf_available_changed(cJSON_bool new_bool)
1578 char *stringConfiguration = readConfigFileInString();
1580 if (stringConfiguration == NULL)
1582 printf("Could not read configuration file!\n");
1583 return SR_ERR_OPERATION_FAILED;
1586 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
1587 if (jsonConfig == NULL)
1589 free(stringConfiguration);
1590 const char *error_ptr = cJSON_GetErrorPtr();
1591 if (error_ptr != NULL)
1593 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1595 return SR_ERR_OPERATION_FAILED;
1597 //we don't need the string anymore
1598 free(stringConfiguration);
1599 stringConfiguration = NULL;
1601 cJSON *notifConfig = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
1602 if (!cJSON_IsObject(notifConfig))
1604 printf("Configuration JSON is not as expected: notification-config is not an object");
1605 cJSON_Delete(jsonConfig);
1606 return SR_ERR_OPERATION_FAILED;
1609 cJSON *isNetconfAvailable = cJSON_GetObjectItemCaseSensitive(notifConfig, "is-netconf-available");
1610 if (!cJSON_IsBool(isNetconfAvailable))
1612 printf("Configuration JSON is not as expected: is-netconf-available is not a bool.");
1613 cJSON_Delete(jsonConfig);
1614 return SR_ERR_OPERATION_FAILED;
1617 //we set the value of the ves-registration object
1618 cJSON_ReplaceItemInObject(notifConfig, "is-netconf-available", cJSON_CreateBool(new_bool));
1620 //writing the new JSON to the configuration file
1621 stringConfiguration = cJSON_Print(jsonConfig);
1622 writeConfigFile(stringConfiguration);
1624 cJSON_Delete(jsonConfig);
1629 int is_ves_available_changed(cJSON_bool new_bool)
1631 char *stringConfiguration = readConfigFileInString();
1633 if (stringConfiguration == NULL)
1635 printf("Could not read configuration file!\n");
1636 return SR_ERR_OPERATION_FAILED;
1639 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
1640 if (jsonConfig == NULL)
1642 free(stringConfiguration);
1643 const char *error_ptr = cJSON_GetErrorPtr();
1644 if (error_ptr != NULL)
1646 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1648 return SR_ERR_OPERATION_FAILED;
1650 //we don't need the string anymore
1651 free(stringConfiguration);
1652 stringConfiguration = NULL;
1654 cJSON *notifConfig = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
1655 if (!cJSON_IsObject(notifConfig))
1657 printf("Configuration JSON is not as expected: notification-config is not an object");
1658 cJSON_Delete(jsonConfig);
1659 return SR_ERR_OPERATION_FAILED;
1662 cJSON *isVesAvailable = cJSON_GetObjectItemCaseSensitive(notifConfig, "is-ves-available");
1663 if (!cJSON_IsBool(isVesAvailable))
1665 printf("Configuration JSON is not as expected: is-ves-available is not a bool.");
1666 cJSON_Delete(jsonConfig);
1667 return SR_ERR_OPERATION_FAILED;
1670 //we set the value of the ves-registration object
1671 cJSON_ReplaceItemInObject(notifConfig, "is-ves-available", cJSON_CreateBool(new_bool));
1673 //writing the new JSON to the configuration file
1674 stringConfiguration = cJSON_Print(jsonConfig);
1675 writeConfigFile(stringConfiguration);
1677 cJSON_Delete(jsonConfig);