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>
28 #define LINE_BUFSIZE 128
30 static CURL *curl; //share the same curl connection for communicating with the Docker Engine API
31 static CURL *curl_odl; //share the same curl connection for mounting servers in ODL
32 static CURL *curl_k8s; //share the same curl connection for communicating with the K8S cluster
35 curl -X POST -H 'Content-Type: application/json' -i http://localhost:5000/scale --data '{"simulatedDevices":2}'
38 static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
40 size_t realsize = size * nmemb;
41 struct MemoryStruct *mem = (struct MemoryStruct *)userp;
43 char *ptr = realloc(mem->memory, mem->size + realsize + 1);
46 printf("not enough memory (realloc returned NULL)\n");
51 memcpy(&(mem->memory[mem->size]), contents, realsize);
52 mem->size += realsize;
53 mem->memory[mem->size] = 0;
58 static void set_curl_common_info()
60 struct curl_slist *chunk = NULL;
61 chunk = curl_slist_append(chunk, "Content-Type: application/json");
62 chunk = curl_slist_append(chunk, "Accept: application/json");
64 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
66 curl_easy_setopt(curl, CURLOPT_UNIX_SOCKET_PATH, "/var/run/docker.sock");
68 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
69 curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 2L); // seconds timeout for a connection
70 curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L); //seconds timeout for an operation
72 curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
75 static void set_curl_common_info_odl()
77 struct curl_slist *chunk = NULL;
78 chunk = curl_slist_append(chunk, "Content-Type: application/xml");
79 chunk = curl_slist_append(chunk, "Accept: application/xml");
81 curl_easy_setopt(curl_odl, CURLOPT_HTTPHEADER, chunk);
83 curl_easy_setopt(curl_odl, CURLOPT_CONNECTTIMEOUT, 2L); // seconds timeout for a connection
84 curl_easy_setopt(curl_odl, CURLOPT_TIMEOUT, 10L); //seconds timeout for an operation
86 curl_easy_setopt(curl_odl, CURLOPT_VERBOSE, 1L);
89 static void set_curl_common_info_k8s()
91 struct curl_slist *chunk = NULL;
92 chunk = curl_slist_append(chunk, "Content-Type: application/json");
93 chunk = curl_slist_append(chunk, "Accept: application/json");
95 curl_easy_setopt(curl_k8s, CURLOPT_HTTPHEADER, chunk);
97 curl_easy_setopt(curl_k8s, CURLOPT_CONNECTTIMEOUT, 2L); // seconds timeout for a connection
98 curl_easy_setopt(curl_k8s, CURLOPT_TIMEOUT, 10L); //seconds timeout for an operation
100 curl_easy_setopt(curl_k8s, CURLOPT_VERBOSE, 1L);
103 static cJSON* get_docker_container_bindings(void)
105 struct MemoryStruct curl_response_mem;
107 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
108 curl_response_mem.size = 0; /* no data at this point */
112 curl_easy_reset(curl);
113 set_curl_common_info();
116 sprintf(url, "http:/v%s/containers/%s/json", getenv("DOCKER_ENGINE_VERSION"), getenv("HOSTNAME"));
118 curl_easy_setopt(curl, CURLOPT_URL, url);
120 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
121 curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
123 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
125 res = curl_easy_perform(curl);
133 cJSON *json_response = cJSON_Parse(curl_response_mem.memory);
135 printf("%lu bytes retrieved\n", (unsigned long)curl_response_mem.size);
137 if (json_response == NULL)
139 printf("Could not parse JSON response for url=\"%s\"\n", url);
143 cJSON *hostConfig = cJSON_GetObjectItemCaseSensitive(json_response, "HostConfig");
145 if (hostConfig == NULL)
147 printf("Could not get HostConfig object\n");
151 cJSON *binds = cJSON_GetObjectItemCaseSensitive(hostConfig, "Binds");
155 printf("Could not get Binds object\n");
159 cJSON *bindsCopy = cJSON_Duplicate(binds, 1);
161 cJSON_Delete(json_response);
169 static cJSON* get_docker_container_network_node(void)
171 struct MemoryStruct curl_response_mem;
173 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
174 curl_response_mem.size = 0; /* no data at this point */
178 curl_easy_reset(curl);
179 set_curl_common_info();
182 sprintf(url, "http:/v%s/containers/%s/json", getenv("DOCKER_ENGINE_VERSION"), getenv("HOSTNAME"));
184 curl_easy_setopt(curl, CURLOPT_URL, url);
186 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
187 curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
189 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
191 res = curl_easy_perform(curl);
199 cJSON *json_response = cJSON_Parse(curl_response_mem.memory);
201 printf("%lu bytes retrieved\n", (unsigned long)curl_response_mem.size);
203 if (json_response == NULL)
205 printf("Could not parse JSON response for url=\"%s\"\n", url);
209 cJSON *hostConfig = cJSON_GetObjectItemCaseSensitive(json_response, "HostConfig");
211 if (hostConfig == NULL)
213 printf("Could not get HostConfig object\n");
217 cJSON *networkMode = cJSON_GetObjectItemCaseSensitive(hostConfig, "NetworkMode");
219 if (networkMode == NULL)
221 printf("Could not get NetworkMode object\n");
225 cJSON *networkCopy = cJSON_Duplicate(networkMode, 1);
227 cJSON_Delete(json_response);
235 static char* create_docker_container_curl(int base_netconf_port, cJSON* managerBinds, cJSON* networkMode, int device_number)
237 if (managerBinds == NULL)
239 printf("Could not retrieve JSON object: Binds\n");
242 cJSON *binds = cJSON_Duplicate(managerBinds, 1);
244 if (networkMode == NULL)
246 printf("Could not retrieve JSON object: NetworkMode\n");
249 cJSON *netMode = cJSON_Duplicate(networkMode, 1);
251 struct MemoryStruct curl_response_mem;
253 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
254 curl_response_mem.size = 0; /* no data at this point */
258 curl_easy_reset(curl);
259 set_curl_common_info();
262 sprintf(url, "http:/v%s/containers/create", getenv("DOCKER_ENGINE_VERSION"));
264 // the docker image name to be used is defined in the Dockerfile of the NTS Manager,
265 // under the MODELS_IMAGE env variable
267 sprintf(models_var, "%s", getenv("MODELS_IMAGE"));
269 curl_easy_setopt(curl, CURLOPT_URL, url);
271 cJSON *postDataJson = cJSON_CreateObject();
273 if (cJSON_AddStringToObject(postDataJson, "Image", models_var) == NULL)
275 printf("Could not create JSON object: Image\n");
279 char device_name[100];
280 sprintf(device_name, "%s-%d", getenv("CONTAINER_NAME"), device_number);
282 if (cJSON_AddStringToObject(postDataJson, "Hostname", device_name) == NULL)
284 printf("Could not create JSON object: Hostname\n");
288 cJSON *hostConfig = cJSON_CreateObject();
289 if (hostConfig == NULL)
291 printf("Could not create JSON object: HostConfig\n");
295 cJSON_AddItemToObject(postDataJson, "HostConfig", hostConfig);
297 cJSON *portBindings = cJSON_CreateObject();
298 if (portBindings == NULL)
300 printf("Could not create JSON object: PortBindings\n");
304 cJSON_AddItemToObject(hostConfig, "PortBindings", portBindings);
306 for (int i = 0; i < NETCONF_CONNECTIONS_PER_DEVICE; ++i)
308 cJSON *port = cJSON_CreateArray();
311 printf("Could not create JSON object: port\n");
315 char dockerContainerPort[20];
316 sprintf(dockerContainerPort, "%d/tcp", 830 + i);
318 cJSON_AddItemToObject(portBindings, dockerContainerPort, port);
320 cJSON *hostPort = cJSON_CreateObject();
321 if (hostPort == NULL)
323 printf("Could not create JSON object: HostPort\n");
327 char dockerHostPort[10];
328 sprintf(dockerHostPort, "%d", base_netconf_port + i);
329 if (cJSON_AddStringToObject(hostPort, "HostPort", dockerHostPort) == NULL)
331 printf("Could not create JSON object: HostPortString\n");
334 if (cJSON_AddStringToObject(hostPort, "HostIp", getenv("NTS_IP")) == NULL)
336 printf("Could not create JSON object: HostIpString\n");
340 cJSON_AddItemToArray(port, hostPort);
343 cJSON *labels = cJSON_CreateObject();
346 printf("Could not create JSON object: Labels\n");
350 cJSON_AddItemToObject(postDataJson, "Labels", labels);
352 if (cJSON_AddStringToObject(labels, "NTS", "") == NULL)
354 printf("Could not create JSON object: NTS\n");
358 if (cJSON_AddStringToObject(labels, "NTS_Manager", getenv("HOSTNAME")) == NULL)
360 printf("Could not create JSON object: NTS Manager\n");
364 cJSON *env_variables_array = cJSON_CreateArray();
365 if (env_variables_array == NULL)
367 printf("Could not create JSON object: Env array\n");
371 cJSON_AddItemToObject(postDataJson, "Env", env_variables_array);
373 char environment_var[100];
374 sprintf(environment_var, "NTS_IP=%s", getenv("NTS_IP"));
376 cJSON *env_var_obj = cJSON_CreateString(environment_var);
377 if (env_var_obj == NULL)
379 printf("Could not create JSON object: Env array object NTS_IP\n");
382 cJSON_AddItemToArray(env_variables_array, env_var_obj);
384 char *external_nts_ip = getenv("EXTERNAL_NTS_IP");
385 if (external_nts_ip == NULL)
387 sprintf(environment_var, "EXTERNAL_NTS_IP=%s", getenv("NTS_IP"));
391 sprintf(environment_var, "EXTERNAL_NTS_IP=%s", external_nts_ip);
394 cJSON *env_var_obj_0 = cJSON_CreateString(environment_var);
395 if (env_var_obj_0 == NULL)
397 printf("Could not create JSON object: Env array object EXTERNAL_NTS_IP\n");
400 cJSON_AddItemToArray(env_variables_array, env_var_obj_0);
402 sprintf(environment_var, "NETCONF_BASE=%d", base_netconf_port);
403 cJSON *env_var_obj_2 = cJSON_CreateString(environment_var);
404 if (env_var_obj_2 == NULL)
406 printf("Could not create JSON object: Env array object NETCONF_BASE\n");
409 cJSON_AddItemToArray(env_variables_array, env_var_obj_2);
411 char scripts_dir[200];
412 sprintf(scripts_dir, "SCRIPTS_DIR=%s", getenv("SCRIPTS_DIR"));
413 cJSON *env_var_obj_3 = cJSON_CreateString(scripts_dir);
414 if (env_var_obj_3 == NULL)
416 printf("Could not create JSON object: Env array object SCRIPTS_DIR\n");
419 cJSON_AddItemToArray(env_variables_array, env_var_obj_3);
421 char k8s_deployment[50];
422 sprintf(k8s_deployment, "K8S_DEPLOYMENT=%s", getenv("K8S_DEPLOYMENT"));
423 cJSON *env_var_obj_4 = cJSON_CreateString(k8s_deployment);
424 if (env_var_obj_4 == NULL)
426 printf("Could not create JSON object: Env array object K8S_DEPLOYMENT\n");
429 cJSON_AddItemToArray(env_variables_array, env_var_obj_4);
431 char ipv6_enabled[50];
432 sprintf(ipv6_enabled, "IPv6Enabled=%s", getenv("IPv6Enabled"));
433 cJSON *env_var_obj_5 = cJSON_CreateString(ipv6_enabled);
434 if (env_var_obj_5 == NULL)
436 printf("Could not create JSON object: Env array object IPv6Enabled\n");
439 cJSON_AddItemToArray(env_variables_array, env_var_obj_5);
441 cJSON_AddItemToObject(hostConfig, "Binds", binds);
443 cJSON_AddItemToObject(hostConfig, "NetworkMode", netMode);
445 char *post_data_string = NULL;
447 post_data_string = cJSON_PrintUnformatted(postDataJson);
449 printf("Post data JSON:\n%s\n", post_data_string);
451 if (postDataJson != NULL)
453 cJSON_Delete(postDataJson);
456 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data_string);
458 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
460 res = curl_easy_perform(curl);
462 if (post_data_string != NULL)
464 free(post_data_string);
473 cJSON *json_response = cJSON_Parse(curl_response_mem.memory);
474 const cJSON *container_id = NULL;
476 printf("%lu bytes retrieved\n", (unsigned long)curl_response_mem.size);
478 container_id = cJSON_GetObjectItemCaseSensitive(json_response, "Id");
480 if (cJSON_IsString(container_id) && (container_id->valuestring != NULL))
482 printf("Container id: \"%s\"\n", container_id->valuestring);
484 char container_id_short[13];
486 memset(container_id_short, '\0', sizeof(container_id_short));
487 strncpy(container_id_short, container_id->valuestring, 12);
489 printf("Container id short: \"%s\"\n", container_id_short);
491 cJSON_Delete(json_response);
492 return strdup(container_id_short);
495 cJSON_Delete(json_response);
501 static int start_docker_container_curl(char *container_id)
503 struct MemoryStruct curl_response_mem;
505 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
506 curl_response_mem.size = 0; /* no data at this point */
510 curl_easy_reset(curl);
511 set_curl_common_info();
514 sprintf(url, "http:/v%s/containers/%s/start", getenv("DOCKER_ENGINE_VERSION"), container_id);
516 curl_easy_setopt(curl, CURLOPT_URL, url);
518 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
520 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
522 res = curl_easy_perform(curl);
526 return SR_ERR_OPERATION_FAILED;
530 printf("Container %s started successfully!\n", container_id);
536 static int rename_docker_container_curl(char *container_id, int device_number)
538 struct MemoryStruct curl_response_mem;
540 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
541 curl_response_mem.size = 0; /* no data at this point */
545 curl_easy_reset(curl);
546 set_curl_common_info();
548 char device_name[100];
549 sprintf(device_name, "%s-%d", getenv("CONTAINER_NAME"), device_number);
552 sprintf(url, "http:/v%s/containers/%s/rename?name=%s", getenv("DOCKER_ENGINE_VERSION"), container_id,
555 curl_easy_setopt(curl, CURLOPT_URL, url);
557 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
559 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
561 res = curl_easy_perform(curl);
565 return SR_ERR_OPERATION_FAILED;
569 printf("Container %s renamed successfully to %s!\n", container_id, device_name);
575 static int kill_and_remove_docker_container_curl(char *container_id)
577 struct MemoryStruct curl_response_mem;
579 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
580 curl_response_mem.size = 0; /* no data at this point */
584 curl_easy_reset(curl);
585 set_curl_common_info();
588 sprintf(url, "http:/v%s/containers/%s?force=true", getenv("DOCKER_ENGINE_VERSION"), container_id);
590 curl_easy_setopt(curl, CURLOPT_URL, url);
592 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
593 curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
595 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
597 res = curl_easy_perform(curl);
601 return SR_ERR_OPERATION_FAILED;
605 printf("Container %s removed successfully!\n", container_id);
611 static int send_mount_device_instance_ssh(char *url, char *credentials, char *device_name, int device_port)
615 curl_easy_reset(curl_odl);
616 set_curl_common_info_odl();
618 char url_for_curl[200];
619 sprintf(url_for_curl, "%s%s_%d", url, device_name, device_port);
621 curl_easy_setopt(curl_odl, CURLOPT_URL, url_for_curl);
623 char post_data_xml[1500];
625 sprintf(post_data_xml,
626 "<node xmlns=\"urn:TBD:params:xml:ns:yang:network-topology\">"
627 "<node-id>%s_%d</node-id>"
628 "<host xmlns=\"urn:opendaylight:netconf-node-topology\">%s</host>"
629 "<port xmlns=\"urn:opendaylight:netconf-node-topology\">%d</port>"
630 "<username xmlns=\"urn:opendaylight:netconf-node-topology\">%s</username>"
631 "<password xmlns=\"urn:opendaylight:netconf-node-topology\">%s</password>"
632 "<tcp-only xmlns=\"urn:opendaylight:netconf-node-topology\">false</tcp-only>"
633 "<keepalive-delay xmlns=\"urn:opendaylight:netconf-node-topology\">120</keepalive-delay>"
634 "<reconnect-on-changed-schema xmlns=\"urn:opendaylight:netconf-node-topology\">false</reconnect-on-changed-schema>"
635 "<sleep-factor xmlns=\"urn:opendaylight:netconf-node-topology\">1.5</sleep-factor>"
636 "<connection-timeout-millis xmlns=\"urn:opendaylight:netconf-node-topology\">20000</connection-timeout-millis>"
637 "<max-connection-attempts xmlns=\"urn:opendaylight:netconf-node-topology\">100</max-connection-attempts>"
638 "<between-attempts-timeout-millis xmlns=\"urn:opendaylight:netconf-node-topology\">2000</between-attempts-timeout-millis>"
640 device_name, device_port, (getenv("EXTERNAL_NTS_IP") == NULL) ? getenv("NTS_IP") : getenv("EXTERNAL_NTS_IP"),
641 device_port, "netconf", "netconf");
643 printf("Post data:\n%s\n", post_data_xml);
645 curl_easy_setopt(curl_odl, CURLOPT_POSTFIELDS, post_data_xml);
646 curl_easy_setopt(curl_odl, CURLOPT_CUSTOMREQUEST, "PUT");
647 curl_easy_setopt(curl_odl, CURLOPT_USERPWD, credentials);
649 res = curl_easy_perform(curl_odl);
652 printf("cURL failed to url=%s\n", url_for_curl);
655 long http_response_code = 0;
656 curl_easy_getinfo (curl_odl, CURLINFO_RESPONSE_CODE, &http_response_code);
657 if (http_response_code >= 200 && http_response_code <= 226 && http_response_code != CURLE_ABORTED_BY_CALLBACK)
659 printf("cURL succeeded to url=%s\n", url_for_curl);
663 printf("cURL to url=%s failed with code=%ld\n", url_for_curl, http_response_code);
664 return SR_ERR_OPERATION_FAILED;
670 static int send_mount_device_instance_tls(char *url, char *credentials, char *device_name, int device_port)
674 curl_easy_reset(curl_odl);
675 set_curl_common_info_odl();
677 char url_for_curl[200];
678 sprintf(url_for_curl, "%s%s_%d", url, device_name, device_port);
680 curl_easy_setopt(curl_odl, CURLOPT_URL, url_for_curl);
682 char post_data_xml[1500];
684 sprintf(post_data_xml,
685 "<node xmlns=\"urn:TBD:params:xml:ns:yang:network-topology\">"
686 "<protocol xmlns=\"urn:opendaylight:netconf-node-topology\">"
689 "<node-id>%s_%d</node-id>"
690 "<host xmlns=\"urn:opendaylight:netconf-node-topology\">%s</host>"
691 "<key-based xmlns=\"urn:opendaylight:netconf-node-topology\">"
692 "<username>%s</username>"
693 "<key-id>device-key</key-id>"
695 "<port xmlns=\"urn:opendaylight:netconf-node-topology\">%d</port>"
696 "<tcp-only xmlns=\"urn:opendaylight:netconf-node-topology\">false</tcp-only>"
697 "<keepalive-delay xmlns=\"urn:opendaylight:netconf-node-topology\">120</keepalive-delay>"
698 "<reconnect-on-changed-schema xmlns=\"urn:opendaylight:netconf-node-topology\">false</reconnect-on-changed-schema>"
699 "<sleep-factor xmlns=\"urn:opendaylight:netconf-node-topology\">1.5</sleep-factor>"
700 "<connection-timeout-millis xmlns=\"urn:opendaylight:netconf-node-topology\">20000</connection-timeout-millis>"
701 "<max-connection-attempts xmlns=\"urn:opendaylight:netconf-node-topology\">100</max-connection-attempts>"
702 "<between-attempts-timeout-millis xmlns=\"urn:opendaylight:netconf-node-topology\">2000</between-attempts-timeout-millis>"
704 device_name, device_port, (getenv("EXTERNAL_NTS_IP") == NULL) ? getenv("NTS_IP") : getenv("EXTERNAL_NTS_IP"), "netconf", device_port);
706 printf("Post data:\n%s\n", post_data_xml);
708 curl_easy_setopt(curl_odl, CURLOPT_POSTFIELDS, post_data_xml);
709 curl_easy_setopt(curl_odl, CURLOPT_CUSTOMREQUEST, "PUT");
710 curl_easy_setopt(curl_odl, CURLOPT_USERPWD, credentials);
712 res = curl_easy_perform(curl_odl);
715 printf("cURL failed to url=%s\n", url_for_curl);
718 long http_response_code = 0;
719 curl_easy_getinfo (curl_odl, CURLINFO_RESPONSE_CODE, &http_response_code);
720 if (http_response_code >= 200 && http_response_code <= 226 && http_response_code != CURLE_ABORTED_BY_CALLBACK)
722 printf("cURL succeeded to url=%s\n", url_for_curl);
726 printf("cURL to url=%s failed with code=%ld\n", url_for_curl, http_response_code);
727 return SR_ERR_OPERATION_FAILED;
733 static int send_unmount_device_instance(char *url, char *credentials, char *device_name, int device_port)
737 curl_easy_reset(curl_odl);
738 set_curl_common_info_odl();
740 char url_for_curl[200];
741 sprintf(url_for_curl, "%s%s_%d", url, device_name, device_port);
743 curl_easy_setopt(curl_odl, CURLOPT_URL, url_for_curl);
745 curl_easy_setopt(curl_odl, CURLOPT_POSTFIELDS, "");
746 curl_easy_setopt(curl_odl, CURLOPT_CUSTOMREQUEST, "DELETE");
747 curl_easy_setopt(curl_odl, CURLOPT_USERPWD, credentials);
749 res = curl_easy_perform(curl_odl);
752 printf("cURL failed to url=%s\n", url_for_curl);
755 long http_response_code = 0;
756 curl_easy_getinfo (curl_odl, CURLINFO_RESPONSE_CODE, &http_response_code);
757 if (http_response_code == 200 && http_response_code != CURLE_ABORTED_BY_CALLBACK)
759 printf("cURL succeeded to url=%s\n", url_for_curl);
763 printf("cURL to url=%s failed with code=%ld\n", url_for_curl, http_response_code);
764 return SR_ERR_OPERATION_FAILED;
771 static int send_mount_device(device_t *current_device, controller_t controller_details)
774 bool is_mounted = true;
777 char device_name[200];
778 sprintf(device_name, "%s-%d", getenv("CONTAINER_NAME"), current_device->device_number);
780 //This is where we hardcoded: 7 devices will have SSH connections and 3 devices will have TLS connections
781 for (int i = 0; i < SSH_CONNECTIONS_PER_DEVICE; ++port, ++i)
785 rc = send_mount_device_instance_ssh(controller_details.url, controller_details.credentials,
786 device_name, current_device->netconf_port + port);
792 for (int i = 0; i < TLS_CONNECTIONS_PER_DEVICE; ++port, ++i)
794 rc = send_mount_device_instance_tls(controller_details.url, controller_details.credentials,
795 device_name, current_device->netconf_port + port);
802 current_device->is_mounted = is_mounted;
807 static int send_unmount_device(device_t *current_device, controller_t controller_details)
810 char device_name[100];
811 sprintf(device_name, "%s-%d", getenv("CONTAINER_NAME"), current_device->device_number);
813 for (int port = 0; port < NETCONF_CONNECTIONS_PER_DEVICE; ++port)
815 rc = send_unmount_device_instance(controller_details.url, controller_details.credentials,
816 device_name, current_device->netconf_port + port);
819 printf("Could not send unmount for ODL with url=\"%s\", for device=\"%s\" and port=%d\n",
820 controller_details.url, device_name, current_device->netconf_port);
823 current_device->is_mounted = false;
828 device_stack_t *new_device_stack(void)
830 device_stack_t *stack = malloc(sizeof(*stack));
834 stack->stack_size = 0;
839 void push_device(device_stack_t *theStack, char *dev_id, int port, int dev_num)
841 device_t *new_dev = malloc(sizeof(*new_dev));
844 new_dev->device_id = strdup(dev_id);
845 new_dev->netconf_port = port;
846 new_dev->device_number = dev_num;
847 new_dev->is_mounted = false;
848 new_dev->operational_state = strdup("not-specified");
850 new_dev->next = theStack->head;
852 theStack->head = new_dev;
853 theStack->stack_size++;
857 void pop_device(device_stack_t *theStack)
859 if (theStack && theStack->head) {
860 device_t *temp = theStack->head;
861 theStack->head = theStack->head->next;
863 free(temp->device_id);
864 free(temp->operational_state);
866 theStack->stack_size--;
870 int get_netconf_port_next(device_stack_t *theStack)
872 if (theStack && theStack->stack_size > 0) {
873 return theStack->head->netconf_port + NETCONF_CONNECTIONS_PER_DEVICE;
876 return get_netconf_port_base();
879 int get_netconf_port_base()
881 int netconf_port_base;
883 netconf_port_base = getIntFromString(getenv("NETCONF_BASE"), 50000);
885 return netconf_port_base;
888 // we start numbering the containers from 0
889 int get_device_number_next(device_stack_t *theStack)
891 if (theStack && theStack->stack_size > 0) {
892 return theStack->head->device_number + 1;
898 char *get_id_last_device(device_stack_t *theStack)
900 if (theStack && theStack->head) {
901 return theStack->head->device_id;
906 int get_current_number_of_mounted_devices(device_stack_t *theStack)
908 int mounted_devices = 0;
910 if (theStack && theStack->head)
912 device_t *current_device = theStack->head;
914 while (current_device != NULL)
916 if (current_device->is_mounted)
920 current_device = current_device->next;
924 return mounted_devices;
927 int get_current_number_of_devices(device_stack_t *theStack)
929 //TODO implement function for k8s deployment
930 if (strcmp(getenv("K8S_DEPLOYMENT"), "true") == 0)
935 struct MemoryStruct curl_response_mem;
937 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
938 curl_response_mem.size = 0; /* no data at this point */
942 curl_easy_reset(curl);
943 set_curl_common_info();
946 sprintf(url, "http:/v%s/containers/json?all=true&filters={\"label\":[\"NTS_Manager=%s\"],\"status\":[\"running\"]}",
947 getenv("DOCKER_ENGINE_VERSION"), getenv("HOSTNAME"));
949 curl_easy_setopt(curl, CURLOPT_URL, url);
951 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
952 curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
954 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
956 res = curl_easy_perform(curl);
960 return SR_ERR_OPERATION_FAILED;
964 cJSON *json_response = cJSON_Parse(curl_response_mem.memory);
966 printf("%lu bytes retrieved\n", (unsigned long)curl_response_mem.size);
968 if (json_response == NULL || !cJSON_IsArray(json_response))
970 printf("Could not parse JSON response for url=\"%s\"\n", url);
971 return SR_ERR_OPERATION_FAILED;
974 int num_of_devices = cJSON_GetArraySize(json_response);
975 cJSON_Delete(json_response);
977 return num_of_devices;
983 static int set_operational_state_of_device(device_stack_t *theStack, char *device_id, char *operational_state)
985 if (theStack && theStack->head)
987 device_t *current_device = theStack->head;
989 while (current_device != NULL)
991 if (strcmp(current_device->device_id, device_id) == 0)
993 free(current_device->operational_state);
994 current_device->operational_state = strdup(operational_state);
999 current_device = current_device->next;
1003 printf("Could not find device with uuid=\"%s\"\n", device_id);
1004 return SR_ERR_OPERATION_FAILED;
1007 char* get_docker_container_operational_state(device_stack_t *theStack, char *container_id)
1009 if (theStack && theStack->head)
1011 device_t *current_device = theStack->head;
1013 while (current_device != NULL)
1015 if (strcmp(current_device->device_id, container_id) == 0)
1017 return current_device->operational_state;
1020 current_device = current_device->next;
1027 int start_device(device_stack_t *theStack)
1030 static cJSON *managerBindings = NULL, *networkMode = NULL;
1032 if (managerBindings == NULL)
1034 managerBindings = get_docker_container_bindings();
1037 if (networkMode == NULL)
1039 networkMode = get_docker_container_network_node();
1042 int netconf_base = get_netconf_port_next(theStack);
1043 int device_number = get_device_number_next(theStack);
1045 char *dev_id = create_docker_container_curl(netconf_base, managerBindings, networkMode, device_number);
1048 printf("ERROR: Could not create docker container!\n");
1049 return SR_ERR_OPERATION_FAILED;
1052 push_device(theStack, dev_id, netconf_base, device_number);
1054 rc = start_docker_container_curl(dev_id);
1055 if (rc != SR_ERR_OK)
1057 printf("Could not start device with device_id=\"%s\"\n", dev_id);
1060 rc = rename_docker_container_curl(dev_id, device_number);
1061 if (rc != SR_ERR_OK)
1063 printf("Could not rename device with device_id=\"%s\"\n", dev_id);
1075 curl = curl_easy_init();
1078 printf("cURL initialization error! Aborting call!\n");
1079 return SR_ERR_OPERATION_FAILED;
1089 curl_easy_cleanup(curl);
1095 int _init_curl_odl()
1097 curl_odl = curl_easy_init();
1099 if (curl_odl == NULL) {
1100 printf("cURL initialization error! Aborting call!\n");
1101 return SR_ERR_OPERATION_FAILED;
1107 int cleanup_curl_odl()
1109 if (curl_odl != NULL)
1111 curl_easy_cleanup(curl_odl);
1117 int _init_curl_k8s()
1119 curl_k8s = curl_easy_init();
1121 if (curl_k8s == NULL) {
1122 printf("cURL initialization error! Aborting call!\n");
1123 return SR_ERR_OPERATION_FAILED;
1129 int cleanup_curl_k8s()
1131 if (curl_k8s != NULL)
1133 curl_easy_cleanup(curl_k8s);
1139 int stop_device(device_stack_t *theStack)
1142 char *last_id = get_id_last_device(theStack);
1144 rc = kill_and_remove_docker_container_curl(last_id);
1145 if (rc != SR_ERR_OK)
1147 printf("Could not kill and remove docker container with uuid=\"%s\"\n", last_id);
1150 rc = removeDeviceEntryFromStatusFile(last_id);
1151 if (rc != SR_ERR_OK)
1153 printf("Could not remove entry from status file for uuid=\"%s\"\n", last_id);
1156 pop_device(theStack);
1161 int mount_device(device_stack_t *theStack, controller_t controller_details)
1165 if (theStack && theStack->head)
1167 device_t *current_device = theStack->head;
1168 while (current_device != NULL && current_device->is_mounted == true)
1170 printf("Device \"%s\" is already mounted, skipping...\n", current_device->device_id);
1171 current_device = current_device->next;
1174 if (current_device != NULL)
1176 printf("Sending mount device for device \"%s\"...\n", current_device->device_id);
1177 rc = send_mount_device(current_device, controller_details);
1178 if (rc != SR_ERR_OK)
1180 return SR_ERR_OPERATION_FAILED;
1188 int unmount_device(device_stack_t *theStack, controller_t controller_list)
1192 if (theStack && theStack->head)
1194 device_t *current_device = theStack->head;
1195 while (current_device != NULL && current_device->is_mounted == false)
1197 printf("Device \"%s\" is already unmounted, skipping...\n", current_device->device_id);
1198 current_device = current_device->next;
1201 if (current_device != NULL)
1203 printf("Sending unmount device for device \"%s\"...\n", current_device->device_id);
1204 rc = send_unmount_device(current_device, controller_list);
1205 if (rc != SR_ERR_OK)
1207 return SR_ERR_OPERATION_FAILED;
1215 int get_docker_containers_operational_state_curl(device_stack_t *theStack)
1218 //TODO implement function for k8s deployment
1219 if (strcmp(getenv("K8S_DEPLOYMENT"), "true") == 0)
1225 struct MemoryStruct curl_response_mem;
1227 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
1228 curl_response_mem.size = 0; /* no data at this point */
1232 curl_easy_reset(curl);
1233 set_curl_common_info();
1236 sprintf(url, "http:/v%s/containers/json?all=true&filters={\"label\":[\"NTS_Manager=%s\"]}",
1237 getenv("DOCKER_ENGINE_VERSION"), getenv("HOSTNAME"));
1239 curl_easy_setopt(curl, CURLOPT_URL, url);
1241 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
1242 curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
1244 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
1246 res = curl_easy_perform(curl);
1248 if (res != CURLE_OK)
1250 return SR_ERR_OPERATION_FAILED;
1254 cJSON *json_response = cJSON_Parse(curl_response_mem.memory);
1255 const cJSON *container = NULL;
1257 printf("%lu bytes retrieved\n", (unsigned long)curl_response_mem.size);
1259 if (json_response == NULL || !cJSON_IsArray(json_response))
1261 printf("Could not parse JSON response for url=\"%s\"\n", url);
1262 return SR_ERR_OPERATION_FAILED;
1265 cJSON_ArrayForEach(container, json_response)
1267 cJSON *container_id_long = cJSON_GetObjectItemCaseSensitive(container, "Id");
1268 cJSON *state = cJSON_GetObjectItemCaseSensitive(container, "State");
1270 if (cJSON_IsString(container_id_long) && (container_id_long->valuestring != NULL))
1272 char container_id_short[13];
1274 memset(container_id_short, '\0', sizeof(container_id_short));
1275 strncpy(container_id_short, container_id_long->valuestring, 12);
1277 if (cJSON_IsString(state) && (state->valuestring != NULL))
1279 rc = set_operational_state_of_device(theStack, container_id_short, state->valuestring);
1280 if (rc != SR_ERR_OK)
1282 printf("Could not set the operational state for the device with uuid=\"%s\"\n", container_id_short);
1283 return SR_ERR_OPERATION_FAILED;
1289 cJSON_Delete(json_response);
1295 char* get_docker_container_resource_stats(device_stack_t *theStack)
1297 //TOD need to implement this for k8s deployment
1298 if (strcmp(getenv("K8S_DEPLOYMENT"), "true"))
1300 return strdup("CPU=0%;RAM=0MiB");
1303 char line[LINE_BUFSIZE];
1307 /* Get a pipe where the output from the scripts comes in */
1309 sprintf(script, "/opt/dev/docker_stats.sh %s", getenv("HOSTNAME"));
1311 pipe = popen(script, "r");
1312 if (pipe == NULL) { /* check for errors */
1313 printf("Could not open script.\n");
1314 return NULL; /* return with exit code indicating error */
1317 /* Read script output from the pipe line by line */
1319 while (fgets(line, LINE_BUFSIZE, pipe) != NULL) {
1320 printf("Script output line %d: %s", linenr, line);
1323 pclose(pipe); /* Close the pipe */
1324 return strdup(line);
1327 /* Once here, out of the loop, the script has ended. */
1328 pclose(pipe); /* Close the pipe */
1329 return NULL; /* return with exit code indicating success. */
1332 int notification_delay_period_changed(sr_val_t *val, size_t count)
1334 char *stringConfiguration = readConfigFileInString();
1336 if (stringConfiguration == NULL)
1338 printf("Could not read configuration file!\n");
1339 return SR_ERR_OPERATION_FAILED;
1342 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
1343 if (jsonConfig == NULL)
1345 free(stringConfiguration);
1346 const char *error_ptr = cJSON_GetErrorPtr();
1347 if (error_ptr != NULL)
1349 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1351 return SR_ERR_OPERATION_FAILED;
1353 //we don't need the string anymore
1354 free(stringConfiguration);
1355 stringConfiguration = NULL;
1357 cJSON *notifConfig = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
1358 if (!cJSON_IsObject(notifConfig))
1360 printf("Configuration JSON is not as expected: notification-config is not an object");
1361 cJSON_Delete(jsonConfig);
1362 return SR_ERR_OPERATION_FAILED;
1365 cJSON *faultNotifDelay = cJSON_GetObjectItemCaseSensitive(notifConfig, "fault-notification-delay-period");
1366 if (!cJSON_IsArray(faultNotifDelay))
1368 printf("Configuration JSON is not as expected: fault-notification-delay-period is not an array.");
1369 cJSON_Delete(jsonConfig);
1370 return SR_ERR_OPERATION_FAILED;
1373 cJSON_DeleteItemFromObject(notifConfig, "fault-notification-delay-period");
1375 faultNotifDelay = NULL;
1377 faultNotifDelay = cJSON_CreateArray();
1378 if (faultNotifDelay == NULL)
1380 cJSON_Delete(jsonConfig);
1381 return SR_ERR_OPERATION_FAILED;
1383 cJSON_AddItemToObject(notifConfig, "fault-notification-delay-period", faultNotifDelay);
1385 if (val != NULL && count > 0)
1387 cJSON *arrayEntry = NULL;
1388 for (size_t i=0; i<count; ++i)
1390 arrayEntry = cJSON_CreateNumber(val[i].data.uint32_val);
1391 if (arrayEntry == NULL)
1393 cJSON_Delete(jsonConfig);
1394 return SR_ERR_OPERATION_FAILED;
1396 cJSON_AddItemToArray(faultNotifDelay, arrayEntry);
1401 cJSON *arrayEntry = cJSON_CreateNumber(0);
1402 if (arrayEntry == NULL)
1404 cJSON_Delete(jsonConfig);
1405 return SR_ERR_OPERATION_FAILED;
1407 cJSON_AddItemToArray(faultNotifDelay, arrayEntry);
1410 //writing the new JSON to the configuration file
1411 stringConfiguration = cJSON_Print(jsonConfig);
1412 writeConfigFile(stringConfiguration);
1414 if (stringConfiguration != NULL)
1416 free(stringConfiguration);
1417 stringConfiguration = NULL;
1420 cJSON_Delete(jsonConfig);
1425 int ves_heartbeat_period_changed(int period)
1427 char *stringConfiguration = readConfigFileInString();
1429 if (stringConfiguration == NULL)
1431 printf("Could not read configuration file!\n");
1432 return SR_ERR_OPERATION_FAILED;
1435 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
1436 if (jsonConfig == NULL)
1438 free(stringConfiguration);
1439 const char *error_ptr = cJSON_GetErrorPtr();
1440 if (error_ptr != NULL)
1442 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1444 return SR_ERR_OPERATION_FAILED;
1446 //we don't need the string anymore
1447 free(stringConfiguration);
1448 stringConfiguration = NULL;
1450 cJSON *notifConfig = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
1451 if (!cJSON_IsObject(notifConfig))
1453 printf("Configuration JSON is not as expected: notification-config is not an object");
1454 cJSON_Delete(jsonConfig);
1455 return SR_ERR_OPERATION_FAILED;
1458 cJSON *vesHeartbeatPeriod = cJSON_GetObjectItemCaseSensitive(notifConfig, "ves-heartbeat-period");
1459 if (!cJSON_IsNumber(vesHeartbeatPeriod))
1461 printf("Configuration JSON is not as expected: ves-heartbeat-period is not an object");
1462 cJSON_Delete(jsonConfig);
1463 return SR_ERR_OPERATION_FAILED;
1466 //we set the value of the fault-notification-delay-period object
1467 cJSON_SetNumberValue(vesHeartbeatPeriod, period);
1469 //writing the new JSON to the configuration file
1470 stringConfiguration = cJSON_Print(jsonConfig);
1471 writeConfigFile(stringConfiguration);
1473 if (stringConfiguration != NULL)
1475 free(stringConfiguration);
1476 stringConfiguration = NULL;
1479 cJSON_Delete(jsonConfig);
1484 static int add_keystore_entry_odl(char *url, char *credentials)
1488 curl_easy_reset(curl_odl);
1489 set_curl_common_info_odl();
1491 char url_for_curl[200];
1492 sprintf(url_for_curl, "%s", url);
1494 curl_easy_setopt(curl_odl, CURLOPT_URL, url_for_curl);
1496 char post_data_xml[2000];
1498 sprintf(post_data_xml,
1499 "<input xmlns=\"urn:opendaylight:netconf:keystore\">"
1501 "<key-id>device-key</key-id>"
1502 "<private-key>MIIEpAIBAAKCAQEAueCQaNQWoNmFK6LKu1p8U8ZWdWg/PvDdLsJyzfzl/Qw4UA68"
1503 "SfFNaY06zZl8QB9W02nr5kWeeMY0VA3adrPgOlvfx3oWlFbkETnMaN4OT3WTQ0Wt"
1504 "6jAWZDzVfopwpJPAzRPxACDftIqFGagYcF32hZlVNqqnVdbXh0S0EViweqp/dbG4"
1505 "VDUHSNVbglc+u4UbEzNIFXMdEFsJZpkynOmSiTsIATqIhb+2srkVgLwhfkC2qkuH"
1506 "QwAHdubuB07ObM2z01UhyEdDvEYGHwtYAGDBL2TAcsI0oGeVkRyuOkV0QY0UN7UE"
1507 "FI1yTYw+xZ42HgFx3uGwApCImxhbj69GBYWFqwIDAQABAoIBAQCZN9kR8DGu6V7y"
1508 "t0Ax68asL8O5B/OKaHWKQ9LqpVrXmikZJOxkbzoGldow/CIFoU+q+Zbwu9aDa65a"
1509 "0wiP7Hoa4Py3q5XNNUrOQDyU/OYC7cI0I83WS0lJ2zOJGYj8wKae5Z81IeQFKGHK"
1510 "4lsy1OGPAvPRGh7RjUUgRavA2MCwe07rWRuDb/OJFe4Oh56UMEjwMiNBtMNtncog"
1511 "j1vr/qgRJdf9tf0zlJmLvUJ9+HSFFV9I/97LJyFhb95gAfHkjdVroLVgT3Cho+4P"
1512 "WtZaKCIGD0OwfOG2nLV4leXvRUk62/LMlB8NI9+JF7Xm+HCKbaWHNWC7mvWSLV58"
1513 "Zl4AbUWRAoGBANyJ6SFHFRHSPDY026SsdMzXR0eUxBAK7G70oSBKKhY+O1j0ocLE"
1514 "jI2krHJBhHbLlnvJVyMUaCUOTS5m0uDw9hgSsAqeSL3hL38kxVZw+KNG9Ouno1Fl"
1515 "KnE/xXHlPQyeGs/P8nAMzHZxQtEsQdQayJEhK2XXHTsy7Q3MxDisfVJ1AoGBANfD"
1516 "34gB+OMx6pwj7zk3qWbYXSX8xjCZMR0ciko+h4xeMP2N8B0oyoqC+v1ABMAtJ3wG"
1517 "sGZd0hV9gwM7OUM3SEwkn6oeg1GemWLcn4rlSmTnZc4aeVwrEWlnSNFX3s4g9l4u"
1518 "k8Ugu4MVJYqH8HuDQ5Ggl6/QAwPzMSEdCW0O+jOfAoGAIBRbegC5+t6m7Yegz4Ja"
1519 "dxV1g98K6f58x+MDsQu4tYWV4mmrQgaPH2dtwizvlMwmdpkh+LNWNtWuumowkJHc"
1520 "akIFo3XExQIFg6wYnGtQb4e5xrGa2xMpKlIJaXjb+YLiCYqJDG2ALFZrTrvuU2kV"
1521 "9a5qfqTc1qigvNolTM0iaaUCgYApmrZWhnLUdEKV2wP813PNxfioI4afxlpHD8LG"
1522 "sCn48gymR6E+Lihn7vuwq5B+8fYEH1ISWxLwW+RQUjIneNhy/jjfV8TgjyFqg7or"
1523 "0Sy4KjpiNI6kLBXOakELRNNMkeSPopGR2E7v5rr3bGD9oAD+aqX1G7oJH/KgPPYd"
1524 "Vl7+ZwKBgQDcHyWYrimjyUgKaQD2GmoO9wdcJYQ59ke9K+OuGlp4ti5arsi7N1tP"
1525 "B4f09aeELM2ASIuk8Q/Mx0jQFnm8lzRFXdewgvdPoZW/7VufM9O7dGPOc41cm2Dh"
1526 "yrTcXx/VmUBb+/fnXVEgCv7gylp/wtdTGHQBQJHR81jFBz0lnLj+gg==</private-key>"
1527 "<passphrase></passphrase>"
1531 printf("Post data:\n%s\n", post_data_xml);
1533 curl_easy_setopt(curl_odl, CURLOPT_POSTFIELDS, post_data_xml);
1534 curl_easy_setopt(curl_odl, CURLOPT_CUSTOMREQUEST, "POST");
1535 curl_easy_setopt(curl_odl, CURLOPT_USERPWD, credentials);
1537 res = curl_easy_perform(curl_odl);
1538 if (res != CURLE_OK)
1540 printf("cURL failed to url=%s\n", url_for_curl);
1543 long http_response_code = 0;
1544 curl_easy_getinfo (curl_odl, CURLINFO_RESPONSE_CODE, &http_response_code);
1545 if (http_response_code >= 200 && http_response_code <= 226 && http_response_code != CURLE_ABORTED_BY_CALLBACK)
1547 printf("cURL succeeded to url=%s\n", url_for_curl);
1551 printf("cURL to url=%s failed with code=%ld\n", url_for_curl, http_response_code);
1552 return SR_ERR_OPERATION_FAILED;
1558 static int add_private_key_odl(char *url, char *credentials)
1562 curl_easy_reset(curl_odl);
1563 set_curl_common_info_odl();
1565 char url_for_curl[200];
1566 sprintf(url_for_curl, "%s", url);
1568 curl_easy_setopt(curl_odl, CURLOPT_URL, url_for_curl);
1570 char post_data_xml[4000];
1572 sprintf(post_data_xml,
1573 "<input xmlns=\"urn:opendaylight:netconf:keystore\">"
1575 "<name>device-key</name>"
1576 "<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>"
1577 "<certificate-chain>MIIECTCCAvGgAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBjDELMAkGA1UEBhMCQ1oxFjAUBgNVBAgMDVNvdXRoIE1vcmF2aWExDTALBgNVBAcMBEJybm8xDzANBgNVBAoMBkNFU05FVDEMMAoGA1UECwwDVE1DMRMwEQYDVQQDDApleGFtcGxlIENBMSIwIAYJKoZIhvcNAQkBFhNleGFtcGxlY2FAbG9jYWxob3N0MB4XDTE1MDczMDA3MjcxOFoXDTM1MDcyNTA3MjcxOFowgYUxCzAJBgNVBAYTAkNaMRYwFAYDVQQIDA1Tb3V0aCBNb3JhdmlhMQ8wDQYDVQQKDAZDRVNORVQxDDAKBgNVBAsMA1RNQzEXMBUGA1UEAwwOZXhhbXBsZSBjbGllbnQxJjAkBgkqhkiG9w0BCQEWF2V4YW1wbGVjbGllbnRAbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAueCQaNQWoNmFK6LKu1p8U8ZWdWg/PvDdLsJyzfzl/Qw4UA68SfFNaY06zZl8QB9W02nr5kWeeMY0VA3adrPgOlvfx3oWlFbkETnMaN4OT3WTQ0Wt6jAWZDzVfopwpJPAzRPxACDftIqFGagYcF32hZlVNqqnVdbXh0S0EViweqp/dbG4VDUHSNVbglc+u4UbEzNIFXMdEFsJZpkynOmSiTsIATqIhb+2srkVgLwhfkC2qkuHQwAHdubuB07ObM2z01UhyEdDvEYGHwtYAGDBL2TAcsI0oGeVkRyuOkV0QY0UN7UEFI1yTYw+xZ42HgFx3uGwApCImxhbj69GBYWFqwIDAQABo3sweTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUXGpLeLnh2cSDARAVA7KrBxGYpo8wHwYDVR0jBBgwFoAUc1YQIqjZsHVwlea0AB4N+ilNI2gwDQYJKoZIhvcNAQELBQADggEBAJPV3RTXFRtNyOU4rjPpYeBAIAFp2aqGc4t2J1c7oPp/1n+lZvjnwtlJpZHxMM783e2ryDQ6dkvXDf8kpwKlg3U3mkJ3xKkDdWrM4QwghXdCN519aa9qmu0zdFL+jUAaWlQ5tsceOrvbusCcbMqiFGk/QfpHqPv52SVWbYyUx7IX7DE+UjgsLHycfV/tlcx4ZE6soTzl9VdgSL/zmzG3rjsr58J80rXckLgBhvijgBlIAJvWfC7D0vaouvBInSFXymdPVoUDZ30cdGLf+hI/i/TfsEMOinLrXVdkSGNo6FXAHKSvXeB9oFKSzhQ7OPyRyqvEPycUSw/qD6FVr80oDDc=</certificate-chain>"
1581 printf("Post data:\n%s\n", post_data_xml);
1583 curl_easy_setopt(curl_odl, CURLOPT_POSTFIELDS, post_data_xml);
1584 curl_easy_setopt(curl_odl, CURLOPT_CUSTOMREQUEST, "POST");
1585 curl_easy_setopt(curl_odl, CURLOPT_USERPWD, credentials);
1587 res = curl_easy_perform(curl_odl);
1588 if (res != CURLE_OK)
1590 printf("cURL failed to url=%s\n", url_for_curl);
1593 long http_response_code = 0;
1594 curl_easy_getinfo (curl_odl, CURLINFO_RESPONSE_CODE, &http_response_code);
1595 if (http_response_code >= 200 && http_response_code <= 226 && http_response_code != CURLE_ABORTED_BY_CALLBACK)
1597 printf("cURL succeeded to url=%s\n", url_for_curl);
1601 printf("cURL to url=%s failed with code=%ld\n", url_for_curl, http_response_code);
1602 return SR_ERR_OPERATION_FAILED;
1608 static int add_trusted_ca_odl(char *url, char *credentials)
1612 curl_easy_reset(curl_odl);
1613 set_curl_common_info_odl();
1615 char url_for_curl[200];
1616 sprintf(url_for_curl, "%s", url);
1618 curl_easy_setopt(curl_odl, CURLOPT_URL, url_for_curl);
1620 char post_data_xml[2000];
1622 sprintf(post_data_xml,
1623 "<input xmlns=\"urn:opendaylight:netconf:keystore\">"
1624 "<trusted-certificate>"
1625 "<name>test_trusted_cert</name>"
1626 "<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>"
1627 "</trusted-certificate>"
1630 printf("Post data:\n%s\n", post_data_xml);
1632 curl_easy_setopt(curl_odl, CURLOPT_POSTFIELDS, post_data_xml);
1633 curl_easy_setopt(curl_odl, CURLOPT_CUSTOMREQUEST, "POST");
1634 curl_easy_setopt(curl_odl, CURLOPT_USERPWD, credentials);
1636 res = curl_easy_perform(curl_odl);
1637 if (res != CURLE_OK)
1639 printf("cURL failed to url=%s\n", url_for_curl);
1642 long http_response_code = 0;
1643 curl_easy_getinfo (curl_odl, CURLINFO_RESPONSE_CODE, &http_response_code);
1644 if (http_response_code >= 200 && http_response_code <= 226 && http_response_code != CURLE_ABORTED_BY_CALLBACK)
1646 printf("cURL succeeded to url=%s\n", url_for_curl);
1650 printf("cURL to url=%s failed with code=%ld\n", url_for_curl, http_response_code);
1651 return SR_ERR_OPERATION_FAILED;
1657 int add_key_pair_to_odl(controller_t *controller_list, int controller_list_size)
1661 rc = add_keystore_entry_odl(controller_list[0].url_for_keystore_add, controller_list[0].credentials);
1662 if (rc != SR_ERR_OK)
1664 printf("Failed to add keystore entry to ODL.\n");
1667 rc = add_private_key_odl(controller_list[0].url_for_private_key_add, controller_list[0].credentials);
1668 if (rc != SR_ERR_OK)
1670 printf("Failed to add private key entry to ODL.\n");
1673 rc = add_trusted_ca_odl(controller_list[0].url_for_trusted_ca_add, controller_list[0].credentials);
1674 if (rc != SR_ERR_OK)
1676 printf("Failed to add trusted CA entry to ODL.\n");
1682 int ves_ip_changed(char *new_ip)
1684 char *stringConfiguration = readConfigFileInString();
1686 if (stringConfiguration == NULL)
1688 printf("Could not read configuration file!\n");
1689 return SR_ERR_OPERATION_FAILED;
1692 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
1693 if (jsonConfig == NULL)
1695 free(stringConfiguration);
1696 const char *error_ptr = cJSON_GetErrorPtr();
1697 if (error_ptr != NULL)
1699 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1701 return SR_ERR_OPERATION_FAILED;
1703 //we don't need the string anymore
1704 free(stringConfiguration);
1705 stringConfiguration = NULL;
1707 cJSON *vesDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ves-endpoint-details");
1708 if (!cJSON_IsObject(vesDetails))
1710 printf("Configuration JSON is not as expected: ves-endpoint-details is not an object");
1711 cJSON_Delete(jsonConfig);
1712 return SR_ERR_OPERATION_FAILED;
1715 cJSON *vesIp = cJSON_GetObjectItemCaseSensitive(vesDetails, "ves-endpoint-ip");
1716 if (!cJSON_IsString(vesIp))
1718 printf("Configuration JSON is not as expected: ves-endpoint-ip is not a string");
1719 cJSON_Delete(jsonConfig);
1720 return SR_ERR_OPERATION_FAILED;
1723 //we set the value of the fault-notification-delay-period object
1724 cJSON_ReplaceItemInObject(vesDetails, "ves-endpoint-ip", cJSON_CreateString(new_ip));
1726 //writing the new JSON to the configuration file
1727 stringConfiguration = cJSON_Print(jsonConfig);
1728 writeConfigFile(stringConfiguration);
1730 if (stringConfiguration != NULL)
1732 free(stringConfiguration);
1733 stringConfiguration = NULL;
1736 cJSON_Delete(jsonConfig);
1741 int ves_port_changed(int new_port)
1743 char *stringConfiguration = readConfigFileInString();
1745 if (stringConfiguration == NULL)
1747 printf("Could not read configuration file!\n");
1748 return SR_ERR_OPERATION_FAILED;
1751 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
1752 if (jsonConfig == NULL)
1754 free(stringConfiguration);
1755 const char *error_ptr = cJSON_GetErrorPtr();
1756 if (error_ptr != NULL)
1758 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1760 return SR_ERR_OPERATION_FAILED;
1762 //we don't need the string anymore
1763 free(stringConfiguration);
1764 stringConfiguration = NULL;
1766 cJSON *vesDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ves-endpoint-details");
1767 if (!cJSON_IsObject(vesDetails))
1769 printf("Configuration JSON is not as expected: ves-endpoint-details is not an object");
1770 cJSON_Delete(jsonConfig);
1771 return SR_ERR_OPERATION_FAILED;
1774 cJSON *vesPort = cJSON_GetObjectItemCaseSensitive(vesDetails, "ves-endpoint-port");
1775 if (!cJSON_IsNumber(vesPort))
1777 printf("Configuration JSON is not as expected: ves-endpoint-port is not a number.");
1778 cJSON_Delete(jsonConfig);
1779 return SR_ERR_OPERATION_FAILED;
1782 //we set the value of the fault-notification-delay-period object
1783 cJSON_SetNumberValue(vesPort, new_port);
1785 //writing the new JSON to the configuration file
1786 stringConfiguration = cJSON_Print(jsonConfig);
1787 writeConfigFile(stringConfiguration);
1789 if (stringConfiguration != NULL)
1791 free(stringConfiguration);
1792 stringConfiguration = NULL;
1795 cJSON_Delete(jsonConfig);
1800 int ves_username_changed(char *new_username)
1802 char *stringConfiguration = readConfigFileInString();
1804 if (stringConfiguration == NULL)
1806 printf("Could not read configuration file!\n");
1807 return SR_ERR_OPERATION_FAILED;
1810 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
1811 if (jsonConfig == NULL)
1813 free(stringConfiguration);
1814 const char *error_ptr = cJSON_GetErrorPtr();
1815 if (error_ptr != NULL)
1817 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1819 return SR_ERR_OPERATION_FAILED;
1821 //we don't need the string anymore
1822 free(stringConfiguration);
1823 stringConfiguration = NULL;
1825 cJSON *vesDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ves-endpoint-details");
1826 if (!cJSON_IsObject(vesDetails))
1828 printf("Configuration JSON is not as expected: ves-endpoint-details is not an object");
1829 cJSON_Delete(jsonConfig);
1830 return SR_ERR_OPERATION_FAILED;
1833 cJSON *vesUsername = cJSON_GetObjectItemCaseSensitive(vesDetails, "ves-endpoint-username");
1834 if (!cJSON_IsString(vesUsername))
1836 printf("Configuration JSON is not as expected: ves-endpoint-username is not a string");
1837 cJSON_Delete(jsonConfig);
1838 return SR_ERR_OPERATION_FAILED;
1841 //we set the value of the fault-notification-delay-period object
1842 cJSON_ReplaceItemInObject(vesDetails, "ves-endpoint-username", cJSON_CreateString(new_username));
1844 //writing the new JSON to the configuration file
1845 stringConfiguration = cJSON_Print(jsonConfig);
1846 writeConfigFile(stringConfiguration);
1848 if (stringConfiguration != NULL)
1850 free(stringConfiguration);
1851 stringConfiguration = NULL;
1854 cJSON_Delete(jsonConfig);
1859 int ves_password_changed(char *new_password)
1861 char *stringConfiguration = readConfigFileInString();
1863 if (stringConfiguration == NULL)
1865 printf("Could not read configuration file!\n");
1866 return SR_ERR_OPERATION_FAILED;
1869 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
1870 if (jsonConfig == NULL)
1872 free(stringConfiguration);
1873 const char *error_ptr = cJSON_GetErrorPtr();
1874 if (error_ptr != NULL)
1876 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1878 return SR_ERR_OPERATION_FAILED;
1880 //we don't need the string anymore
1881 free(stringConfiguration);
1882 stringConfiguration = NULL;
1884 cJSON *vesDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ves-endpoint-details");
1885 if (!cJSON_IsObject(vesDetails))
1887 printf("Configuration JSON is not as expected: ves-endpoint-details is not an object");
1888 cJSON_Delete(jsonConfig);
1889 return SR_ERR_OPERATION_FAILED;
1892 cJSON *vesPassword = cJSON_GetObjectItemCaseSensitive(vesDetails, "ves-endpoint-password");
1893 if (!cJSON_IsString(vesPassword))
1895 printf("Configuration JSON is not as expected: ves-endpoint-password is not a string");
1896 cJSON_Delete(jsonConfig);
1897 return SR_ERR_OPERATION_FAILED;
1900 //we set the value of the fault-notification-delay-period object
1901 cJSON_ReplaceItemInObject(vesDetails, "ves-endpoint-password", cJSON_CreateString(new_password));
1903 //writing the new JSON to the configuration file
1904 stringConfiguration = cJSON_Print(jsonConfig);
1905 writeConfigFile(stringConfiguration);
1907 if (stringConfiguration != NULL)
1909 free(stringConfiguration);
1910 stringConfiguration = NULL;
1913 cJSON_Delete(jsonConfig);
1918 int ves_auth_method_changed(char *new_auth_method)
1920 char *stringConfiguration = readConfigFileInString();
1922 if (stringConfiguration == NULL)
1924 printf("Could not read configuration file!\n");
1925 return SR_ERR_OPERATION_FAILED;
1928 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
1929 if (jsonConfig == NULL)
1931 free(stringConfiguration);
1932 const char *error_ptr = cJSON_GetErrorPtr();
1933 if (error_ptr != NULL)
1935 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1937 return SR_ERR_OPERATION_FAILED;
1939 //we don't need the string anymore
1940 free(stringConfiguration);
1941 stringConfiguration = NULL;
1943 cJSON *vesDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ves-endpoint-details");
1944 if (!cJSON_IsObject(vesDetails))
1946 printf("Configuration JSON is not as expected: ves-endpoint-details is not an object");
1947 cJSON_Delete(jsonConfig);
1948 return SR_ERR_OPERATION_FAILED;
1951 cJSON *vesAuthMethod = cJSON_GetObjectItemCaseSensitive(vesDetails, "ves-endpoint-auth-method");
1952 if (!cJSON_IsString(vesAuthMethod))
1954 printf("Configuration JSON is not as expected: ves-endpoint-auth-method is not a string");
1955 cJSON_Delete(jsonConfig);
1956 return SR_ERR_OPERATION_FAILED;
1959 //we set the value of the fault-notification-delay-period object
1960 cJSON_ReplaceItemInObject(vesDetails, "ves-endpoint-auth-method", cJSON_CreateString(new_auth_method));
1962 //writing the new JSON to the configuration file
1963 stringConfiguration = cJSON_Print(jsonConfig);
1964 writeConfigFile(stringConfiguration);
1966 if (stringConfiguration != NULL)
1968 free(stringConfiguration);
1969 stringConfiguration = NULL;
1972 cJSON_Delete(jsonConfig);
1977 int ves_registration_changed(cJSON_bool new_bool)
1979 char *stringConfiguration = readConfigFileInString();
1981 if (stringConfiguration == NULL)
1983 printf("Could not read configuration file!\n");
1984 return SR_ERR_OPERATION_FAILED;
1987 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
1988 if (jsonConfig == NULL)
1990 free(stringConfiguration);
1991 const char *error_ptr = cJSON_GetErrorPtr();
1992 if (error_ptr != NULL)
1994 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1996 return SR_ERR_OPERATION_FAILED;
1998 //we don't need the string anymore
1999 free(stringConfiguration);
2000 stringConfiguration = NULL;
2002 cJSON *vesDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ves-endpoint-details");
2003 if (!cJSON_IsObject(vesDetails))
2005 printf("Configuration JSON is not as expected: ves-endpoint-details is not an object");
2006 cJSON_Delete(jsonConfig);
2007 return SR_ERR_OPERATION_FAILED;
2010 cJSON *vesRegistration = cJSON_GetObjectItemCaseSensitive(vesDetails, "ves-registration");
2011 if (!cJSON_IsBool(vesRegistration))
2013 printf("Configuration JSON is not as expected: ves-registration is not a bool.");
2014 cJSON_Delete(jsonConfig);
2015 return SR_ERR_OPERATION_FAILED;
2018 //we set the value of the ves-registration object
2019 cJSON_ReplaceItemInObject(vesDetails, "ves-registration", cJSON_CreateBool(new_bool));
2021 //writing the new JSON to the configuration file
2022 stringConfiguration = cJSON_Print(jsonConfig);
2023 writeConfigFile(stringConfiguration);
2025 if (stringConfiguration != NULL)
2027 free(stringConfiguration);
2028 stringConfiguration = NULL;
2031 cJSON_Delete(jsonConfig);
2036 int is_netconf_available_changed(cJSON_bool new_bool)
2038 char *stringConfiguration = readConfigFileInString();
2040 if (stringConfiguration == NULL)
2042 printf("Could not read configuration file!\n");
2043 return SR_ERR_OPERATION_FAILED;
2046 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
2047 if (jsonConfig == NULL)
2049 free(stringConfiguration);
2050 const char *error_ptr = cJSON_GetErrorPtr();
2051 if (error_ptr != NULL)
2053 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
2055 return SR_ERR_OPERATION_FAILED;
2057 //we don't need the string anymore
2058 free(stringConfiguration);
2059 stringConfiguration = NULL;
2061 cJSON *notifConfig = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
2062 if (!cJSON_IsObject(notifConfig))
2064 printf("Configuration JSON is not as expected: notification-config is not an object");
2065 cJSON_Delete(jsonConfig);
2066 return SR_ERR_OPERATION_FAILED;
2069 cJSON *isNetconfAvailable = cJSON_GetObjectItemCaseSensitive(notifConfig, "is-netconf-available");
2070 if (!cJSON_IsBool(isNetconfAvailable))
2072 printf("Configuration JSON is not as expected: is-netconf-available is not a bool.");
2073 cJSON_Delete(jsonConfig);
2074 return SR_ERR_OPERATION_FAILED;
2077 //we set the value of the ves-registration object
2078 cJSON_ReplaceItemInObject(notifConfig, "is-netconf-available", cJSON_CreateBool(new_bool));
2080 //writing the new JSON to the configuration file
2081 stringConfiguration = cJSON_Print(jsonConfig);
2082 writeConfigFile(stringConfiguration);
2084 if (stringConfiguration != NULL)
2086 free(stringConfiguration);
2087 stringConfiguration = NULL;
2090 cJSON_Delete(jsonConfig);
2095 int is_ves_available_changed(cJSON_bool new_bool)
2097 char *stringConfiguration = readConfigFileInString();
2099 if (stringConfiguration == NULL)
2101 printf("Could not read configuration file!\n");
2102 return SR_ERR_OPERATION_FAILED;
2105 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
2106 if (jsonConfig == NULL)
2108 free(stringConfiguration);
2109 const char *error_ptr = cJSON_GetErrorPtr();
2110 if (error_ptr != NULL)
2112 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
2114 return SR_ERR_OPERATION_FAILED;
2116 //we don't need the string anymore
2117 free(stringConfiguration);
2118 stringConfiguration = NULL;
2120 cJSON *notifConfig = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
2121 if (!cJSON_IsObject(notifConfig))
2123 printf("Configuration JSON is not as expected: notification-config is not an object");
2124 cJSON_Delete(jsonConfig);
2125 return SR_ERR_OPERATION_FAILED;
2128 cJSON *isVesAvailable = cJSON_GetObjectItemCaseSensitive(notifConfig, "is-ves-available");
2129 if (!cJSON_IsBool(isVesAvailable))
2131 printf("Configuration JSON is not as expected: is-ves-available is not a bool.");
2132 cJSON_Delete(jsonConfig);
2133 return SR_ERR_OPERATION_FAILED;
2136 //we set the value of the ves-registration object
2137 cJSON_ReplaceItemInObject(notifConfig, "is-ves-available", cJSON_CreateBool(new_bool));
2139 //writing the new JSON to the configuration file
2140 stringConfiguration = cJSON_Print(jsonConfig);
2141 writeConfigFile(stringConfiguration);
2143 if (stringConfiguration != NULL)
2145 free(stringConfiguration);
2146 stringConfiguration = NULL;
2149 cJSON_Delete(jsonConfig);
2154 int ssh_connections_changed(int number)
2156 char *stringConfiguration = readConfigFileInString();
2158 if (stringConfiguration == NULL)
2160 printf("Could not read configuration file!\n");
2161 return SR_ERR_OPERATION_FAILED;
2164 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
2165 if (jsonConfig == NULL)
2167 free(stringConfiguration);
2168 const char *error_ptr = cJSON_GetErrorPtr();
2169 if (error_ptr != NULL)
2171 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
2173 return SR_ERR_OPERATION_FAILED;
2175 //we don't need the string anymore
2176 free(stringConfiguration);
2177 stringConfiguration = NULL;
2179 cJSON *sshConnections = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ssh-connections");
2180 if (!cJSON_IsNumber(sshConnections))
2182 printf("Configuration JSON is not as expected: ssh-connections is not an object");
2183 cJSON_Delete(jsonConfig);
2184 return SR_ERR_OPERATION_FAILED;
2187 //we set the value of the ssh-connections object
2188 cJSON_SetNumberValue(sshConnections, number);
2190 //writing the new JSON to the configuration file
2191 stringConfiguration = cJSON_Print(jsonConfig);
2192 writeConfigFile(stringConfiguration);
2194 if (stringConfiguration != NULL)
2196 free(stringConfiguration);
2197 stringConfiguration = NULL;
2200 cJSON_Delete(jsonConfig);
2205 int tls_connections_changed(int number)
2207 char *stringConfiguration = readConfigFileInString();
2209 if (stringConfiguration == NULL)
2211 printf("Could not read configuration file!\n");
2212 return SR_ERR_OPERATION_FAILED;
2215 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
2216 if (jsonConfig == NULL)
2218 free(stringConfiguration);
2219 const char *error_ptr = cJSON_GetErrorPtr();
2220 if (error_ptr != NULL)
2222 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
2224 return SR_ERR_OPERATION_FAILED;
2226 //we don't need the string anymore
2227 free(stringConfiguration);
2228 stringConfiguration = NULL;
2230 cJSON *tlsConnections = cJSON_GetObjectItemCaseSensitive(jsonConfig, "tls-connections");
2231 if (!cJSON_IsNumber(tlsConnections))
2233 printf("Configuration JSON is not as expected: tls-connections is not an object");
2234 cJSON_Delete(jsonConfig);
2235 return SR_ERR_OPERATION_FAILED;
2238 //we set the value of the tls-connections object
2239 cJSON_SetNumberValue(tlsConnections, number);
2241 //writing the new JSON to the configuration file
2242 stringConfiguration = cJSON_Print(jsonConfig);
2243 writeConfigFile(stringConfiguration);
2245 if (stringConfiguration != NULL)
2247 free(stringConfiguration);
2248 stringConfiguration = NULL;
2251 cJSON_Delete(jsonConfig);
2257 curl -X POST -H 'Content-Type: application/json' -i http://localhost:5000/extend-ports --data '{"number-of-ports":12}'
2259 int send_k8s_extend_port(void)
2261 int num_of_ports = getSshConnectionsFromConfigJson() + getTlsConnectionsFromConfigJson();
2265 curl_easy_reset(curl_k8s);
2266 set_curl_common_info_k8s();
2268 char url_for_curl[100];
2269 sprintf(url_for_curl, "http://localhost:5000/extend-ports");
2271 curl_easy_setopt(curl_k8s, CURLOPT_URL, url_for_curl);
2273 char post_data_json[1500];
2275 sprintf(post_data_json,
2276 "{\"number-of-ports\":%d}",
2279 printf("Post data:\n%s\n", post_data_json);
2281 curl_easy_setopt(curl_k8s, CURLOPT_POSTFIELDS, post_data_json);
2282 curl_easy_setopt(curl_k8s, CURLOPT_CUSTOMREQUEST, "POST");
2284 res = curl_easy_perform(curl_k8s);
2285 if (res != CURLE_OK)
2287 printf("cURL failed to url=%s\n", url_for_curl);
2290 long http_response_code = 0;
2291 curl_easy_getinfo (curl_k8s, CURLINFO_RESPONSE_CODE, &http_response_code);
2292 if (http_response_code >= 200 && http_response_code <= 226 && http_response_code != CURLE_ABORTED_BY_CALLBACK)
2294 printf("cURL succeeded to url=%s\n", url_for_curl);
2298 printf("cURL to url=%s failed with code=%ld\n", url_for_curl, http_response_code);
2299 return SR_ERR_OPERATION_FAILED;
2306 curl -X POST -H 'Content-Type: application/json' -i http://localhost:5000/scale --data '{"simulatedDevices":2}'
2308 int send_k8s_scale(int number_of_devices)
2312 curl_easy_reset(curl_k8s);
2313 set_curl_common_info_k8s();
2315 char url_for_curl[100];
2316 sprintf(url_for_curl, "http://localhost:5000/scale");
2318 curl_easy_setopt(curl_k8s, CURLOPT_URL, url_for_curl);
2320 char post_data_json[1500];
2322 sprintf(post_data_json,
2323 "{\"simulatedDevices\":%d}",
2326 printf("Post data:\n%s\n", post_data_json);
2328 curl_easy_setopt(curl_k8s, CURLOPT_POSTFIELDS, post_data_json);
2329 curl_easy_setopt(curl_k8s, CURLOPT_CUSTOMREQUEST, "POST");
2331 res = curl_easy_perform(curl_k8s);
2332 if (res != CURLE_OK)
2334 printf("cURL failed to url=%s\n", url_for_curl);
2337 long http_response_code = 0;
2338 curl_easy_getinfo (curl_k8s, CURLINFO_RESPONSE_CODE, &http_response_code);
2339 if (http_response_code >= 200 && http_response_code <= 226 && http_response_code != CURLE_ABORTED_BY_CALLBACK)
2341 printf("cURL succeeded to url=%s\n", url_for_curl);
2345 printf("cURL to url=%s failed with code=%ld\n", url_for_curl, http_response_code);
2346 return SR_ERR_OPERATION_FAILED;
2352 int controller_ip_changed(char *new_ip)
2354 char *stringConfiguration = readConfigFileInString();
2356 if (stringConfiguration == NULL)
2358 printf("Could not read configuration file!\n");
2359 return SR_ERR_OPERATION_FAILED;
2362 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
2363 if (jsonConfig == NULL)
2365 free(stringConfiguration);
2366 const char *error_ptr = cJSON_GetErrorPtr();
2367 if (error_ptr != NULL)
2369 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
2371 return SR_ERR_OPERATION_FAILED;
2373 //we don't need the string anymore
2374 free(stringConfiguration);
2375 stringConfiguration = NULL;
2377 cJSON *controllerDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "controller-details");
2378 if (!cJSON_IsObject(controllerDetails))
2380 printf("Configuration JSON is not as expected: controller-details is not an object");
2381 cJSON_Delete(jsonConfig);
2382 return SR_ERR_OPERATION_FAILED;
2385 cJSON *controllerIp = cJSON_GetObjectItemCaseSensitive(controllerDetails, "controller-ip");
2386 if (!cJSON_IsString(controllerIp))
2388 printf("Configuration JSON is not as expected: controller-ip is not a string");
2389 cJSON_Delete(jsonConfig);
2390 return SR_ERR_OPERATION_FAILED;
2393 //we set the value of the fault-notification-delay-period object
2394 cJSON_ReplaceItemInObject(controllerDetails, "controller-ip", cJSON_CreateString(new_ip));
2396 //writing the new JSON to the configuration file
2397 stringConfiguration = cJSON_Print(jsonConfig);
2398 writeConfigFile(stringConfiguration);
2400 if (stringConfiguration != NULL)
2402 free(stringConfiguration);
2403 stringConfiguration = NULL;
2406 cJSON_Delete(jsonConfig);
2411 int controller_port_changed(int new_port)
2413 char *stringConfiguration = readConfigFileInString();
2415 if (stringConfiguration == NULL)
2417 printf("Could not read configuration file!\n");
2418 return SR_ERR_OPERATION_FAILED;
2421 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
2422 if (jsonConfig == NULL)
2424 free(stringConfiguration);
2425 const char *error_ptr = cJSON_GetErrorPtr();
2426 if (error_ptr != NULL)
2428 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
2430 return SR_ERR_OPERATION_FAILED;
2432 //we don't need the string anymore
2433 free(stringConfiguration);
2434 stringConfiguration = NULL;
2436 cJSON *controllerDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "controller-details");
2437 if (!cJSON_IsObject(controllerDetails))
2439 printf("Configuration JSON is not as expected: controller-details is not an object");
2440 cJSON_Delete(jsonConfig);
2441 return SR_ERR_OPERATION_FAILED;
2444 cJSON *controllerPort = cJSON_GetObjectItemCaseSensitive(controllerDetails, "controller-port");
2445 if (!cJSON_IsNumber(controllerPort))
2447 printf("Configuration JSON is not as expected: controller-port is not a number.");
2448 cJSON_Delete(jsonConfig);
2449 return SR_ERR_OPERATION_FAILED;
2452 //we set the value of the fault-notification-delay-period object
2453 cJSON_SetNumberValue(controllerPort, new_port);
2455 //writing the new JSON to the configuration file
2456 stringConfiguration = cJSON_Print(jsonConfig);
2457 writeConfigFile(stringConfiguration);
2459 if (stringConfiguration != NULL)
2461 free(stringConfiguration);
2462 stringConfiguration = NULL;
2465 cJSON_Delete(jsonConfig);
2470 int controller_netconf_call_home_port_changed(int new_port)
2472 char *stringConfiguration = readConfigFileInString();
2474 if (stringConfiguration == NULL)
2476 printf("Could not read configuration file!\n");
2477 return SR_ERR_OPERATION_FAILED;
2480 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
2481 if (jsonConfig == NULL)
2483 free(stringConfiguration);
2484 const char *error_ptr = cJSON_GetErrorPtr();
2485 if (error_ptr != NULL)
2487 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
2489 return SR_ERR_OPERATION_FAILED;
2491 //we don't need the string anymore
2492 free(stringConfiguration);
2493 stringConfiguration = NULL;
2495 cJSON *controllerDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "controller-details");
2496 if (!cJSON_IsObject(controllerDetails))
2498 printf("Configuration JSON is not as expected: controller-details is not an object");
2499 cJSON_Delete(jsonConfig);
2500 return SR_ERR_OPERATION_FAILED;
2503 cJSON *netconfCallHomePort = cJSON_GetObjectItemCaseSensitive(controllerDetails, "netconf-call-home-port");
2504 if (!cJSON_IsNumber(netconfCallHomePort))
2506 printf("Configuration JSON is not as expected: netconf-call-home-port is not a number.");
2507 cJSON_Delete(jsonConfig);
2508 return SR_ERR_OPERATION_FAILED;
2511 //we set the value of the fault-notification-delay-period object
2512 cJSON_SetNumberValue(netconfCallHomePort, new_port);
2514 //writing the new JSON to the configuration file
2515 stringConfiguration = cJSON_Print(jsonConfig);
2516 writeConfigFile(stringConfiguration);
2518 if (stringConfiguration != NULL)
2520 free(stringConfiguration);
2521 stringConfiguration = NULL;
2524 cJSON_Delete(jsonConfig);
2529 int controller_username_changed(char *new_username)
2531 char *stringConfiguration = readConfigFileInString();
2533 if (stringConfiguration == NULL)
2535 printf("Could not read configuration file!\n");
2536 return SR_ERR_OPERATION_FAILED;
2539 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
2540 if (jsonConfig == NULL)
2542 free(stringConfiguration);
2543 const char *error_ptr = cJSON_GetErrorPtr();
2544 if (error_ptr != NULL)
2546 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
2548 return SR_ERR_OPERATION_FAILED;
2550 //we don't need the string anymore
2551 free(stringConfiguration);
2552 stringConfiguration = NULL;
2554 cJSON *controllerDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "controller-details");
2555 if (!cJSON_IsObject(controllerDetails))
2557 printf("Configuration JSON is not as expected: controller-details is not an object");
2558 cJSON_Delete(jsonConfig);
2559 return SR_ERR_OPERATION_FAILED;
2562 cJSON *controllerUsername = cJSON_GetObjectItemCaseSensitive(controllerDetails, "controller-username");
2563 if (!cJSON_IsString(controllerUsername))
2565 printf("Configuration JSON is not as expected: controller-username is not a string");
2566 cJSON_Delete(jsonConfig);
2567 return SR_ERR_OPERATION_FAILED;
2570 //we set the value of the fault-notification-delay-period object
2571 cJSON_ReplaceItemInObject(controllerDetails, "controller-username", cJSON_CreateString(new_username));
2573 //writing the new JSON to the configuration file
2574 stringConfiguration = cJSON_Print(jsonConfig);
2575 writeConfigFile(stringConfiguration);
2577 if (stringConfiguration != NULL)
2579 free(stringConfiguration);
2580 stringConfiguration = NULL;
2583 cJSON_Delete(jsonConfig);
2588 int controller_password_changed(char *new_password)
2590 char *stringConfiguration = readConfigFileInString();
2592 if (stringConfiguration == NULL)
2594 printf("Could not read configuration file!\n");
2595 return SR_ERR_OPERATION_FAILED;
2598 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
2599 if (jsonConfig == NULL)
2601 free(stringConfiguration);
2602 const char *error_ptr = cJSON_GetErrorPtr();
2603 if (error_ptr != NULL)
2605 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
2607 return SR_ERR_OPERATION_FAILED;
2609 //we don't need the string anymore
2610 free(stringConfiguration);
2611 stringConfiguration = NULL;
2613 cJSON *controllerDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "controller-details");
2614 if (!cJSON_IsObject(controllerDetails))
2616 printf("Configuration JSON is not as expected: controller-details is not an object");
2617 cJSON_Delete(jsonConfig);
2618 return SR_ERR_OPERATION_FAILED;
2621 cJSON *controllerPassword = cJSON_GetObjectItemCaseSensitive(controllerDetails, "controller-password");
2622 if (!cJSON_IsString(controllerPassword))
2624 printf("Configuration JSON is not as expected: controller-password is not a string");
2625 cJSON_Delete(jsonConfig);
2626 return SR_ERR_OPERATION_FAILED;
2629 //we set the value of the fault-notification-delay-period object
2630 cJSON_ReplaceItemInObject(controllerDetails, "controller-password", cJSON_CreateString(new_password));
2632 //writing the new JSON to the configuration file
2633 stringConfiguration = cJSON_Print(jsonConfig);
2634 writeConfigFile(stringConfiguration);
2636 if (stringConfiguration != NULL)
2638 free(stringConfiguration);
2639 stringConfiguration = NULL;
2642 cJSON_Delete(jsonConfig);
2647 int netconf_call_home_changed(cJSON_bool new_bool)
2649 char *stringConfiguration = readConfigFileInString();
2651 if (stringConfiguration == NULL)
2653 printf("Could not read configuration file!\n");
2654 return SR_ERR_OPERATION_FAILED;
2657 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
2658 if (jsonConfig == NULL)
2660 free(stringConfiguration);
2661 const char *error_ptr = cJSON_GetErrorPtr();
2662 if (error_ptr != NULL)
2664 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
2666 return SR_ERR_OPERATION_FAILED;
2668 //we don't need the string anymore
2669 free(stringConfiguration);
2670 stringConfiguration = NULL;
2672 cJSON *netconfCallHome = cJSON_GetObjectItemCaseSensitive(jsonConfig, "netconf-call-home");
2673 if (!cJSON_IsBool(netconfCallHome))
2675 printf("Configuration JSON is not as expected: netconf-call-home is not a bool.");
2676 cJSON_Delete(jsonConfig);
2677 return SR_ERR_OPERATION_FAILED;
2680 //we set the value of the ves-registration object
2681 cJSON_ReplaceItemInObject(jsonConfig, "netconf-call-home", cJSON_CreateBool(new_bool));
2683 //writing the new JSON to the configuration file
2684 stringConfiguration = cJSON_Print(jsonConfig);
2685 writeConfigFile(stringConfiguration);
2687 if (stringConfiguration != NULL)
2689 free(stringConfiguration);
2690 stringConfiguration = NULL;
2693 cJSON_Delete(jsonConfig);
2698 static int start_device_notification(char *exec_id)
2700 struct MemoryStruct curl_response_mem;
2702 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
2703 curl_response_mem.size = 0; /* no data at this point */
2707 curl_easy_reset(curl);
2708 set_curl_common_info();
2711 sprintf(url, "http:/v%s/exec/%s/start", getenv("DOCKER_ENGINE_VERSION"), exec_id);
2713 curl_easy_setopt(curl, CURLOPT_URL, url);
2715 cJSON *postDataJson = cJSON_CreateObject();
2717 if (cJSON_AddFalseToObject(postDataJson, "Detach") == NULL)
2719 printf("Could not create JSON object: Detach\n");
2720 return SR_ERR_OPERATION_FAILED;
2723 if (cJSON_AddFalseToObject(postDataJson, "Tty") == NULL)
2725 printf("Could not create JSON object: Tty\n");
2726 return SR_ERR_OPERATION_FAILED;
2729 char *post_data_string = NULL;
2731 post_data_string = cJSON_PrintUnformatted(postDataJson);
2733 printf("Post data JSON:\n%s\n", post_data_string);
2735 if (postDataJson != NULL)
2737 cJSON_Delete(postDataJson);
2740 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data_string);
2742 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
2744 res = curl_easy_perform(curl);
2746 if (post_data_string != NULL)
2748 free(post_data_string);
2751 if (res != CURLE_OK)
2753 return SR_ERR_OPERATION_FAILED;
2757 cJSON *json_response = cJSON_Parse(curl_response_mem.memory);
2758 const cJSON *message = NULL;
2760 printf("%lu bytes retrieved\n", (unsigned long)curl_response_mem.size);
2762 message = cJSON_GetObjectItemCaseSensitive(json_response, "message");
2764 if (cJSON_IsString(message) && (message->valuestring != NULL))
2766 printf("Message: \"%s\"\n", message->valuestring);
2769 cJSON_Delete(json_response);
2775 static int inspect_device_notification_execution(char *exec_id)
2779 struct MemoryStruct curl_response_mem;
2781 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
2782 curl_response_mem.size = 0; /* no data at this point */
2786 curl_easy_reset(curl);
2787 set_curl_common_info();
2790 sprintf(url, "http:/v%s/exec/%s/json", getenv("DOCKER_ENGINE_VERSION"), exec_id);
2792 curl_easy_setopt(curl, CURLOPT_URL, url);
2794 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
2795 curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
2797 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
2799 res = curl_easy_perform(curl);
2801 if (res != CURLE_OK)
2803 rc = SR_ERR_OPERATION_FAILED;
2807 cJSON *json_response = cJSON_Parse(curl_response_mem.memory);
2808 const cJSON *exit_code = NULL;
2810 exit_code = cJSON_GetObjectItemCaseSensitive(json_response, "ExitCode");
2812 if (cJSON_IsNumber(exit_code))
2814 rc = exit_code->valueint;
2818 printf("Exit code is not a number!\n");
2819 rc = SR_ERR_OPERATION_FAILED;
2822 cJSON_Delete(json_response);
2828 int invoke_device_notification(char *device_id, char *module_name, char *notification_string)
2832 printf("Device-name = %s\nModule-name = %s\nNotification-object = %s\n", device_id, module_name, notification_string);
2834 struct MemoryStruct curl_response_mem;
2836 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
2837 curl_response_mem.size = 0; /* no data at this point */
2841 curl_easy_reset(curl);
2842 set_curl_common_info();
2845 sprintf(url, "http:/v%s/containers/%s/exec", getenv("DOCKER_ENGINE_VERSION"), device_id);
2847 curl_easy_setopt(curl, CURLOPT_URL, url);
2849 cJSON *postDataJson = cJSON_CreateObject();
2851 if (cJSON_AddFalseToObject(postDataJson, "AtttachStdin") == NULL)
2853 printf("Could not create JSON object: AtttachStdin\n");
2854 rc = SR_ERR_OPERATION_FAILED;
2858 if (cJSON_AddTrueToObject(postDataJson, "AtttachStdout") == NULL)
2860 printf("Could not create JSON object: AtttachStdout\n");
2861 rc = SR_ERR_OPERATION_FAILED;
2865 if (cJSON_AddTrueToObject(postDataJson, "AtttachStderr") == NULL)
2867 printf("Could not create JSON object: AtttachStderr\n");
2868 rc = SR_ERR_OPERATION_FAILED;
2872 if (cJSON_AddTrueToObject(postDataJson, "Privileged") == NULL)
2874 printf("Could not create JSON object: Privileged\n");
2875 rc = SR_ERR_OPERATION_FAILED;
2879 if (cJSON_AddStringToObject(postDataJson, "User", "root") == NULL)
2881 printf("Could not create JSON object: User\n");
2882 rc = SR_ERR_OPERATION_FAILED;
2886 cJSON *cmd_array = cJSON_CreateArray();
2887 if (cmd_array == NULL)
2889 printf("Could not create JSON object: Cmd array\n");
2890 rc = SR_ERR_OPERATION_FAILED;
2894 cJSON_AddItemToObject(postDataJson, "Cmd", cmd_array);
2896 cJSON *cmd_string_1 = cJSON_CreateString("sh");
2897 cJSON_AddItemToArray(cmd_array, cmd_string_1);
2899 cJSON *cmd_string_2 = cJSON_CreateString("-c");
2900 cJSON_AddItemToArray(cmd_array, cmd_string_2);
2902 //some notifications require a really long notification object
2903 char string_command[1000000];
2904 sprintf(string_command, "/usr/local/bin/generic-notifications %s '%s'", module_name, notification_string);
2906 cJSON *cmd_string_3 = cJSON_CreateString(string_command);
2907 cJSON_AddItemToArray(cmd_array, cmd_string_3);
2909 char *post_data_string = NULL;
2911 post_data_string = cJSON_PrintUnformatted(postDataJson);
2913 printf("Post data JSON:\n%s\n", post_data_string);
2915 if (postDataJson != NULL)
2917 cJSON_Delete(postDataJson);
2920 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data_string);
2922 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
2924 res = curl_easy_perform(curl);
2926 if (post_data_string != NULL)
2928 free(post_data_string);
2931 if (res != CURLE_OK)
2933 rc = SR_ERR_OPERATION_FAILED;
2938 cJSON *json_response = cJSON_Parse(curl_response_mem.memory);
2939 const cJSON *exec_id = NULL;
2941 exec_id = cJSON_GetObjectItemCaseSensitive(json_response, "Id");
2943 if (cJSON_IsString(exec_id) && (exec_id->valuestring != NULL))
2945 printf("Exec id: \"%s\"\n", exec_id->valuestring);
2947 rc = start_device_notification(exec_id->valuestring);
2948 if (rc != SR_ERR_OK)
2950 printf("Could not start the execution of the notification...\n");
2955 rc = inspect_device_notification_execution(exec_id->valuestring);
2958 cJSON_Delete(json_response);
2962 if (device_id != NULL)
2966 if (module_name != NULL)
2970 if (notification_string != NULL)
2972 free(notification_string);
2978 int pull_docker_image_of_simulated_device()
2980 struct MemoryStruct curl_response_mem;
2982 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
2983 curl_response_mem.size = 0; /* no data at this point */
2987 curl_easy_reset(curl);
2988 set_curl_common_info();
2991 sprintf(url, "http:/v%s/images/create?fromImage=%s", getenv("DOCKER_ENGINE_VERSION"), getenv("MODELS_IMAGE"));
2993 curl_easy_setopt(curl, CURLOPT_URL, url);
2995 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
2997 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
2999 curl_easy_setopt(curl, CURLOPT_TIMEOUT, 300L);
3001 res = curl_easy_perform(curl);
3003 if (res != CURLE_OK)
3005 return SR_ERR_OPERATION_FAILED;