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[50];
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 sprintf(environment_var, "NETCONF_BASE=%d", base_netconf_port);
385 cJSON *env_var_obj_2 = cJSON_CreateString(environment_var);
386 if (env_var_obj_2 == NULL)
388 printf("Could not create JSON object: Env array object NETCONF_BASE\n");
391 cJSON_AddItemToArray(env_variables_array, env_var_obj_2);
393 char scripts_dir[200];
394 sprintf(scripts_dir, "SCRIPTS_DIR=%s", getenv("SCRIPTS_DIR"));
395 cJSON *env_var_obj_3 = cJSON_CreateString(scripts_dir);
396 if (env_var_obj_3 == NULL)
398 printf("Could not create JSON object: Env array object SCRIPTS_DIR\n");
401 cJSON_AddItemToArray(env_variables_array, env_var_obj_3);
403 char k8s_deployment[50];
404 sprintf(k8s_deployment, "K8S_DEPLOYMENT=%s", getenv("K8S_DEPLOYMENT"));
405 cJSON *env_var_obj_4 = cJSON_CreateString(k8s_deployment);
406 if (env_var_obj_4 == NULL)
408 printf("Could not create JSON object: Env array object K8S_DEPLOYMENT\n");
411 cJSON_AddItemToArray(env_variables_array, env_var_obj_4);
413 char ipv6_enabled[50];
414 sprintf(ipv6_enabled, "IPv6Enabled=%s", getenv("IPv6Enabled"));
415 cJSON *env_var_obj_5 = cJSON_CreateString(ipv6_enabled);
416 if (env_var_obj_5 == NULL)
418 printf("Could not create JSON object: Env array object IPv6Enabled\n");
421 cJSON_AddItemToArray(env_variables_array, env_var_obj_5);
423 cJSON_AddItemToObject(hostConfig, "Binds", binds);
425 cJSON_AddItemToObject(hostConfig, "NetworkMode", netMode);
427 char *post_data_string = NULL;
429 post_data_string = cJSON_PrintUnformatted(postDataJson);
431 printf("Post data JSON:\n%s\n", post_data_string);
433 if (postDataJson != NULL)
435 cJSON_Delete(postDataJson);
438 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data_string);
440 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
442 res = curl_easy_perform(curl);
444 if (post_data_string != NULL)
446 free(post_data_string);
455 cJSON *json_response = cJSON_Parse(curl_response_mem.memory);
456 const cJSON *container_id = NULL;
458 printf("%lu bytes retrieved\n", (unsigned long)curl_response_mem.size);
460 container_id = cJSON_GetObjectItemCaseSensitive(json_response, "Id");
462 if (cJSON_IsString(container_id) && (container_id->valuestring != NULL))
464 printf("Container id: \"%s\"\n", container_id->valuestring);
466 char container_id_short[13];
468 memset(container_id_short, '\0', sizeof(container_id_short));
469 strncpy(container_id_short, container_id->valuestring, 12);
471 printf("Container id short: \"%s\"\n", container_id_short);
473 cJSON_Delete(json_response);
474 return strdup(container_id_short);
477 cJSON_Delete(json_response);
483 static int start_docker_container_curl(char *container_id)
485 struct MemoryStruct curl_response_mem;
487 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
488 curl_response_mem.size = 0; /* no data at this point */
492 curl_easy_reset(curl);
493 set_curl_common_info();
496 sprintf(url, "http:/v%s/containers/%s/start", getenv("DOCKER_ENGINE_VERSION"), container_id);
498 curl_easy_setopt(curl, CURLOPT_URL, url);
500 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
502 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
504 res = curl_easy_perform(curl);
508 return SR_ERR_OPERATION_FAILED;
512 printf("Container %s started successfully!\n", container_id);
518 static int rename_docker_container_curl(char *container_id, int device_number)
520 struct MemoryStruct curl_response_mem;
522 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
523 curl_response_mem.size = 0; /* no data at this point */
527 curl_easy_reset(curl);
528 set_curl_common_info();
530 char device_name[100];
531 sprintf(device_name, "%s-%d", getenv("CONTAINER_NAME"), device_number);
534 sprintf(url, "http:/v%s/containers/%s/rename?name=%s", getenv("DOCKER_ENGINE_VERSION"), container_id,
537 curl_easy_setopt(curl, CURLOPT_URL, url);
539 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
541 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
543 res = curl_easy_perform(curl);
547 return SR_ERR_OPERATION_FAILED;
551 printf("Container %s renamed successfully to %s!\n", container_id, device_name);
557 static int kill_and_remove_docker_container_curl(char *container_id)
559 struct MemoryStruct curl_response_mem;
561 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
562 curl_response_mem.size = 0; /* no data at this point */
566 curl_easy_reset(curl);
567 set_curl_common_info();
570 sprintf(url, "http:/v%s/containers/%s?force=true", getenv("DOCKER_ENGINE_VERSION"), container_id);
572 curl_easy_setopt(curl, CURLOPT_URL, url);
574 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
575 curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
577 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
579 res = curl_easy_perform(curl);
583 return SR_ERR_OPERATION_FAILED;
587 printf("Container %s removed successfully!\n", container_id);
593 static int send_mount_device_instance_ssh(char *url, char *credentials, char *device_name, int device_port)
597 curl_easy_reset(curl_odl);
598 set_curl_common_info_odl();
600 char url_for_curl[200];
601 sprintf(url_for_curl, "%s%s_%d", url, device_name, device_port);
603 curl_easy_setopt(curl_odl, CURLOPT_URL, url_for_curl);
605 char post_data_xml[1500];
607 sprintf(post_data_xml,
608 "<node xmlns=\"urn:TBD:params:xml:ns:yang:network-topology\">"
609 "<node-id>%s_%d</node-id>"
610 "<host xmlns=\"urn:opendaylight:netconf-node-topology\">%s</host>"
611 "<port xmlns=\"urn:opendaylight:netconf-node-topology\">%d</port>"
612 "<username xmlns=\"urn:opendaylight:netconf-node-topology\">%s</username>"
613 "<password xmlns=\"urn:opendaylight:netconf-node-topology\">%s</password>"
614 "<tcp-only xmlns=\"urn:opendaylight:netconf-node-topology\">false</tcp-only>"
615 "<keepalive-delay xmlns=\"urn:opendaylight:netconf-node-topology\">120</keepalive-delay>"
616 "<reconnect-on-changed-schema xmlns=\"urn:opendaylight:netconf-node-topology\">false</reconnect-on-changed-schema>"
617 "<sleep-factor xmlns=\"urn:opendaylight:netconf-node-topology\">1.5</sleep-factor>"
618 "<connection-timeout-millis xmlns=\"urn:opendaylight:netconf-node-topology\">20000</connection-timeout-millis>"
619 "<max-connection-attempts xmlns=\"urn:opendaylight:netconf-node-topology\">100</max-connection-attempts>"
620 "<between-attempts-timeout-millis xmlns=\"urn:opendaylight:netconf-node-topology\">2000</between-attempts-timeout-millis>"
622 device_name, device_port, getenv("NTS_IP"), device_port, "netconf", "netconf");
624 printf("Post data:\n%s\n", post_data_xml);
626 curl_easy_setopt(curl_odl, CURLOPT_POSTFIELDS, post_data_xml);
627 curl_easy_setopt(curl_odl, CURLOPT_CUSTOMREQUEST, "PUT");
628 curl_easy_setopt(curl_odl, CURLOPT_USERPWD, credentials);
630 res = curl_easy_perform(curl_odl);
633 printf("cURL failed to url=%s\n", url_for_curl);
636 long http_response_code = 0;
637 curl_easy_getinfo (curl_odl, CURLINFO_RESPONSE_CODE, &http_response_code);
638 if (http_response_code >= 200 && http_response_code <= 226 && http_response_code != CURLE_ABORTED_BY_CALLBACK)
640 printf("cURL succeeded to url=%s\n", url_for_curl);
644 printf("cURL to url=%s failed with code=%ld\n", url_for_curl, http_response_code);
645 return SR_ERR_OPERATION_FAILED;
651 static int send_mount_device_instance_tls(char *url, char *credentials, char *device_name, int device_port)
655 curl_easy_reset(curl_odl);
656 set_curl_common_info_odl();
658 char url_for_curl[200];
659 sprintf(url_for_curl, "%s%s_%d", url, device_name, device_port);
661 curl_easy_setopt(curl_odl, CURLOPT_URL, url_for_curl);
663 char post_data_xml[1500];
665 sprintf(post_data_xml,
666 "<node xmlns=\"urn:TBD:params:xml:ns:yang:network-topology\">"
667 "<protocol xmlns=\"urn:opendaylight:netconf-node-topology\">"
670 "<node-id>%s_%d</node-id>"
671 "<host xmlns=\"urn:opendaylight:netconf-node-topology\">%s</host>"
672 "<key-based xmlns=\"urn:opendaylight:netconf-node-topology\">"
673 "<username>%s</username>"
674 "<key-id>device-key</key-id>"
676 "<port xmlns=\"urn:opendaylight:netconf-node-topology\">%d</port>"
677 "<tcp-only xmlns=\"urn:opendaylight:netconf-node-topology\">false</tcp-only>"
678 "<keepalive-delay xmlns=\"urn:opendaylight:netconf-node-topology\">120</keepalive-delay>"
679 "<reconnect-on-changed-schema xmlns=\"urn:opendaylight:netconf-node-topology\">false</reconnect-on-changed-schema>"
680 "<sleep-factor xmlns=\"urn:opendaylight:netconf-node-topology\">1.5</sleep-factor>"
681 "<connection-timeout-millis xmlns=\"urn:opendaylight:netconf-node-topology\">20000</connection-timeout-millis>"
682 "<max-connection-attempts xmlns=\"urn:opendaylight:netconf-node-topology\">100</max-connection-attempts>"
683 "<between-attempts-timeout-millis xmlns=\"urn:opendaylight:netconf-node-topology\">2000</between-attempts-timeout-millis>"
685 device_name, device_port, getenv("NTS_IP"), "netconf", device_port);
687 printf("Post data:\n%s\n", post_data_xml);
689 curl_easy_setopt(curl_odl, CURLOPT_POSTFIELDS, post_data_xml);
690 curl_easy_setopt(curl_odl, CURLOPT_CUSTOMREQUEST, "PUT");
691 curl_easy_setopt(curl_odl, CURLOPT_USERPWD, credentials);
693 res = curl_easy_perform(curl_odl);
696 printf("cURL failed to url=%s\n", url_for_curl);
699 long http_response_code = 0;
700 curl_easy_getinfo (curl_odl, CURLINFO_RESPONSE_CODE, &http_response_code);
701 if (http_response_code >= 200 && http_response_code <= 226 && http_response_code != CURLE_ABORTED_BY_CALLBACK)
703 printf("cURL succeeded to url=%s\n", url_for_curl);
707 printf("cURL to url=%s failed with code=%ld\n", url_for_curl, http_response_code);
708 return SR_ERR_OPERATION_FAILED;
714 static int send_unmount_device_instance(char *url, char *credentials, char *device_name, int device_port)
718 curl_easy_reset(curl_odl);
719 set_curl_common_info_odl();
721 char url_for_curl[200];
722 sprintf(url_for_curl, "%s%s_%d", url, device_name, device_port);
724 curl_easy_setopt(curl_odl, CURLOPT_URL, url_for_curl);
726 curl_easy_setopt(curl_odl, CURLOPT_POSTFIELDS, "");
727 curl_easy_setopt(curl_odl, CURLOPT_CUSTOMREQUEST, "DELETE");
728 curl_easy_setopt(curl_odl, CURLOPT_USERPWD, credentials);
730 res = curl_easy_perform(curl_odl);
733 printf("cURL failed to url=%s\n", url_for_curl);
736 long http_response_code = 0;
737 curl_easy_getinfo (curl_odl, CURLINFO_RESPONSE_CODE, &http_response_code);
738 if (http_response_code == 200 && http_response_code != CURLE_ABORTED_BY_CALLBACK)
740 printf("cURL succeeded to url=%s\n", url_for_curl);
744 printf("cURL to url=%s failed with code=%ld\n", url_for_curl, http_response_code);
745 return SR_ERR_OPERATION_FAILED;
752 static int send_mount_device(device_t *current_device, controller_t controller_details)
755 bool is_mounted = true;
758 char device_name[100];
759 sprintf(device_name, "%s-%d", getenv("CONTAINER_NAME"), current_device->device_number);
761 //This is where we hardcoded: 7 devices will have SSH connections and 3 devices will have TLS connections
762 for (int i = 0; i < SSH_CONNECTIONS_PER_DEVICE; ++port, ++i)
766 rc = send_mount_device_instance_ssh(controller_details.url, controller_details.credentials,
767 device_name, current_device->netconf_port + port);
773 for (int i = 0; i < TLS_CONNECTIONS_PER_DEVICE; ++port, ++i)
775 rc = send_mount_device_instance_tls(controller_details.url, controller_details.credentials,
776 device_name, current_device->netconf_port + port);
783 current_device->is_mounted = is_mounted;
788 static int send_unmount_device(device_t *current_device, controller_t controller_details)
791 char device_name[100];
792 sprintf(device_name, "%s-%d", getenv("CONTAINER_NAME"), current_device->device_number);
794 for (int port = 0; port < NETCONF_CONNECTIONS_PER_DEVICE; ++port)
796 rc = send_unmount_device_instance(controller_details.url, controller_details.credentials,
797 device_name, current_device->netconf_port + port);
800 printf("Could not send unmount for ODL with url=\"%s\", for device=\"%s\" and port=%d\n",
801 controller_details.url, device_name, current_device->netconf_port);
804 current_device->is_mounted = false;
809 device_stack_t *new_device_stack(void)
811 device_stack_t *stack = malloc(sizeof(*stack));
815 stack->stack_size = 0;
820 void push_device(device_stack_t *theStack, char *dev_id, int port, int dev_num)
822 device_t *new_dev = malloc(sizeof(*new_dev));
825 new_dev->device_id = strdup(dev_id);
826 new_dev->netconf_port = port;
827 new_dev->device_number = dev_num;
828 new_dev->is_mounted = false;
829 new_dev->operational_state = strdup("not-specified");
831 new_dev->next = theStack->head;
833 theStack->head = new_dev;
834 theStack->stack_size++;
838 void pop_device(device_stack_t *theStack)
840 if (theStack && theStack->head) {
841 device_t *temp = theStack->head;
842 theStack->head = theStack->head->next;
844 free(temp->device_id);
845 free(temp->operational_state);
847 theStack->stack_size--;
851 int get_netconf_port_next(device_stack_t *theStack)
853 if (theStack && theStack->stack_size > 0) {
854 return theStack->head->netconf_port + NETCONF_CONNECTIONS_PER_DEVICE;
857 return get_netconf_port_base();
860 int get_netconf_port_base()
862 int netconf_port_base;
864 netconf_port_base = getIntFromString(getenv("NETCONF_BASE"), 50000);
866 return netconf_port_base;
869 // we start numbering the containers from 0
870 int get_device_number_next(device_stack_t *theStack)
872 if (theStack && theStack->stack_size > 0) {
873 return theStack->head->device_number + 1;
879 char *get_id_last_device(device_stack_t *theStack)
881 if (theStack && theStack->head) {
882 return theStack->head->device_id;
887 int get_current_number_of_mounted_devices(device_stack_t *theStack)
889 int mounted_devices = 0;
891 if (theStack && theStack->head)
893 device_t *current_device = theStack->head;
895 while (current_device != NULL)
897 if (current_device->is_mounted)
901 current_device = current_device->next;
905 return mounted_devices;
908 int get_current_number_of_devices(device_stack_t *theStack)
910 //TODO implement function for k8s deployment
911 if (strcmp(getenv("K8S_DEPLOYMENT"), "true") == 0)
916 struct MemoryStruct curl_response_mem;
918 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
919 curl_response_mem.size = 0; /* no data at this point */
923 curl_easy_reset(curl);
924 set_curl_common_info();
927 sprintf(url, "http:/v%s/containers/json?all=true&filters={\"label\":[\"NTS_Manager=%s\"],\"status\":[\"running\"]}",
928 getenv("DOCKER_ENGINE_VERSION"), getenv("HOSTNAME"));
930 curl_easy_setopt(curl, CURLOPT_URL, url);
932 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
933 curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
935 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
937 res = curl_easy_perform(curl);
941 return SR_ERR_OPERATION_FAILED;
945 cJSON *json_response = cJSON_Parse(curl_response_mem.memory);
947 printf("%lu bytes retrieved\n", (unsigned long)curl_response_mem.size);
949 if (json_response == NULL || !cJSON_IsArray(json_response))
951 printf("Could not parse JSON response for url=\"%s\"\n", url);
952 return SR_ERR_OPERATION_FAILED;
955 int num_of_devices = cJSON_GetArraySize(json_response);
956 cJSON_Delete(json_response);
958 return num_of_devices;
964 static int set_operational_state_of_device(device_stack_t *theStack, char *device_id, char *operational_state)
966 if (theStack && theStack->head)
968 device_t *current_device = theStack->head;
970 while (current_device != NULL)
972 if (strcmp(current_device->device_id, device_id) == 0)
974 free(current_device->operational_state);
975 current_device->operational_state = strdup(operational_state);
980 current_device = current_device->next;
984 printf("Could not find device with uuid=\"%s\"\n", device_id);
985 return SR_ERR_OPERATION_FAILED;
988 char* get_docker_container_operational_state(device_stack_t *theStack, char *container_id)
990 if (theStack && theStack->head)
992 device_t *current_device = theStack->head;
994 while (current_device != NULL)
996 if (strcmp(current_device->device_id, container_id) == 0)
998 return current_device->operational_state;
1001 current_device = current_device->next;
1008 int start_device(device_stack_t *theStack)
1011 static cJSON *managerBindings = NULL, *networkMode = NULL;
1013 if (managerBindings == NULL)
1015 managerBindings = get_docker_container_bindings();
1018 if (networkMode == NULL)
1020 networkMode = get_docker_container_network_node();
1023 int netconf_base = get_netconf_port_next(theStack);
1024 int device_number = get_device_number_next(theStack);
1026 char *dev_id = create_docker_container_curl(netconf_base, managerBindings, networkMode, device_number);
1029 printf("ERROR: Could not create docker container!\n");
1030 return SR_ERR_OPERATION_FAILED;
1033 push_device(theStack, dev_id, netconf_base, device_number);
1035 rc = start_docker_container_curl(dev_id);
1036 if (rc != SR_ERR_OK)
1038 printf("Could not start device with device_id=\"%s\"\n", dev_id);
1041 rc = rename_docker_container_curl(dev_id, device_number);
1042 if (rc != SR_ERR_OK)
1044 printf("Could not rename device with device_id=\"%s\"\n", dev_id);
1056 curl = curl_easy_init();
1059 printf("cURL initialization error! Aborting call!\n");
1060 return SR_ERR_OPERATION_FAILED;
1070 curl_easy_cleanup(curl);
1076 int _init_curl_odl()
1078 curl_odl = curl_easy_init();
1080 if (curl_odl == NULL) {
1081 printf("cURL initialization error! Aborting call!\n");
1082 return SR_ERR_OPERATION_FAILED;
1088 int cleanup_curl_odl()
1090 if (curl_odl != NULL)
1092 curl_easy_cleanup(curl_odl);
1098 int _init_curl_k8s()
1100 curl_k8s = curl_easy_init();
1102 if (curl_k8s == NULL) {
1103 printf("cURL initialization error! Aborting call!\n");
1104 return SR_ERR_OPERATION_FAILED;
1110 int cleanup_curl_k8s()
1112 if (curl_k8s != NULL)
1114 curl_easy_cleanup(curl_k8s);
1120 int stop_device(device_stack_t *theStack)
1123 char *last_id = get_id_last_device(theStack);
1125 rc = kill_and_remove_docker_container_curl(last_id);
1126 if (rc != SR_ERR_OK)
1128 printf("Could not kill and remove docker container with uuid=\"%s\"\n", last_id);
1131 rc = removeDeviceEntryFromStatusFile(last_id);
1132 if (rc != SR_ERR_OK)
1134 printf("Could not remove entry from status file for uuid=\"%s\"\n", last_id);
1137 pop_device(theStack);
1142 int mount_device(device_stack_t *theStack, controller_t controller_details)
1146 if (theStack && theStack->head)
1148 device_t *current_device = theStack->head;
1149 while (current_device != NULL && current_device->is_mounted == true)
1151 printf("Device \"%s\" is already mounted, skipping...\n", current_device->device_id);
1152 current_device = current_device->next;
1155 if (current_device != NULL)
1157 printf("Sending mount device for device \"%s\"...\n", current_device->device_id);
1158 rc = send_mount_device(current_device, controller_details);
1159 if (rc != SR_ERR_OK)
1161 return SR_ERR_OPERATION_FAILED;
1169 int unmount_device(device_stack_t *theStack, controller_t controller_list)
1173 if (theStack && theStack->head)
1175 device_t *current_device = theStack->head;
1176 while (current_device != NULL && current_device->is_mounted == false)
1178 printf("Device \"%s\" is already unmounted, skipping...\n", current_device->device_id);
1179 current_device = current_device->next;
1182 if (current_device != NULL)
1184 printf("Sending unmount device for device \"%s\"...\n", current_device->device_id);
1185 rc = send_unmount_device(current_device, controller_list);
1186 if (rc != SR_ERR_OK)
1188 return SR_ERR_OPERATION_FAILED;
1196 int get_docker_containers_operational_state_curl(device_stack_t *theStack)
1199 //TODO implement function for k8s deployment
1200 if (strcmp(getenv("K8S_DEPLOYMENT"), "true") == 0)
1206 struct MemoryStruct curl_response_mem;
1208 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
1209 curl_response_mem.size = 0; /* no data at this point */
1213 curl_easy_reset(curl);
1214 set_curl_common_info();
1217 sprintf(url, "http:/v%s/containers/json?all=true&filters={\"label\":[\"NTS_Manager=%s\"]}",
1218 getenv("DOCKER_ENGINE_VERSION"), getenv("HOSTNAME"));
1220 curl_easy_setopt(curl, CURLOPT_URL, url);
1222 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
1223 curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
1225 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
1227 res = curl_easy_perform(curl);
1229 if (res != CURLE_OK)
1231 return SR_ERR_OPERATION_FAILED;
1235 cJSON *json_response = cJSON_Parse(curl_response_mem.memory);
1236 const cJSON *container = NULL;
1238 printf("%lu bytes retrieved\n", (unsigned long)curl_response_mem.size);
1240 if (json_response == NULL || !cJSON_IsArray(json_response))
1242 printf("Could not parse JSON response for url=\"%s\"\n", url);
1243 return SR_ERR_OPERATION_FAILED;
1246 cJSON_ArrayForEach(container, json_response)
1248 cJSON *container_id_long = cJSON_GetObjectItemCaseSensitive(container, "Id");
1249 cJSON *state = cJSON_GetObjectItemCaseSensitive(container, "State");
1251 if (cJSON_IsString(container_id_long) && (container_id_long->valuestring != NULL))
1253 char container_id_short[13];
1255 memset(container_id_short, '\0', sizeof(container_id_short));
1256 strncpy(container_id_short, container_id_long->valuestring, 12);
1258 if (cJSON_IsString(state) && (state->valuestring != NULL))
1260 rc = set_operational_state_of_device(theStack, container_id_short, state->valuestring);
1261 if (rc != SR_ERR_OK)
1263 printf("Could not set the operational state for the device with uuid=\"%s\"\n", container_id_short);
1264 return SR_ERR_OPERATION_FAILED;
1270 cJSON_Delete(json_response);
1276 char* get_docker_container_resource_stats(device_stack_t *theStack)
1278 //TOD need to implement this for k8s deployment
1279 if (strcmp(getenv("K8S_DEPLOYMENT"), "true"))
1281 return strdup("CPU=0%;RAM=0MiB");
1284 char line[LINE_BUFSIZE];
1288 /* Get a pipe where the output from the scripts comes in */
1290 sprintf(script, "/opt/dev/docker_stats.sh %s", getenv("HOSTNAME"));
1292 pipe = popen(script, "r");
1293 if (pipe == NULL) { /* check for errors */
1294 printf("Could not open script.\n");
1295 return NULL; /* return with exit code indicating error */
1298 /* Read script output from the pipe line by line */
1300 while (fgets(line, LINE_BUFSIZE, pipe) != NULL) {
1301 printf("Script output line %d: %s", linenr, line);
1304 pclose(pipe); /* Close the pipe */
1305 return strdup(line);
1308 /* Once here, out of the loop, the script has ended. */
1309 pclose(pipe); /* Close the pipe */
1310 return NULL; /* return with exit code indicating success. */
1313 int notification_delay_period_changed(sr_val_t *val, size_t count)
1315 char *stringConfiguration = readConfigFileInString();
1317 if (stringConfiguration == NULL)
1319 printf("Could not read configuration file!\n");
1320 return SR_ERR_OPERATION_FAILED;
1323 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
1324 if (jsonConfig == NULL)
1326 free(stringConfiguration);
1327 const char *error_ptr = cJSON_GetErrorPtr();
1328 if (error_ptr != NULL)
1330 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1332 return SR_ERR_OPERATION_FAILED;
1334 //we don't need the string anymore
1335 free(stringConfiguration);
1336 stringConfiguration = NULL;
1338 cJSON *notifConfig = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
1339 if (!cJSON_IsObject(notifConfig))
1341 printf("Configuration JSON is not as expected: notification-config is not an object");
1342 cJSON_Delete(jsonConfig);
1343 return SR_ERR_OPERATION_FAILED;
1346 cJSON *faultNotifDelay = cJSON_GetObjectItemCaseSensitive(notifConfig, "fault-notification-delay-period");
1347 if (!cJSON_IsArray(faultNotifDelay))
1349 printf("Configuration JSON is not as expected: fault-notification-delay-period is not an array.");
1350 cJSON_Delete(jsonConfig);
1351 return SR_ERR_OPERATION_FAILED;
1354 cJSON_DeleteItemFromObject(notifConfig, "fault-notification-delay-period");
1356 faultNotifDelay = NULL;
1358 faultNotifDelay = cJSON_CreateArray();
1359 if (faultNotifDelay == NULL)
1361 cJSON_Delete(jsonConfig);
1362 return SR_ERR_OPERATION_FAILED;
1364 cJSON_AddItemToObject(notifConfig, "fault-notification-delay-period", faultNotifDelay);
1366 if (val != NULL && count > 0)
1368 cJSON *arrayEntry = NULL;
1369 for (size_t i=0; i<count; ++i)
1371 arrayEntry = cJSON_CreateNumber(val[i].data.uint32_val);
1372 if (arrayEntry == NULL)
1374 cJSON_Delete(jsonConfig);
1375 return SR_ERR_OPERATION_FAILED;
1377 cJSON_AddItemToArray(faultNotifDelay, arrayEntry);
1382 cJSON *arrayEntry = cJSON_CreateNumber(0);
1383 if (arrayEntry == NULL)
1385 cJSON_Delete(jsonConfig);
1386 return SR_ERR_OPERATION_FAILED;
1388 cJSON_AddItemToArray(faultNotifDelay, arrayEntry);
1391 //writing the new JSON to the configuration file
1392 stringConfiguration = cJSON_Print(jsonConfig);
1393 writeConfigFile(stringConfiguration);
1395 if (stringConfiguration != NULL)
1397 free(stringConfiguration);
1398 stringConfiguration = NULL;
1401 cJSON_Delete(jsonConfig);
1406 int ves_heartbeat_period_changed(int period)
1408 char *stringConfiguration = readConfigFileInString();
1410 if (stringConfiguration == NULL)
1412 printf("Could not read configuration file!\n");
1413 return SR_ERR_OPERATION_FAILED;
1416 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
1417 if (jsonConfig == NULL)
1419 free(stringConfiguration);
1420 const char *error_ptr = cJSON_GetErrorPtr();
1421 if (error_ptr != NULL)
1423 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1425 return SR_ERR_OPERATION_FAILED;
1427 //we don't need the string anymore
1428 free(stringConfiguration);
1429 stringConfiguration = NULL;
1431 cJSON *notifConfig = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
1432 if (!cJSON_IsObject(notifConfig))
1434 printf("Configuration JSON is not as expected: notification-config is not an object");
1435 cJSON_Delete(jsonConfig);
1436 return SR_ERR_OPERATION_FAILED;
1439 cJSON *vesHeartbeatPeriod = cJSON_GetObjectItemCaseSensitive(notifConfig, "ves-heartbeat-period");
1440 if (!cJSON_IsNumber(vesHeartbeatPeriod))
1442 printf("Configuration JSON is not as expected: ves-heartbeat-period is not an object");
1443 cJSON_Delete(jsonConfig);
1444 return SR_ERR_OPERATION_FAILED;
1447 //we set the value of the fault-notification-delay-period object
1448 cJSON_SetNumberValue(vesHeartbeatPeriod, period);
1450 //writing the new JSON to the configuration file
1451 stringConfiguration = cJSON_Print(jsonConfig);
1452 writeConfigFile(stringConfiguration);
1454 if (stringConfiguration != NULL)
1456 free(stringConfiguration);
1457 stringConfiguration = NULL;
1460 cJSON_Delete(jsonConfig);
1465 static int add_keystore_entry_odl(char *url, char *credentials)
1469 curl_easy_reset(curl_odl);
1470 set_curl_common_info_odl();
1472 char url_for_curl[200];
1473 sprintf(url_for_curl, "%s", url);
1475 curl_easy_setopt(curl_odl, CURLOPT_URL, url_for_curl);
1477 char post_data_xml[2000];
1479 sprintf(post_data_xml,
1480 "<input xmlns=\"urn:opendaylight:netconf:keystore\">"
1482 "<key-id>device-key</key-id>"
1483 "<private-key>MIIEpAIBAAKCAQEAueCQaNQWoNmFK6LKu1p8U8ZWdWg/PvDdLsJyzfzl/Qw4UA68"
1484 "SfFNaY06zZl8QB9W02nr5kWeeMY0VA3adrPgOlvfx3oWlFbkETnMaN4OT3WTQ0Wt"
1485 "6jAWZDzVfopwpJPAzRPxACDftIqFGagYcF32hZlVNqqnVdbXh0S0EViweqp/dbG4"
1486 "VDUHSNVbglc+u4UbEzNIFXMdEFsJZpkynOmSiTsIATqIhb+2srkVgLwhfkC2qkuH"
1487 "QwAHdubuB07ObM2z01UhyEdDvEYGHwtYAGDBL2TAcsI0oGeVkRyuOkV0QY0UN7UE"
1488 "FI1yTYw+xZ42HgFx3uGwApCImxhbj69GBYWFqwIDAQABAoIBAQCZN9kR8DGu6V7y"
1489 "t0Ax68asL8O5B/OKaHWKQ9LqpVrXmikZJOxkbzoGldow/CIFoU+q+Zbwu9aDa65a"
1490 "0wiP7Hoa4Py3q5XNNUrOQDyU/OYC7cI0I83WS0lJ2zOJGYj8wKae5Z81IeQFKGHK"
1491 "4lsy1OGPAvPRGh7RjUUgRavA2MCwe07rWRuDb/OJFe4Oh56UMEjwMiNBtMNtncog"
1492 "j1vr/qgRJdf9tf0zlJmLvUJ9+HSFFV9I/97LJyFhb95gAfHkjdVroLVgT3Cho+4P"
1493 "WtZaKCIGD0OwfOG2nLV4leXvRUk62/LMlB8NI9+JF7Xm+HCKbaWHNWC7mvWSLV58"
1494 "Zl4AbUWRAoGBANyJ6SFHFRHSPDY026SsdMzXR0eUxBAK7G70oSBKKhY+O1j0ocLE"
1495 "jI2krHJBhHbLlnvJVyMUaCUOTS5m0uDw9hgSsAqeSL3hL38kxVZw+KNG9Ouno1Fl"
1496 "KnE/xXHlPQyeGs/P8nAMzHZxQtEsQdQayJEhK2XXHTsy7Q3MxDisfVJ1AoGBANfD"
1497 "34gB+OMx6pwj7zk3qWbYXSX8xjCZMR0ciko+h4xeMP2N8B0oyoqC+v1ABMAtJ3wG"
1498 "sGZd0hV9gwM7OUM3SEwkn6oeg1GemWLcn4rlSmTnZc4aeVwrEWlnSNFX3s4g9l4u"
1499 "k8Ugu4MVJYqH8HuDQ5Ggl6/QAwPzMSEdCW0O+jOfAoGAIBRbegC5+t6m7Yegz4Ja"
1500 "dxV1g98K6f58x+MDsQu4tYWV4mmrQgaPH2dtwizvlMwmdpkh+LNWNtWuumowkJHc"
1501 "akIFo3XExQIFg6wYnGtQb4e5xrGa2xMpKlIJaXjb+YLiCYqJDG2ALFZrTrvuU2kV"
1502 "9a5qfqTc1qigvNolTM0iaaUCgYApmrZWhnLUdEKV2wP813PNxfioI4afxlpHD8LG"
1503 "sCn48gymR6E+Lihn7vuwq5B+8fYEH1ISWxLwW+RQUjIneNhy/jjfV8TgjyFqg7or"
1504 "0Sy4KjpiNI6kLBXOakELRNNMkeSPopGR2E7v5rr3bGD9oAD+aqX1G7oJH/KgPPYd"
1505 "Vl7+ZwKBgQDcHyWYrimjyUgKaQD2GmoO9wdcJYQ59ke9K+OuGlp4ti5arsi7N1tP"
1506 "B4f09aeELM2ASIuk8Q/Mx0jQFnm8lzRFXdewgvdPoZW/7VufM9O7dGPOc41cm2Dh"
1507 "yrTcXx/VmUBb+/fnXVEgCv7gylp/wtdTGHQBQJHR81jFBz0lnLj+gg==</private-key>"
1508 "<passphrase></passphrase>"
1512 printf("Post data:\n%s\n", post_data_xml);
1514 curl_easy_setopt(curl_odl, CURLOPT_POSTFIELDS, post_data_xml);
1515 curl_easy_setopt(curl_odl, CURLOPT_CUSTOMREQUEST, "POST");
1516 curl_easy_setopt(curl_odl, CURLOPT_USERPWD, credentials);
1518 res = curl_easy_perform(curl_odl);
1519 if (res != CURLE_OK)
1521 printf("cURL failed to url=%s\n", url_for_curl);
1524 long http_response_code = 0;
1525 curl_easy_getinfo (curl_odl, CURLINFO_RESPONSE_CODE, &http_response_code);
1526 if (http_response_code >= 200 && http_response_code <= 226 && http_response_code != CURLE_ABORTED_BY_CALLBACK)
1528 printf("cURL succeeded to url=%s\n", url_for_curl);
1532 printf("cURL to url=%s failed with code=%ld\n", url_for_curl, http_response_code);
1533 return SR_ERR_OPERATION_FAILED;
1539 static int add_private_key_odl(char *url, char *credentials)
1543 curl_easy_reset(curl_odl);
1544 set_curl_common_info_odl();
1546 char url_for_curl[200];
1547 sprintf(url_for_curl, "%s", url);
1549 curl_easy_setopt(curl_odl, CURLOPT_URL, url_for_curl);
1551 char post_data_xml[4000];
1553 sprintf(post_data_xml,
1554 "<input xmlns=\"urn:opendaylight:netconf:keystore\">"
1556 "<name>device-key</name>"
1557 "<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>"
1558 "<certificate-chain>MIIECTCCAvGgAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBjDELMAkGA1UEBhMCQ1oxFjAUBgNVBAgMDVNvdXRoIE1vcmF2aWExDTALBgNVBAcMBEJybm8xDzANBgNVBAoMBkNFU05FVDEMMAoGA1UECwwDVE1DMRMwEQYDVQQDDApleGFtcGxlIENBMSIwIAYJKoZIhvcNAQkBFhNleGFtcGxlY2FAbG9jYWxob3N0MB4XDTE1MDczMDA3MjcxOFoXDTM1MDcyNTA3MjcxOFowgYUxCzAJBgNVBAYTAkNaMRYwFAYDVQQIDA1Tb3V0aCBNb3JhdmlhMQ8wDQYDVQQKDAZDRVNORVQxDDAKBgNVBAsMA1RNQzEXMBUGA1UEAwwOZXhhbXBsZSBjbGllbnQxJjAkBgkqhkiG9w0BCQEWF2V4YW1wbGVjbGllbnRAbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAueCQaNQWoNmFK6LKu1p8U8ZWdWg/PvDdLsJyzfzl/Qw4UA68SfFNaY06zZl8QB9W02nr5kWeeMY0VA3adrPgOlvfx3oWlFbkETnMaN4OT3WTQ0Wt6jAWZDzVfopwpJPAzRPxACDftIqFGagYcF32hZlVNqqnVdbXh0S0EViweqp/dbG4VDUHSNVbglc+u4UbEzNIFXMdEFsJZpkynOmSiTsIATqIhb+2srkVgLwhfkC2qkuHQwAHdubuB07ObM2z01UhyEdDvEYGHwtYAGDBL2TAcsI0oGeVkRyuOkV0QY0UN7UEFI1yTYw+xZ42HgFx3uGwApCImxhbj69GBYWFqwIDAQABo3sweTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUXGpLeLnh2cSDARAVA7KrBxGYpo8wHwYDVR0jBBgwFoAUc1YQIqjZsHVwlea0AB4N+ilNI2gwDQYJKoZIhvcNAQELBQADggEBAJPV3RTXFRtNyOU4rjPpYeBAIAFp2aqGc4t2J1c7oPp/1n+lZvjnwtlJpZHxMM783e2ryDQ6dkvXDf8kpwKlg3U3mkJ3xKkDdWrM4QwghXdCN519aa9qmu0zdFL+jUAaWlQ5tsceOrvbusCcbMqiFGk/QfpHqPv52SVWbYyUx7IX7DE+UjgsLHycfV/tlcx4ZE6soTzl9VdgSL/zmzG3rjsr58J80rXckLgBhvijgBlIAJvWfC7D0vaouvBInSFXymdPVoUDZ30cdGLf+hI/i/TfsEMOinLrXVdkSGNo6FXAHKSvXeB9oFKSzhQ7OPyRyqvEPycUSw/qD6FVr80oDDc=</certificate-chain>"
1562 printf("Post data:\n%s\n", post_data_xml);
1564 curl_easy_setopt(curl_odl, CURLOPT_POSTFIELDS, post_data_xml);
1565 curl_easy_setopt(curl_odl, CURLOPT_CUSTOMREQUEST, "POST");
1566 curl_easy_setopt(curl_odl, CURLOPT_USERPWD, credentials);
1568 res = curl_easy_perform(curl_odl);
1569 if (res != CURLE_OK)
1571 printf("cURL failed to url=%s\n", url_for_curl);
1574 long http_response_code = 0;
1575 curl_easy_getinfo (curl_odl, CURLINFO_RESPONSE_CODE, &http_response_code);
1576 if (http_response_code >= 200 && http_response_code <= 226 && http_response_code != CURLE_ABORTED_BY_CALLBACK)
1578 printf("cURL succeeded to url=%s\n", url_for_curl);
1582 printf("cURL to url=%s failed with code=%ld\n", url_for_curl, http_response_code);
1583 return SR_ERR_OPERATION_FAILED;
1589 static int add_trusted_ca_odl(char *url, char *credentials)
1593 curl_easy_reset(curl_odl);
1594 set_curl_common_info_odl();
1596 char url_for_curl[200];
1597 sprintf(url_for_curl, "%s", url);
1599 curl_easy_setopt(curl_odl, CURLOPT_URL, url_for_curl);
1601 char post_data_xml[2000];
1603 sprintf(post_data_xml,
1604 "<input xmlns=\"urn:opendaylight:netconf:keystore\">"
1605 "<trusted-certificate>"
1606 "<name>test_trusted_cert</name>"
1607 "<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>"
1608 "</trusted-certificate>"
1611 printf("Post data:\n%s\n", post_data_xml);
1613 curl_easy_setopt(curl_odl, CURLOPT_POSTFIELDS, post_data_xml);
1614 curl_easy_setopt(curl_odl, CURLOPT_CUSTOMREQUEST, "POST");
1615 curl_easy_setopt(curl_odl, CURLOPT_USERPWD, credentials);
1617 res = curl_easy_perform(curl_odl);
1618 if (res != CURLE_OK)
1620 printf("cURL failed to url=%s\n", url_for_curl);
1623 long http_response_code = 0;
1624 curl_easy_getinfo (curl_odl, CURLINFO_RESPONSE_CODE, &http_response_code);
1625 if (http_response_code >= 200 && http_response_code <= 226 && http_response_code != CURLE_ABORTED_BY_CALLBACK)
1627 printf("cURL succeeded to url=%s\n", url_for_curl);
1631 printf("cURL to url=%s failed with code=%ld\n", url_for_curl, http_response_code);
1632 return SR_ERR_OPERATION_FAILED;
1638 int add_key_pair_to_odl(controller_t *controller_list, int controller_list_size)
1642 rc = add_keystore_entry_odl(controller_list[0].url_for_keystore_add, controller_list[0].credentials);
1643 if (rc != SR_ERR_OK)
1645 printf("Failed to add keystore entry to ODL.\n");
1648 rc = add_private_key_odl(controller_list[0].url_for_private_key_add, controller_list[0].credentials);
1649 if (rc != SR_ERR_OK)
1651 printf("Failed to add private key entry to ODL.\n");
1654 rc = add_trusted_ca_odl(controller_list[0].url_for_trusted_ca_add, controller_list[0].credentials);
1655 if (rc != SR_ERR_OK)
1657 printf("Failed to add trusted CA entry to ODL.\n");
1663 int ves_ip_changed(char *new_ip)
1665 char *stringConfiguration = readConfigFileInString();
1667 if (stringConfiguration == NULL)
1669 printf("Could not read configuration file!\n");
1670 return SR_ERR_OPERATION_FAILED;
1673 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
1674 if (jsonConfig == NULL)
1676 free(stringConfiguration);
1677 const char *error_ptr = cJSON_GetErrorPtr();
1678 if (error_ptr != NULL)
1680 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1682 return SR_ERR_OPERATION_FAILED;
1684 //we don't need the string anymore
1685 free(stringConfiguration);
1686 stringConfiguration = NULL;
1688 cJSON *vesDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ves-endpoint-details");
1689 if (!cJSON_IsObject(vesDetails))
1691 printf("Configuration JSON is not as expected: ves-endpoint-details is not an object");
1692 cJSON_Delete(jsonConfig);
1693 return SR_ERR_OPERATION_FAILED;
1696 cJSON *vesIp = cJSON_GetObjectItemCaseSensitive(vesDetails, "ves-endpoint-ip");
1697 if (!cJSON_IsString(vesIp))
1699 printf("Configuration JSON is not as expected: ves-endpoint-ip is not a string");
1700 cJSON_Delete(jsonConfig);
1701 return SR_ERR_OPERATION_FAILED;
1704 //we set the value of the fault-notification-delay-period object
1705 cJSON_ReplaceItemInObject(vesDetails, "ves-endpoint-ip", cJSON_CreateString(new_ip));
1707 //writing the new JSON to the configuration file
1708 stringConfiguration = cJSON_Print(jsonConfig);
1709 writeConfigFile(stringConfiguration);
1711 if (stringConfiguration != NULL)
1713 free(stringConfiguration);
1714 stringConfiguration = NULL;
1717 cJSON_Delete(jsonConfig);
1722 int ves_port_changed(int new_port)
1724 char *stringConfiguration = readConfigFileInString();
1726 if (stringConfiguration == NULL)
1728 printf("Could not read configuration file!\n");
1729 return SR_ERR_OPERATION_FAILED;
1732 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
1733 if (jsonConfig == NULL)
1735 free(stringConfiguration);
1736 const char *error_ptr = cJSON_GetErrorPtr();
1737 if (error_ptr != NULL)
1739 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1741 return SR_ERR_OPERATION_FAILED;
1743 //we don't need the string anymore
1744 free(stringConfiguration);
1745 stringConfiguration = NULL;
1747 cJSON *vesDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ves-endpoint-details");
1748 if (!cJSON_IsObject(vesDetails))
1750 printf("Configuration JSON is not as expected: ves-endpoint-details is not an object");
1751 cJSON_Delete(jsonConfig);
1752 return SR_ERR_OPERATION_FAILED;
1755 cJSON *vesPort = cJSON_GetObjectItemCaseSensitive(vesDetails, "ves-endpoint-port");
1756 if (!cJSON_IsNumber(vesPort))
1758 printf("Configuration JSON is not as expected: ves-endpoint-port is not a number.");
1759 cJSON_Delete(jsonConfig);
1760 return SR_ERR_OPERATION_FAILED;
1763 //we set the value of the fault-notification-delay-period object
1764 cJSON_SetNumberValue(vesPort, new_port);
1766 //writing the new JSON to the configuration file
1767 stringConfiguration = cJSON_Print(jsonConfig);
1768 writeConfigFile(stringConfiguration);
1770 if (stringConfiguration != NULL)
1772 free(stringConfiguration);
1773 stringConfiguration = NULL;
1776 cJSON_Delete(jsonConfig);
1781 int ves_registration_changed(cJSON_bool new_bool)
1783 char *stringConfiguration = readConfigFileInString();
1785 if (stringConfiguration == NULL)
1787 printf("Could not read configuration file!\n");
1788 return SR_ERR_OPERATION_FAILED;
1791 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
1792 if (jsonConfig == NULL)
1794 free(stringConfiguration);
1795 const char *error_ptr = cJSON_GetErrorPtr();
1796 if (error_ptr != NULL)
1798 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1800 return SR_ERR_OPERATION_FAILED;
1802 //we don't need the string anymore
1803 free(stringConfiguration);
1804 stringConfiguration = NULL;
1806 cJSON *vesDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ves-endpoint-details");
1807 if (!cJSON_IsObject(vesDetails))
1809 printf("Configuration JSON is not as expected: ves-endpoint-details is not an object");
1810 cJSON_Delete(jsonConfig);
1811 return SR_ERR_OPERATION_FAILED;
1814 cJSON *vesRegistration = cJSON_GetObjectItemCaseSensitive(vesDetails, "ves-registration");
1815 if (!cJSON_IsBool(vesRegistration))
1817 printf("Configuration JSON is not as expected: ves-registration is not a bool.");
1818 cJSON_Delete(jsonConfig);
1819 return SR_ERR_OPERATION_FAILED;
1822 //we set the value of the ves-registration object
1823 cJSON_ReplaceItemInObject(vesDetails, "ves-registration", cJSON_CreateBool(new_bool));
1825 //writing the new JSON to the configuration file
1826 stringConfiguration = cJSON_Print(jsonConfig);
1827 writeConfigFile(stringConfiguration);
1829 if (stringConfiguration != NULL)
1831 free(stringConfiguration);
1832 stringConfiguration = NULL;
1835 cJSON_Delete(jsonConfig);
1840 int is_netconf_available_changed(cJSON_bool new_bool)
1842 char *stringConfiguration = readConfigFileInString();
1844 if (stringConfiguration == NULL)
1846 printf("Could not read configuration file!\n");
1847 return SR_ERR_OPERATION_FAILED;
1850 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
1851 if (jsonConfig == NULL)
1853 free(stringConfiguration);
1854 const char *error_ptr = cJSON_GetErrorPtr();
1855 if (error_ptr != NULL)
1857 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1859 return SR_ERR_OPERATION_FAILED;
1861 //we don't need the string anymore
1862 free(stringConfiguration);
1863 stringConfiguration = NULL;
1865 cJSON *notifConfig = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
1866 if (!cJSON_IsObject(notifConfig))
1868 printf("Configuration JSON is not as expected: notification-config is not an object");
1869 cJSON_Delete(jsonConfig);
1870 return SR_ERR_OPERATION_FAILED;
1873 cJSON *isNetconfAvailable = cJSON_GetObjectItemCaseSensitive(notifConfig, "is-netconf-available");
1874 if (!cJSON_IsBool(isNetconfAvailable))
1876 printf("Configuration JSON is not as expected: is-netconf-available is not a bool.");
1877 cJSON_Delete(jsonConfig);
1878 return SR_ERR_OPERATION_FAILED;
1881 //we set the value of the ves-registration object
1882 cJSON_ReplaceItemInObject(notifConfig, "is-netconf-available", cJSON_CreateBool(new_bool));
1884 //writing the new JSON to the configuration file
1885 stringConfiguration = cJSON_Print(jsonConfig);
1886 writeConfigFile(stringConfiguration);
1888 if (stringConfiguration != NULL)
1890 free(stringConfiguration);
1891 stringConfiguration = NULL;
1894 cJSON_Delete(jsonConfig);
1899 int is_ves_available_changed(cJSON_bool new_bool)
1901 char *stringConfiguration = readConfigFileInString();
1903 if (stringConfiguration == NULL)
1905 printf("Could not read configuration file!\n");
1906 return SR_ERR_OPERATION_FAILED;
1909 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
1910 if (jsonConfig == NULL)
1912 free(stringConfiguration);
1913 const char *error_ptr = cJSON_GetErrorPtr();
1914 if (error_ptr != NULL)
1916 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1918 return SR_ERR_OPERATION_FAILED;
1920 //we don't need the string anymore
1921 free(stringConfiguration);
1922 stringConfiguration = NULL;
1924 cJSON *notifConfig = cJSON_GetObjectItemCaseSensitive(jsonConfig, "notification-config");
1925 if (!cJSON_IsObject(notifConfig))
1927 printf("Configuration JSON is not as expected: notification-config is not an object");
1928 cJSON_Delete(jsonConfig);
1929 return SR_ERR_OPERATION_FAILED;
1932 cJSON *isVesAvailable = cJSON_GetObjectItemCaseSensitive(notifConfig, "is-ves-available");
1933 if (!cJSON_IsBool(isVesAvailable))
1935 printf("Configuration JSON is not as expected: is-ves-available is not a bool.");
1936 cJSON_Delete(jsonConfig);
1937 return SR_ERR_OPERATION_FAILED;
1940 //we set the value of the ves-registration object
1941 cJSON_ReplaceItemInObject(notifConfig, "is-ves-available", cJSON_CreateBool(new_bool));
1943 //writing the new JSON to the configuration file
1944 stringConfiguration = cJSON_Print(jsonConfig);
1945 writeConfigFile(stringConfiguration);
1947 if (stringConfiguration != NULL)
1949 free(stringConfiguration);
1950 stringConfiguration = NULL;
1953 cJSON_Delete(jsonConfig);
1958 int ssh_connections_changed(int number)
1960 char *stringConfiguration = readConfigFileInString();
1962 if (stringConfiguration == NULL)
1964 printf("Could not read configuration file!\n");
1965 return SR_ERR_OPERATION_FAILED;
1968 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
1969 if (jsonConfig == NULL)
1971 free(stringConfiguration);
1972 const char *error_ptr = cJSON_GetErrorPtr();
1973 if (error_ptr != NULL)
1975 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
1977 return SR_ERR_OPERATION_FAILED;
1979 //we don't need the string anymore
1980 free(stringConfiguration);
1981 stringConfiguration = NULL;
1983 cJSON *sshConnections = cJSON_GetObjectItemCaseSensitive(jsonConfig, "ssh-connections");
1984 if (!cJSON_IsNumber(sshConnections))
1986 printf("Configuration JSON is not as expected: ssh-connections is not an object");
1987 cJSON_Delete(jsonConfig);
1988 return SR_ERR_OPERATION_FAILED;
1991 //we set the value of the ssh-connections object
1992 cJSON_SetNumberValue(sshConnections, number);
1994 //writing the new JSON to the configuration file
1995 stringConfiguration = cJSON_Print(jsonConfig);
1996 writeConfigFile(stringConfiguration);
1998 if (stringConfiguration != NULL)
2000 free(stringConfiguration);
2001 stringConfiguration = NULL;
2004 cJSON_Delete(jsonConfig);
2009 int tls_connections_changed(int number)
2011 char *stringConfiguration = readConfigFileInString();
2013 if (stringConfiguration == NULL)
2015 printf("Could not read configuration file!\n");
2016 return SR_ERR_OPERATION_FAILED;
2019 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
2020 if (jsonConfig == NULL)
2022 free(stringConfiguration);
2023 const char *error_ptr = cJSON_GetErrorPtr();
2024 if (error_ptr != NULL)
2026 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
2028 return SR_ERR_OPERATION_FAILED;
2030 //we don't need the string anymore
2031 free(stringConfiguration);
2032 stringConfiguration = NULL;
2034 cJSON *tlsConnections = cJSON_GetObjectItemCaseSensitive(jsonConfig, "tls-connections");
2035 if (!cJSON_IsNumber(tlsConnections))
2037 printf("Configuration JSON is not as expected: tls-connections is not an object");
2038 cJSON_Delete(jsonConfig);
2039 return SR_ERR_OPERATION_FAILED;
2042 //we set the value of the tls-connections object
2043 cJSON_SetNumberValue(tlsConnections, number);
2045 //writing the new JSON to the configuration file
2046 stringConfiguration = cJSON_Print(jsonConfig);
2047 writeConfigFile(stringConfiguration);
2049 if (stringConfiguration != NULL)
2051 free(stringConfiguration);
2052 stringConfiguration = NULL;
2055 cJSON_Delete(jsonConfig);
2061 curl -X POST -H 'Content-Type: application/json' -i http://localhost:5000/extend-ports --data '{"number-of-ports":12}'
2063 int send_k8s_extend_port(void)
2065 int num_of_ports = getSshConnectionsFromConfigJson() + getTlsConnectionsFromConfigJson();
2069 curl_easy_reset(curl_k8s);
2070 set_curl_common_info_k8s();
2072 char url_for_curl[100];
2073 sprintf(url_for_curl, "http://localhost:5000/extend-ports");
2075 curl_easy_setopt(curl_k8s, CURLOPT_URL, url_for_curl);
2077 char post_data_json[1500];
2079 sprintf(post_data_json,
2080 "{\"number-of-ports\":%d}",
2083 printf("Post data:\n%s\n", post_data_json);
2085 curl_easy_setopt(curl_k8s, CURLOPT_POSTFIELDS, post_data_json);
2086 curl_easy_setopt(curl_k8s, CURLOPT_CUSTOMREQUEST, "POST");
2088 res = curl_easy_perform(curl_k8s);
2089 if (res != CURLE_OK)
2091 printf("cURL failed to url=%s\n", url_for_curl);
2094 long http_response_code = 0;
2095 curl_easy_getinfo (curl_k8s, CURLINFO_RESPONSE_CODE, &http_response_code);
2096 if (http_response_code >= 200 && http_response_code <= 226 && http_response_code != CURLE_ABORTED_BY_CALLBACK)
2098 printf("cURL succeeded to url=%s\n", url_for_curl);
2102 printf("cURL to url=%s failed with code=%ld\n", url_for_curl, http_response_code);
2103 return SR_ERR_OPERATION_FAILED;
2110 curl -X POST -H 'Content-Type: application/json' -i http://localhost:5000/scale --data '{"simulatedDevices":2}'
2112 int send_k8s_scale(int number_of_devices)
2116 curl_easy_reset(curl_k8s);
2117 set_curl_common_info_k8s();
2119 char url_for_curl[100];
2120 sprintf(url_for_curl, "http://localhost:5000/scale");
2122 curl_easy_setopt(curl_k8s, CURLOPT_URL, url_for_curl);
2124 char post_data_json[1500];
2126 sprintf(post_data_json,
2127 "{\"simulatedDevices\":%d}",
2130 printf("Post data:\n%s\n", post_data_json);
2132 curl_easy_setopt(curl_k8s, CURLOPT_POSTFIELDS, post_data_json);
2133 curl_easy_setopt(curl_k8s, CURLOPT_CUSTOMREQUEST, "POST");
2135 res = curl_easy_perform(curl_k8s);
2136 if (res != CURLE_OK)
2138 printf("cURL failed to url=%s\n", url_for_curl);
2141 long http_response_code = 0;
2142 curl_easy_getinfo (curl_k8s, CURLINFO_RESPONSE_CODE, &http_response_code);
2143 if (http_response_code >= 200 && http_response_code <= 226 && http_response_code != CURLE_ABORTED_BY_CALLBACK)
2145 printf("cURL succeeded to url=%s\n", url_for_curl);
2149 printf("cURL to url=%s failed with code=%ld\n", url_for_curl, http_response_code);
2150 return SR_ERR_OPERATION_FAILED;
2156 int controller_ip_changed(char *new_ip)
2158 char *stringConfiguration = readConfigFileInString();
2160 if (stringConfiguration == NULL)
2162 printf("Could not read configuration file!\n");
2163 return SR_ERR_OPERATION_FAILED;
2166 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
2167 if (jsonConfig == NULL)
2169 free(stringConfiguration);
2170 const char *error_ptr = cJSON_GetErrorPtr();
2171 if (error_ptr != NULL)
2173 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
2175 return SR_ERR_OPERATION_FAILED;
2177 //we don't need the string anymore
2178 free(stringConfiguration);
2179 stringConfiguration = NULL;
2181 cJSON *controllerDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "controller-details");
2182 if (!cJSON_IsObject(controllerDetails))
2184 printf("Configuration JSON is not as expected: controller-details is not an object");
2185 cJSON_Delete(jsonConfig);
2186 return SR_ERR_OPERATION_FAILED;
2189 cJSON *controllerIp = cJSON_GetObjectItemCaseSensitive(controllerDetails, "controller-ip");
2190 if (!cJSON_IsString(controllerIp))
2192 printf("Configuration JSON is not as expected: controller-ip is not a string");
2193 cJSON_Delete(jsonConfig);
2194 return SR_ERR_OPERATION_FAILED;
2197 //we set the value of the fault-notification-delay-period object
2198 cJSON_ReplaceItemInObject(controllerDetails, "controller-ip", cJSON_CreateString(new_ip));
2200 //writing the new JSON to the configuration file
2201 stringConfiguration = cJSON_Print(jsonConfig);
2202 writeConfigFile(stringConfiguration);
2204 if (stringConfiguration != NULL)
2206 free(stringConfiguration);
2207 stringConfiguration = NULL;
2210 cJSON_Delete(jsonConfig);
2215 int controller_port_changed(int new_port)
2217 char *stringConfiguration = readConfigFileInString();
2219 if (stringConfiguration == NULL)
2221 printf("Could not read configuration file!\n");
2222 return SR_ERR_OPERATION_FAILED;
2225 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
2226 if (jsonConfig == NULL)
2228 free(stringConfiguration);
2229 const char *error_ptr = cJSON_GetErrorPtr();
2230 if (error_ptr != NULL)
2232 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
2234 return SR_ERR_OPERATION_FAILED;
2236 //we don't need the string anymore
2237 free(stringConfiguration);
2238 stringConfiguration = NULL;
2240 cJSON *controllerDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "controller-details");
2241 if (!cJSON_IsObject(controllerDetails))
2243 printf("Configuration JSON is not as expected: controller-details is not an object");
2244 cJSON_Delete(jsonConfig);
2245 return SR_ERR_OPERATION_FAILED;
2248 cJSON *controllerPort = cJSON_GetObjectItemCaseSensitive(controllerDetails, "controller-port");
2249 if (!cJSON_IsNumber(controllerPort))
2251 printf("Configuration JSON is not as expected: controller-port is not a number.");
2252 cJSON_Delete(jsonConfig);
2253 return SR_ERR_OPERATION_FAILED;
2256 //we set the value of the fault-notification-delay-period object
2257 cJSON_SetNumberValue(controllerPort, new_port);
2259 //writing the new JSON to the configuration file
2260 stringConfiguration = cJSON_Print(jsonConfig);
2261 writeConfigFile(stringConfiguration);
2263 if (stringConfiguration != NULL)
2265 free(stringConfiguration);
2266 stringConfiguration = NULL;
2269 cJSON_Delete(jsonConfig);
2274 int controller_netconf_call_home_port_changed(int new_port)
2276 char *stringConfiguration = readConfigFileInString();
2278 if (stringConfiguration == NULL)
2280 printf("Could not read configuration file!\n");
2281 return SR_ERR_OPERATION_FAILED;
2284 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
2285 if (jsonConfig == NULL)
2287 free(stringConfiguration);
2288 const char *error_ptr = cJSON_GetErrorPtr();
2289 if (error_ptr != NULL)
2291 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
2293 return SR_ERR_OPERATION_FAILED;
2295 //we don't need the string anymore
2296 free(stringConfiguration);
2297 stringConfiguration = NULL;
2299 cJSON *controllerDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "controller-details");
2300 if (!cJSON_IsObject(controllerDetails))
2302 printf("Configuration JSON is not as expected: controller-details is not an object");
2303 cJSON_Delete(jsonConfig);
2304 return SR_ERR_OPERATION_FAILED;
2307 cJSON *netconfCallHomePort = cJSON_GetObjectItemCaseSensitive(controllerDetails, "netconf-call-home-port");
2308 if (!cJSON_IsNumber(netconfCallHomePort))
2310 printf("Configuration JSON is not as expected: netconf-call-home-port is not a number.");
2311 cJSON_Delete(jsonConfig);
2312 return SR_ERR_OPERATION_FAILED;
2315 //we set the value of the fault-notification-delay-period object
2316 cJSON_SetNumberValue(netconfCallHomePort, new_port);
2318 //writing the new JSON to the configuration file
2319 stringConfiguration = cJSON_Print(jsonConfig);
2320 writeConfigFile(stringConfiguration);
2322 if (stringConfiguration != NULL)
2324 free(stringConfiguration);
2325 stringConfiguration = NULL;
2328 cJSON_Delete(jsonConfig);
2333 int controller_username_changed(char *new_username)
2335 char *stringConfiguration = readConfigFileInString();
2337 if (stringConfiguration == NULL)
2339 printf("Could not read configuration file!\n");
2340 return SR_ERR_OPERATION_FAILED;
2343 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
2344 if (jsonConfig == NULL)
2346 free(stringConfiguration);
2347 const char *error_ptr = cJSON_GetErrorPtr();
2348 if (error_ptr != NULL)
2350 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
2352 return SR_ERR_OPERATION_FAILED;
2354 //we don't need the string anymore
2355 free(stringConfiguration);
2356 stringConfiguration = NULL;
2358 cJSON *controllerDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "controller-details");
2359 if (!cJSON_IsObject(controllerDetails))
2361 printf("Configuration JSON is not as expected: controller-details is not an object");
2362 cJSON_Delete(jsonConfig);
2363 return SR_ERR_OPERATION_FAILED;
2366 cJSON *controllerUsername = cJSON_GetObjectItemCaseSensitive(controllerDetails, "controller-username");
2367 if (!cJSON_IsString(controllerUsername))
2369 printf("Configuration JSON is not as expected: controller-username is not a string");
2370 cJSON_Delete(jsonConfig);
2371 return SR_ERR_OPERATION_FAILED;
2374 //we set the value of the fault-notification-delay-period object
2375 cJSON_ReplaceItemInObject(controllerDetails, "controller-username", cJSON_CreateString(new_username));
2377 //writing the new JSON to the configuration file
2378 stringConfiguration = cJSON_Print(jsonConfig);
2379 writeConfigFile(stringConfiguration);
2381 if (stringConfiguration != NULL)
2383 free(stringConfiguration);
2384 stringConfiguration = NULL;
2387 cJSON_Delete(jsonConfig);
2392 int controller_password_changed(char *new_password)
2394 char *stringConfiguration = readConfigFileInString();
2396 if (stringConfiguration == NULL)
2398 printf("Could not read configuration file!\n");
2399 return SR_ERR_OPERATION_FAILED;
2402 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
2403 if (jsonConfig == NULL)
2405 free(stringConfiguration);
2406 const char *error_ptr = cJSON_GetErrorPtr();
2407 if (error_ptr != NULL)
2409 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
2411 return SR_ERR_OPERATION_FAILED;
2413 //we don't need the string anymore
2414 free(stringConfiguration);
2415 stringConfiguration = NULL;
2417 cJSON *controllerDetails = cJSON_GetObjectItemCaseSensitive(jsonConfig, "controller-details");
2418 if (!cJSON_IsObject(controllerDetails))
2420 printf("Configuration JSON is not as expected: controller-details is not an object");
2421 cJSON_Delete(jsonConfig);
2422 return SR_ERR_OPERATION_FAILED;
2425 cJSON *controllerPassword = cJSON_GetObjectItemCaseSensitive(controllerDetails, "controller-password");
2426 if (!cJSON_IsString(controllerPassword))
2428 printf("Configuration JSON is not as expected: controller-password is not a string");
2429 cJSON_Delete(jsonConfig);
2430 return SR_ERR_OPERATION_FAILED;
2433 //we set the value of the fault-notification-delay-period object
2434 cJSON_ReplaceItemInObject(controllerDetails, "controller-password", cJSON_CreateString(new_password));
2436 //writing the new JSON to the configuration file
2437 stringConfiguration = cJSON_Print(jsonConfig);
2438 writeConfigFile(stringConfiguration);
2440 if (stringConfiguration != NULL)
2442 free(stringConfiguration);
2443 stringConfiguration = NULL;
2446 cJSON_Delete(jsonConfig);
2451 int netconf_call_home_changed(cJSON_bool new_bool)
2453 char *stringConfiguration = readConfigFileInString();
2455 if (stringConfiguration == NULL)
2457 printf("Could not read configuration file!\n");
2458 return SR_ERR_OPERATION_FAILED;
2461 cJSON *jsonConfig = cJSON_Parse(stringConfiguration);
2462 if (jsonConfig == NULL)
2464 free(stringConfiguration);
2465 const char *error_ptr = cJSON_GetErrorPtr();
2466 if (error_ptr != NULL)
2468 fprintf(stderr, "Could not parse JSON configuration! Error before: %s\n", error_ptr);
2470 return SR_ERR_OPERATION_FAILED;
2472 //we don't need the string anymore
2473 free(stringConfiguration);
2474 stringConfiguration = NULL;
2476 cJSON *netconfCallHome = cJSON_GetObjectItemCaseSensitive(jsonConfig, "netconf-call-home");
2477 if (!cJSON_IsBool(netconfCallHome))
2479 printf("Configuration JSON is not as expected: netconf-call-home is not a bool.");
2480 cJSON_Delete(jsonConfig);
2481 return SR_ERR_OPERATION_FAILED;
2484 //we set the value of the ves-registration object
2485 cJSON_ReplaceItemInObject(jsonConfig, "netconf-call-home", cJSON_CreateBool(new_bool));
2487 //writing the new JSON to the configuration file
2488 stringConfiguration = cJSON_Print(jsonConfig);
2489 writeConfigFile(stringConfiguration);
2491 if (stringConfiguration != NULL)
2493 free(stringConfiguration);
2494 stringConfiguration = NULL;
2497 cJSON_Delete(jsonConfig);
2502 static int start_device_notification(char *exec_id)
2504 struct MemoryStruct curl_response_mem;
2506 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
2507 curl_response_mem.size = 0; /* no data at this point */
2511 curl_easy_reset(curl);
2512 set_curl_common_info();
2515 sprintf(url, "http:/v%s/exec/%s/start", getenv("DOCKER_ENGINE_VERSION"), exec_id);
2517 curl_easy_setopt(curl, CURLOPT_URL, url);
2519 cJSON *postDataJson = cJSON_CreateObject();
2521 if (cJSON_AddFalseToObject(postDataJson, "Detach") == NULL)
2523 printf("Could not create JSON object: Detach\n");
2524 return SR_ERR_OPERATION_FAILED;
2527 if (cJSON_AddFalseToObject(postDataJson, "Tty") == NULL)
2529 printf("Could not create JSON object: Tty\n");
2530 return SR_ERR_OPERATION_FAILED;
2533 char *post_data_string = NULL;
2535 post_data_string = cJSON_PrintUnformatted(postDataJson);
2537 printf("Post data JSON:\n%s\n", post_data_string);
2539 if (postDataJson != NULL)
2541 cJSON_Delete(postDataJson);
2544 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data_string);
2546 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
2548 res = curl_easy_perform(curl);
2550 if (post_data_string != NULL)
2552 free(post_data_string);
2555 if (res != CURLE_OK)
2557 return SR_ERR_OPERATION_FAILED;
2561 cJSON *json_response = cJSON_Parse(curl_response_mem.memory);
2562 const cJSON *message = NULL;
2564 printf("%lu bytes retrieved\n", (unsigned long)curl_response_mem.size);
2566 message = cJSON_GetObjectItemCaseSensitive(json_response, "message");
2568 if (cJSON_IsString(message) && (message->valuestring != NULL))
2570 printf("Message: \"%s\"\n", message->valuestring);
2573 cJSON_Delete(json_response);
2579 static int inspect_device_notification_execution(char *exec_id)
2583 struct MemoryStruct curl_response_mem;
2585 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
2586 curl_response_mem.size = 0; /* no data at this point */
2590 curl_easy_reset(curl);
2591 set_curl_common_info();
2594 sprintf(url, "http:/v%s/exec/%s/json", getenv("DOCKER_ENGINE_VERSION"), exec_id);
2596 curl_easy_setopt(curl, CURLOPT_URL, url);
2598 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
2599 curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
2601 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
2603 res = curl_easy_perform(curl);
2605 if (res != CURLE_OK)
2607 rc = SR_ERR_OPERATION_FAILED;
2611 cJSON *json_response = cJSON_Parse(curl_response_mem.memory);
2612 const cJSON *exit_code = NULL;
2614 exit_code = cJSON_GetObjectItemCaseSensitive(json_response, "ExitCode");
2616 if (cJSON_IsNumber(exit_code))
2618 rc = exit_code->valueint;
2622 printf("Exit code is not a number!\n");
2623 rc = SR_ERR_OPERATION_FAILED;
2626 cJSON_Delete(json_response);
2632 int invoke_device_notification(char *device_id, char *module_name, char *notification_string)
2636 printf("Device-name = %s\nModule-name = %s\nNotification-object = %s\n", device_id, module_name, notification_string);
2638 struct MemoryStruct curl_response_mem;
2640 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
2641 curl_response_mem.size = 0; /* no data at this point */
2645 curl_easy_reset(curl);
2646 set_curl_common_info();
2649 sprintf(url, "http:/v%s/containers/%s/exec", getenv("DOCKER_ENGINE_VERSION"), device_id);
2651 curl_easy_setopt(curl, CURLOPT_URL, url);
2653 cJSON *postDataJson = cJSON_CreateObject();
2655 if (cJSON_AddFalseToObject(postDataJson, "AtttachStdin") == NULL)
2657 printf("Could not create JSON object: AtttachStdin\n");
2658 rc = SR_ERR_OPERATION_FAILED;
2662 if (cJSON_AddTrueToObject(postDataJson, "AtttachStdout") == NULL)
2664 printf("Could not create JSON object: AtttachStdout\n");
2665 rc = SR_ERR_OPERATION_FAILED;
2669 if (cJSON_AddTrueToObject(postDataJson, "AtttachStderr") == NULL)
2671 printf("Could not create JSON object: AtttachStderr\n");
2672 rc = SR_ERR_OPERATION_FAILED;
2676 if (cJSON_AddTrueToObject(postDataJson, "Privileged") == NULL)
2678 printf("Could not create JSON object: Privileged\n");
2679 rc = SR_ERR_OPERATION_FAILED;
2683 if (cJSON_AddStringToObject(postDataJson, "User", "root") == NULL)
2685 printf("Could not create JSON object: User\n");
2686 rc = SR_ERR_OPERATION_FAILED;
2690 cJSON *cmd_array = cJSON_CreateArray();
2691 if (cmd_array == NULL)
2693 printf("Could not create JSON object: Cmd array\n");
2694 rc = SR_ERR_OPERATION_FAILED;
2698 cJSON_AddItemToObject(postDataJson, "Cmd", cmd_array);
2700 cJSON *cmd_string_1 = cJSON_CreateString("sh");
2701 cJSON_AddItemToArray(cmd_array, cmd_string_1);
2703 cJSON *cmd_string_2 = cJSON_CreateString("-c");
2704 cJSON_AddItemToArray(cmd_array, cmd_string_2);
2706 char string_command[500];
2707 sprintf(string_command, "/usr/local/bin/generic-notifications %s '%s'", module_name, notification_string);
2709 cJSON *cmd_string_3 = cJSON_CreateString(string_command);
2710 cJSON_AddItemToArray(cmd_array, cmd_string_3);
2712 char *post_data_string = NULL;
2714 post_data_string = cJSON_PrintUnformatted(postDataJson);
2716 printf("Post data JSON:\n%s\n", post_data_string);
2718 if (postDataJson != NULL)
2720 cJSON_Delete(postDataJson);
2723 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data_string);
2725 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
2727 res = curl_easy_perform(curl);
2729 if (post_data_string != NULL)
2731 free(post_data_string);
2734 if (res != CURLE_OK)
2736 rc = SR_ERR_OPERATION_FAILED;
2741 cJSON *json_response = cJSON_Parse(curl_response_mem.memory);
2742 const cJSON *exec_id = NULL;
2744 exec_id = cJSON_GetObjectItemCaseSensitive(json_response, "Id");
2746 if (cJSON_IsString(exec_id) && (exec_id->valuestring != NULL))
2748 printf("Exec id: \"%s\"\n", exec_id->valuestring);
2750 rc = start_device_notification(exec_id->valuestring);
2751 if (rc != SR_ERR_OK)
2753 printf("Could not start the execution of the notification...\n");
2758 rc = inspect_device_notification_execution(exec_id->valuestring);
2761 cJSON_Delete(json_response);
2765 if (device_id != NULL)
2769 if (module_name != NULL)
2773 if (notification_string != NULL)
2775 free(notification_string);
2781 int pull_docker_image_of_simulated_device()
2783 struct MemoryStruct curl_response_mem;
2785 curl_response_mem.memory = malloc(1); /* will be grown as needed by the realloc above */
2786 curl_response_mem.size = 0; /* no data at this point */
2790 curl_easy_reset(curl);
2791 set_curl_common_info();
2794 sprintf(url, "http:/v%s/images/create?fromImage=%s", getenv("DOCKER_ENGINE_VERSION"), getenv("MODELS_IMAGE"));
2796 curl_easy_setopt(curl, CURLOPT_URL, url);
2798 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
2800 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&curl_response_mem);
2802 res = curl_easy_perform(curl);
2804 if (res != CURLE_OK)
2806 return SR_ERR_OPERATION_FAILED;