1 /*************************************************************************
3 * Copyright 2020 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 ***************************************************************************/
20 #include "nts_utils.h"
21 #include "utils/log_utils.h"
22 #include "utils/sys_utils.h"
23 #include "core/framework.h"
24 #include "core/session.h"
25 #include "core/xpath.h"
31 cJSON* ves_create_common_event_header(const char *domain, const char *event_type, const char *hostname, int port, const char *priority, int seq_id) {
38 long useconds = get_microseconds_since_epoch();
40 asprintf(&eventId, "%s-%d", event_type, seq_id);
42 log_error("asprintf failed\n");
46 cJSON *common_event_header = cJSON_CreateObject();
47 if(common_event_header == 0) {
48 log_error("could not create JSON object\n");
53 if(cJSON_AddStringToObject(common_event_header, "domain", domain) == 0) {
54 log_error("cJSON AddStringToObject error\n");
56 cJSON_Delete(common_event_header);
60 if(cJSON_AddStringToObject(common_event_header, "eventId", eventId) == 0) {
61 log_error("cJSON AddStringToObject error\n");
63 cJSON_Delete(common_event_header);
69 if(cJSON_AddStringToObject(common_event_header, "eventName", event_type) == 0) {
70 log_error("cJSON AddStringToObject error\n");
71 cJSON_Delete(common_event_header);
75 if(cJSON_AddNumberToObject(common_event_header, "sequence", (double)(seq_id)) == 0) {
76 log_error("cJSON AddNumberToObject error\n");
77 cJSON_Delete(common_event_header);
81 if(cJSON_AddStringToObject(common_event_header, "priority", priority) == 0) {
82 log_error("cJSON AddStringToObject error\n");
83 cJSON_Delete(common_event_header);
87 if(cJSON_AddStringToObject(common_event_header, "reportingEntityId", "") == 0) {
88 log_error("cJSON AddStringToObject error\n");
89 cJSON_Delete(common_event_header);
93 char source_name[512];
95 sprintf(source_name, "%s-%d", hostname, port);
98 sprintf(source_name, "%s", hostname);
101 if(cJSON_AddStringToObject(common_event_header, "reportingEntityName", source_name) == 0) {
102 log_error("cJSON AddStringToObject error\n");
103 cJSON_Delete(common_event_header);
107 if(cJSON_AddStringToObject(common_event_header, "sourceId", "") == 0) {
108 log_error("cJSON AddStringToObject error\n");
109 cJSON_Delete(common_event_header);
113 if(cJSON_AddStringToObject(common_event_header, "sourceName", source_name) == 0) {
114 log_error("cJSON AddStringToObject error\n");
115 cJSON_Delete(common_event_header);
119 if(cJSON_AddNumberToObject(common_event_header, "startEpochMicrosec", (double)(useconds)) == 0) {
120 log_error("cJSON AddNumberToObject error\n");
121 cJSON_Delete(common_event_header);
125 if(cJSON_AddNumberToObject(common_event_header, "lastEpochMicrosec", (double)(useconds)) == 0) {
126 log_error("cJSON AddNumberToObject error\n");
127 cJSON_Delete(common_event_header);
131 if(cJSON_AddStringToObject(common_event_header, "nfNamingCode", "sdn controller") == 0) {
132 log_error("cJSON AddStringToObject error\n");
133 cJSON_Delete(common_event_header);
137 if(cJSON_AddStringToObject(common_event_header, "nfVendorName", "sdn") == 0) {
138 log_error("cJSON AddStringToObject error\n");
139 cJSON_Delete(common_event_header);
143 if(cJSON_AddStringToObject(common_event_header, "timeZoneOffset", "+00:00") == 0) {
144 log_error("cJSON AddStringToObject error\n");
145 cJSON_Delete(common_event_header);
149 if(cJSON_AddStringToObject(common_event_header, "version", "4.1") == 0) {
150 log_error("cJSON AddStringToObject error\n");
151 cJSON_Delete(common_event_header);
155 if(cJSON_AddStringToObject(common_event_header, "vesEventListenerVersion", framework_environment.ves_endpoint.common_header_version) == 0) {
156 log_error("cJSON AddStringToObject error\n");
157 cJSON_Delete(common_event_header);
161 return common_event_header;
164 nts_mount_point_addressing_method_t nts_mount_point_addressing_method_get(sr_session_ctx_t *current_session) {
167 nts_mount_point_addressing_method_t ret = UNKNOWN_MAPPING;
170 bool session_started = false;
171 if(current_session == 0) {
172 rc = sr_session_start(session_connection, SR_DS_RUNNING, ¤t_session);
173 if(rc != SR_ERR_OK) {
174 log_error("could not start sysrepo session\n");
177 session_started = true;
181 rc = sr_get_item(current_session, NTS_NF_NETWORK_FUNCTION_MPAM_SCHEMA_XPATH, 0, &value);
182 if(rc == SR_ERR_OK) {
183 if(strcmp(value->data.enum_val, "host-mapping") == 0) {
187 ret = DOCKER_MAPPING;
192 if(session_started) {
193 rc = sr_session_stop(current_session);
194 if(rc != SR_ERR_OK) {
195 log_error("could not stop sysrepo session\n");
203 // checkAS authentication via certificate not supported yet
204 ves_details_t *ves_endpoint_details_get(sr_session_ctx_t *current_session) {
208 bool session_started = false;
209 if(current_session == 0) {
210 rc = sr_session_start(session_connection, SR_DS_RUNNING, ¤t_session);
211 if(rc != SR_ERR_OK) {
212 log_error("could not start sysrepo session\n");
215 session_started = true;
218 struct lyd_node *data = 0;
221 if(framework_arguments.nts_mode == NTS_MODE_MANAGER) {
222 xpath_to_get = NTS_MANAGER_VES_ENDPOINT_CONFIG_XPATH;
225 xpath_to_get = NTS_NF_VES_ENDPOINT_CONFIG_XPATH;
228 rc = sr_get_subtree(current_session, xpath_to_get, 0, &data);
229 if(rc != SR_ERR_OK) {
230 log_error("could not get value for xPath=%s from the running datastore\n", xpath_to_get);
231 if(session_started) {
232 sr_session_stop(current_session);
237 if(session_started) {
238 rc = sr_session_stop(current_session);
239 if(rc != SR_ERR_OK) {
240 log_error("could not stop sysrepo session\n");
246 if(data->child == 0) {
247 log_error("ves-endpoint probably not set yet\n", xpath_to_get);
252 ves_details_t *ret = (ves_details_t *)malloc(sizeof(ves_details_t));
254 log_error("malloc failed\n");
262 ret->auth_method = 0;
266 struct lyd_node *chd = 0;
267 LY_TREE_FOR(data->child, chd) {
268 const char *val = ((const struct lyd_node_leaf_list *)chd)->value_str;
270 if(strcmp(chd->schema->name, "ves-endpoint-protocol") == 0) {
271 ret->protocol = strdup(val);
273 else if(strcmp(chd->schema->name, "ves-endpoint-ip") == 0) {
274 ret->ip = strdup(val);
276 else if(strcmp(chd->schema->name, "ves-endpoint-port") == 0) {
277 ret->port = ((const struct lyd_node_leaf_list *)chd)->value.uint16;
279 else if(strcmp(chd->schema->name, "ves-endpoint-auth-method") == 0) {
280 ret->auth_method = strdup(val);
282 else if(strcmp(chd->schema->name, "ves-endpoint-username") == 0) {
283 ret->username = strdup(val);
285 else if(strcmp(chd->schema->name, "ves-endpoint-password") == 0) {
286 ret->password = strdup(val);
291 if (strstr(ret->ip, ":")) {
293 asprintf(&ret->url, "%s://[%s]:%d/eventListener/v7", ret->protocol, ret->ip, ret->port);
296 if (framework_environment.ves_endpoint.port_absent == true) {
297 // hostname addressing with port missing
298 asprintf(&ret->url, "%s://%s/eventListener/v7", ret->protocol, ret->ip);
301 // normal addressing with IP and Port
302 asprintf(&ret->url, "%s://%s:%d/eventListener/v7", ret->protocol, ret->ip, ret->port);
307 if((ret->protocol == 0) || (ret->ip == 0) || (ret->auth_method == 0) || (ret->username == 0) || (ret->password == 0) || (ret->url == 0)) {
310 free(ret->auth_method);
321 void ves_details_free(ves_details_t *instance) {
324 free(instance->protocol);
327 free(instance->auth_method);
328 free(instance->username);
329 free(instance->password);
334 // checkAS authentication via certificate not supported yet
335 controller_details_t *controller_details_get(sr_session_ctx_t *current_session) {
339 bool session_started = false;
340 if(current_session == 0) {
341 rc = sr_session_start(session_connection, SR_DS_RUNNING, ¤t_session);
342 if(rc != SR_ERR_OK) {
343 log_error("could not start sysrepo session\n");
346 session_started = true;
349 struct lyd_node *data = 0;
352 if(framework_arguments.nts_mode == NTS_MODE_MANAGER) {
353 xpath_to_get = NTS_MANAGER_SDN_CONTROLLER_CONFIG_XPATH;
356 xpath_to_get = NTS_NF_SDN_CONTROLLER_CONFIG_XPATH;
359 rc = sr_get_subtree(current_session, xpath_to_get, 0, &data);
360 if(rc != SR_ERR_OK) {
361 log_error("could not get value for xPath=%s from the running datastore\n", xpath_to_get);
362 if(session_started) {
363 sr_session_stop(current_session);
368 if(session_started) {
369 rc = sr_session_stop(current_session);
370 if(rc != SR_ERR_OK) {
371 log_error("could not stop sysrepo session\n");
377 if(data->child == 0) {
378 log_error("sdn-controller probably not set yet\n");
383 controller_details_t *ret = (controller_details_t *)malloc(sizeof(controller_details_t));
385 log_error("malloc failed\n");
393 ret->nc_callhome_port = 0;
394 ret->auth_method = 0;
398 ret->auth_method = strdup("basic");
400 struct lyd_node *chd = 0;
401 LY_TREE_FOR(data->child, chd) {
402 const char *val = ((const struct lyd_node_leaf_list *)chd)->value_str;
404 if(strcmp(chd->schema->name, "controller-protocol") == 0) {
405 ret->protocol = strdup(val);
407 else if(strcmp(chd->schema->name, "controller-ip") == 0) {
408 ret->ip = strdup(val);
410 else if(strcmp(chd->schema->name, "controller-port") == 0) {
411 ret->port = ((const struct lyd_node_leaf_list *)chd)->value.uint16;
413 else if(strcmp(chd->schema->name, "controller-netconf-call-home-port") == 0) {
414 ret->nc_callhome_port = ((const struct lyd_node_leaf_list *)chd)->value.uint16;
416 else if(strcmp(chd->schema->name, "controller-username") == 0) {
417 ret->username = strdup(val);
419 else if(strcmp(chd->schema->name, "controller-password") == 0) {
420 ret->password = strdup(val);
425 if (strstr(ret->ip, ":")) {
427 asprintf(&ret->base_url, "%s://[%s]:%d", ret->protocol, ret->ip, ret->port);
430 if (framework_environment.sdn_controller.port_absent == true) {
431 // hostname without port addressing
432 asprintf(&ret->base_url, "%s://%s", ret->protocol, ret->ip);
435 // normal IP and Port addressing
436 asprintf(&ret->base_url, "%s://%s:%d", ret->protocol, ret->ip, ret->port);
440 if((ret->protocol == 0) || (ret->ip == 0) || (ret->auth_method == 0) || (ret->username == 0) || (ret->password == 0) || (ret->base_url == 0)) {
443 free(ret->auth_method);
454 void controller_details_free(controller_details_t *instance) {
457 free(instance->protocol);
459 free(instance->base_url);
460 free(instance->auth_method);
461 free(instance->username);
462 free(instance->password);
466 int nts_vercmp(const char *ver1, const char *ver2) {
471 int v1 = 0, v2 = 0, v3 = 0;
472 while(ver1[i] && (ver1[i] != '.')) {
480 while(ver1[i] && (ver1[i] != '.')) {
488 while(ver1[i] && (ver1[i] != '.')) {
497 int V1 = 0, V2 = 0, V3 = 0;
499 while(ver2[i] && (ver2[i] != '.')) {
507 while(ver2[i] && (ver2[i] != '.')) {
515 while(ver2[i] && (ver2[i] != '.')) {
547 int nts_utils_populate_info(sr_session_ctx_t *current_session, const char *function_type) {
548 assert(current_session);
549 assert(function_type);
551 bool manager = (strcmp(function_type, "NTS_FUNCTION_TYPE_MANAGER") == 0);
555 //setup sdn-controller defaults
556 if(strlen(framework_environment.sdn_controller.protocol)) {
558 rc = sr_set_item_str(current_session, NTS_MANAGER_SDN_CONTROLLER_CONFIG_XPATH"/controller-protocol", (const char*)framework_environment.sdn_controller.protocol, 0, 0);
561 rc = sr_set_item_str(current_session, NTS_NF_SDN_CONTROLLER_CONFIG_XPATH"/controller-protocol", (const char*)framework_environment.sdn_controller.protocol, 0, 0);
563 if(rc != SR_ERR_OK) {
564 log_error("sr_set_item_str failed\n");
565 return NTS_ERR_FAILED;
569 if(strlen(framework_environment.sdn_controller.ip)) {
571 rc = sr_set_item_str(current_session, NTS_MANAGER_SDN_CONTROLLER_CONFIG_XPATH"/controller-ip", (const char*)framework_environment.sdn_controller.ip, 0, 0);
574 rc = sr_set_item_str(current_session, NTS_NF_SDN_CONTROLLER_CONFIG_XPATH"/controller-ip", (const char*)framework_environment.sdn_controller.ip, 0, 0);
576 if(rc != SR_ERR_OK) {
577 log_error("sr_set_item_str failed\n");
578 return NTS_ERR_FAILED;
582 sprintf(int_to_str, "%d", framework_environment.sdn_controller.port);
584 rc = sr_set_item_str(current_session, NTS_MANAGER_SDN_CONTROLLER_CONFIG_XPATH"/controller-port", (const char*)int_to_str, 0, 0);
587 rc = sr_set_item_str(current_session, NTS_NF_SDN_CONTROLLER_CONFIG_XPATH"/controller-port", (const char*)int_to_str, 0, 0);
589 if(rc != SR_ERR_OK) {
590 log_error("sr_set_item_str failed\n");
591 return NTS_ERR_FAILED;
594 sprintf(int_to_str, "%d", framework_environment.sdn_controller.callhome_port);
596 rc = sr_set_item_str(current_session, NTS_MANAGER_SDN_CONTROLLER_CONFIG_XPATH"/controller-netconf-call-home-port", (const char*)int_to_str, 0, 0);
599 rc = sr_set_item_str(current_session, NTS_NF_SDN_CONTROLLER_CONFIG_XPATH"/controller-netconf-call-home-port", (const char*)int_to_str, 0, 0);
601 if(rc != SR_ERR_OK) {
602 log_error("sr_set_item_str failed\n");
603 return NTS_ERR_FAILED;
606 if(strlen(framework_environment.sdn_controller.username)) {
608 rc = sr_set_item_str(current_session, NTS_MANAGER_SDN_CONTROLLER_CONFIG_XPATH"/controller-username", (const char*)framework_environment.sdn_controller.username, 0, 0);
611 rc = sr_set_item_str(current_session, NTS_NF_SDN_CONTROLLER_CONFIG_XPATH"/controller-username", (const char*)framework_environment.sdn_controller.username, 0, 0);
613 if(rc != SR_ERR_OK) {
614 log_error("sr_set_item_str failed\n");
615 return NTS_ERR_FAILED;
619 if(strlen(framework_environment.sdn_controller.password)) {
621 rc = sr_set_item_str(current_session, NTS_MANAGER_SDN_CONTROLLER_CONFIG_XPATH"/controller-password", (const char*)framework_environment.sdn_controller.password, 0, 0);
624 rc = sr_set_item_str(current_session, NTS_NF_SDN_CONTROLLER_CONFIG_XPATH"/controller-password", (const char*)framework_environment.sdn_controller.password, 0, 0);
626 if(rc != SR_ERR_OK) {
627 log_error("sr_set_item_str failed\n");
628 return NTS_ERR_FAILED;
632 //setup ves-endpoint details
633 if(strlen(framework_environment.ves_endpoint.protocol)) {
635 rc = sr_set_item_str(current_session, NTS_MANAGER_VES_ENDPOINT_CONFIG_XPATH"/ves-endpoint-protocol", (const char*)framework_environment.ves_endpoint.protocol, 0, 0);
638 rc = sr_set_item_str(current_session, NTS_NF_VES_ENDPOINT_CONFIG_XPATH"/ves-endpoint-protocol", (const char*)framework_environment.ves_endpoint.protocol, 0, 0);
640 if(rc != SR_ERR_OK) {
641 log_error("sr_set_item_str failed\n");
642 return NTS_ERR_FAILED;
646 if(strlen(framework_environment.ves_endpoint.ip)) {
648 rc = sr_set_item_str(current_session, NTS_MANAGER_VES_ENDPOINT_CONFIG_XPATH"/ves-endpoint-ip", (const char*)framework_environment.ves_endpoint.ip, 0, 0);
651 rc = sr_set_item_str(current_session, NTS_NF_VES_ENDPOINT_CONFIG_XPATH"/ves-endpoint-ip", (const char*)framework_environment.ves_endpoint.ip, 0, 0);
653 if(rc != SR_ERR_OK) {
654 log_error("sr_set_item_str failed\n");
655 return NTS_ERR_FAILED;
659 sprintf(int_to_str, "%d", framework_environment.ves_endpoint.port);
661 rc = sr_set_item_str(current_session, NTS_MANAGER_VES_ENDPOINT_CONFIG_XPATH"/ves-endpoint-port", (const char*)int_to_str, 0, 0);
664 rc = sr_set_item_str(current_session, NTS_NF_VES_ENDPOINT_CONFIG_XPATH"/ves-endpoint-port", (const char*)int_to_str, 0, 0);
666 if(rc != SR_ERR_OK) {
667 log_error("sr_set_item_str failed\n");
668 return NTS_ERR_FAILED;
671 if(strlen(framework_environment.ves_endpoint.auth_method)) {
673 rc = sr_set_item_str(current_session, NTS_MANAGER_VES_ENDPOINT_CONFIG_XPATH"/ves-endpoint-auth-method", (const char*)framework_environment.ves_endpoint.auth_method, 0, 0);
676 rc = sr_set_item_str(current_session, NTS_NF_VES_ENDPOINT_CONFIG_XPATH"/ves-endpoint-auth-method", (const char*)framework_environment.ves_endpoint.auth_method, 0, 0);
678 if(rc != SR_ERR_OK) {
679 log_error("sr_set_item_str failed\n");
680 return NTS_ERR_FAILED;
684 if(strlen(framework_environment.ves_endpoint.username)) {
686 rc = sr_set_item_str(current_session, NTS_MANAGER_VES_ENDPOINT_CONFIG_XPATH"/ves-endpoint-username", (const char*)framework_environment.ves_endpoint.username, 0, 0);
689 rc = sr_set_item_str(current_session, NTS_NF_VES_ENDPOINT_CONFIG_XPATH"/ves-endpoint-username", (const char*)framework_environment.ves_endpoint.username, 0, 0);
691 if(rc != SR_ERR_OK) {
692 log_error("sr_set_item_str failed\n");
693 return NTS_ERR_FAILED;
697 if(strlen(framework_environment.ves_endpoint.password)) {
699 rc = sr_set_item_str(current_session, NTS_MANAGER_VES_ENDPOINT_CONFIG_XPATH"/ves-endpoint-password", (const char*)framework_environment.ves_endpoint.password, 0, 0);
702 rc = sr_set_item_str(current_session, NTS_NF_VES_ENDPOINT_CONFIG_XPATH"/ves-endpoint-password", (const char*)framework_environment.ves_endpoint.password, 0, 0);
704 if(rc != SR_ERR_OK) {
705 log_error("sr_set_item_str failed\n");
706 return NTS_ERR_FAILED;
710 if(strlen(framework_environment.ves_endpoint.certificate)) {
712 rc = sr_set_item_str(current_session, NTS_MANAGER_VES_ENDPOINT_CONFIG_XPATH"/ves-endpoint-certificate", (const char*)framework_environment.ves_endpoint.certificate, 0, 0);
715 rc = sr_set_item_str(current_session, NTS_NF_VES_ENDPOINT_CONFIG_XPATH"/ves-endpoint-certificate", (const char*)framework_environment.ves_endpoint.certificate, 0, 0);
717 if(rc != SR_ERR_OK) {
718 log_error("sr_set_item_str failed\n");
719 return NTS_ERR_FAILED;
723 if(manager == false) {
724 //presence containers
725 rc = sr_set_item_str(current_session, NTS_NF_FAULT_GENERATION_SCHEMA_XPATH, 0, 0, 0);
726 if(rc != SR_ERR_OK) {
727 log_error("sr_set_item_str failed\n");
728 return NTS_ERR_FAILED;
731 rc = sr_set_item_str(current_session, NTS_NF_NETCONF_SCHEMA_XPATH, 0, 0, 0);
732 if(rc != SR_ERR_OK) {
733 log_error("sr_set_item_str failed\n");
734 return NTS_ERR_FAILED;
737 rc = sr_set_item_str(current_session, NTS_NF_VES_SCHEMA_XPATH, 0, 0, 0);
738 if(rc != SR_ERR_OK) {
739 log_error("sr_set_item_str failed\n");
740 return NTS_ERR_FAILED;
744 //also set the network-function module for easy identifying the function type
745 rc = sr_set_item_str(current_session, NTS_NF_NETWORK_FUNCTION_FTYPE_SCHEMA_XPATH, function_type, 0, 0);
746 if(rc != SR_ERR_OK) {
747 log_error("sr_set_item_str failed\n");
748 return NTS_ERR_FAILED;
751 //mount-point-addressing-method
752 rc = sr_set_item_str(current_session, NTS_NF_NETWORK_FUNCTION_MPAM_SCHEMA_XPATH, framework_environment.nts.nf_mount_point_addressing_method, 0, 0);
753 if(rc != SR_ERR_OK) {
754 log_error("sr_set_item_str failed\n");
755 return NTS_ERR_FAILED;
759 rc = sr_apply_changes(current_session, 0, 0);
760 if(rc != SR_ERR_OK) {
761 log_error("sr_apply_changes failed: %s\n", sr_strerror(rc));
762 return NTS_ERR_FAILED;