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 "framework.h"
27 #include <sys/types.h>
29 #include <cjson/cJSON.h>
31 #include "utils/sys_utils.h"
32 #include "utils/log_utils.h"
33 #include "utils/rand_utils.h"
35 framework_arguments_t framework_arguments;
36 framework_environment_t framework_environment;
37 framework_config_t framework_config;
39 const char *argp_program_version = 0; //is set later
40 const char *argp_program_bug_address = "<alexandru.stancu@highstreet-technologies.com> / <adrian.lita@highstreet-technologies.com>";
41 static char doc[] = "ntsim - new generation";
43 static struct argp_option options[] = {
44 { "container-init", 'i', 0, 0, "Runs initialization tasks for the Docker container that's being built. Do not run manually." },
45 { "supervisor", 's', 0, 0, "Run as supervisor; manager/network-function is chosen via config.json"},
46 { "manager", 'm', 0, 0, "Run the daemon as manager." },
47 { "network-function", 'f', 0, 0, "Run the daemon as network function." },
48 { "blank", 'b', 0, 0, "Run the deamon as a blank network function." },
49 { "generate", 'g', 0, 0, "Generate population data without commiting." },
50 { "test-mode", 't', 0, 0, "Test mode." },
53 { "ls", '1', 0, 0, "Print all available root paths." },
54 { "schema", '2', "XPATH", 0, "Print schema for XPATH." },
56 { "fixed-rand", 'r', "SEED", 0, "Initialize RAND seed to a fixed value (for debugging purposes)." },
57 { "verbose", 'v', "LEVEL", 0, "Verbosity level for printing to stdout (logs will still save everything). LEVEL is: 0=errors only, 1=requested info(default), 2=info" },
58 { "workspace", 'w', "PATH", 0, "Initialize workspace to a different one than the current working directory." },
62 volatile sig_atomic_t framework_sigint;
64 static int framework_env_init(void);
65 static int framework_config_init(void);
67 static void framework_signal_handler(int signo);
68 static error_t parse_opt(int key, char *arg, struct argp_state *state);
70 int framework_init(int argc, char **argv) {
72 framework_environment.nts.version = (getenv(ENV_VAR_NTS_BUILD_VERSION) && strlen(getenv(ENV_VAR_NTS_BUILD_VERSION))) ? strdup(getenv(ENV_VAR_NTS_BUILD_VERSION)) : strdup(NTS_VERSION_FALLBACK"!");
73 if(getenv(ENV_VAR_NTS_BUILD_TIME) && strlen(getenv(ENV_VAR_NTS_BUILD_TIME))) {
74 framework_environment.nts.build_time = strdup(getenv(ENV_VAR_NTS_BUILD_TIME));
77 if(__DATE__[0] == '?') {
78 framework_environment.nts.build_time = strdup("1970-01-01T00:00:00Z");
87 year = (__DATE__[10] - '0') + (__DATE__[9] - '0')*10 + (__DATE__[8] - '0')*100 + (__DATE__[7] - '0')*1000;
88 day = (__DATE__[5] - '0');
89 if(__DATE__[4] != ' ') {
90 day += (__DATE__[4] - '0')*10;
101 if(__DATE__[2] == 'n') {
116 switch(__DATE__[2]) {
128 switch(__DATE__[1]) {
156 asprintf(&framework_environment.nts.build_time, "%04d-%02d-%02dT%sZ", year, month, day, __TIME__);
162 asprintf(&version, "ntsim-ng v%s build %s", framework_environment.nts.version, framework_environment.nts.build_time);
163 argp_program_version = version;
165 //initialize app arguments
166 framework_arguments.nts_mode = NTS_MODE_DEFAULT;
168 framework_arguments.argc = argc;
169 framework_arguments.argv = argv;
171 framework_arguments.no_rand = false;
172 framework_arguments.fixed_seed = 0;
173 framework_arguments.verbosity_level = 1;
175 framework_arguments.print_root_paths = false;
176 framework_arguments.print_structure_xpath = 0;
178 //parse provided command line arguments
179 struct argp argp = { options, parse_opt, 0, doc, 0, 0, 0 };
180 argp_parse(&argp, argc, argv, 0, 0, &framework_arguments);
183 framework_sigint = 0;
184 signal(SIGINT, framework_signal_handler);
185 signal(SIGTERM, framework_signal_handler);
186 signal(SIGQUIT, framework_signal_handler);
188 //disable buffering for stdout
189 setbuf(stdout, NULL);
191 //init logging subsystem
193 char *stderr_file = 0;
195 if(!dir_exists("log")) {
199 switch(framework_arguments.nts_mode) {
200 case NTS_MODE_CONTAINER_INIT:
201 log_file = "log/log-install.txt";
202 stderr_file = "log/stderr-install.txt";
206 log_file = "log/log-blank.txt";
207 stderr_file = "log/stderr-blank.txt";
210 case NTS_MODE_SUPERVISOR:
211 log_file = "log/log-supervisor.txt";
212 stderr_file = "log/stderr-supervisor.txt";
215 case NTS_MODE_GENERATE_DATA:
216 log_file = "log/log-generate.txt";
217 stderr_file = "log/stderr-generate.txt";
221 log_file = "log/log.txt";
222 stderr_file = "log/stderr.txt";
227 log_redirect_stderr(stderr_file);
230 getcwd(cwd, sizeof(cwd));
231 log_add_verbose(2, "[framework] current working dir is: %s\n", cwd);
233 //init rand generator if needed
234 if(framework_arguments.no_rand == false) {
238 rand_init_fixed(framework_arguments.fixed_seed);
241 log_add_verbose(2, "[framework] app was called: ");
242 for(int i = 0; i < argc; i++) {
243 log_add(2, "%s ", argv[i]);
247 if(framework_env_init() != NTS_ERR_OK) {
248 log_error("[framework] framework_env_init() failed\n");
249 return NTS_ERR_FAILED;
252 if(framework_config_init() != NTS_ERR_OK) {
253 log_error("[framework] framework_config_init() failed\n");
254 return NTS_ERR_FAILED;
257 log_add_verbose(2, "[framework] init complete\n");
261 static int framework_env_init(void) {
262 log_add_verbose(2, "[framework-env] started\n");
265 The following env vars are taken care of by framework_init()
266 framework_environment.nts.version
267 framework_environment.nts.build_time
270 framework_environment.nts.manual = getenv(ENV_VAR_NTS_MANUAL) ? true : false;
271 framework_environment.nts.function_type = getenv(ENV_VAR_NTS_FUNCTION_TYPE) ? strdup(getenv(ENV_VAR_NTS_FUNCTION_TYPE)) : strdup("");
272 framework_environment.nts.nf_standalone_start_features = getenv(ENV_VAR_NTS_NF_STANDALONE_START_FEATURES) ? strdup(getenv(ENV_VAR_NTS_NF_STANDALONE_START_FEATURES)) : strdup("");
273 framework_environment.nts.nf_mount_point_addressing_method = getenv(ENV_VAR_NTS_NF_MOUNT_POINT_ADDRESSING_METHOD) ? strdup(getenv(ENV_VAR_NTS_NF_MOUNT_POINT_ADDRESSING_METHOD)) : strdup("docker-mapping");
275 framework_environment.settings.docker_repository = getenv(ENV_VAR_DOCKER_REPOSITORY) ? strdup(getenv(ENV_VAR_DOCKER_REPOSITORY)) : strdup("");
276 if(strlen(framework_environment.settings.docker_repository)) {
277 if(framework_environment.settings.docker_repository[strlen(framework_environment.settings.docker_repository) - 1] == '/') {
278 framework_environment.settings.docker_repository[strlen(framework_environment.settings.docker_repository) - 1] = 0;
281 framework_environment.settings.docker_engine_version = getenv(ENV_VAR_DOCKER_ENGINE_VERSION) ? strdup(getenv(ENV_VAR_DOCKER_ENGINE_VERSION)) : strdup("1.40");
282 framework_environment.settings.hostname = getenv(ENV_VAR_HOSTNAME) ? strdup(getenv(ENV_VAR_HOSTNAME)) : strdup("localhost");
284 bool ip_ok = get_local_ips("eth0", &framework_environment.settings.ip_v4, &framework_environment.settings.ip_v6);
286 log_error("[framework-env] could not get local IP addresses\n");
289 char *ipv6_env_var = getenv(ENV_VAR_IPV6ENABLED);
290 if(ipv6_env_var == 0) {
291 log_error("[framework-env] could not get the IPv6 Enabled env variable\n");
293 framework_environment.settings.ip_v6_enabled = (strcmp(ipv6_env_var, "true") == 0) ? true : false;
294 framework_environment.settings.ssh_connections = get_int_from_string_with_default(getenv(ENV_VAR_SSH_CONNECTIONS), 1);
295 framework_environment.settings.tls_connections = get_int_from_string_with_default(getenv(ENV_VAR_TLS_CONNECTIONS), 0);
296 framework_environment.settings.ftp_connections = 1;
297 framework_environment.settings.sftp_connections = 1;
299 //build version and build time are set in the begining of the function
300 framework_environment.host.ip = getenv(ENV_VAR_HOST_IP) ? strdup(getenv(ENV_VAR_HOST_IP)) : strdup("127.0.0.1");
301 framework_environment.host.base_port = get_int_from_string_with_default(getenv(ENV_VAR_HOST_BASE_PORT), 1000);
302 framework_environment.host.ssh_base_port = get_int_from_string_with_default(getenv(ENV_VAR_HOST_NETCONF_SSH_BASE_PORT), 0);
303 framework_environment.host.tls_base_port = get_int_from_string_with_default(getenv(ENV_VAR_HOST_NETCONF_TLS_BASE_PORT), 0);
304 framework_environment.host.ftp_base_port = get_int_from_string_with_default(getenv(ENV_VAR_HOST_TRANSFER_FTP_BASE_PORT), 0);
305 framework_environment.host.sftp_base_port = get_int_from_string_with_default(getenv(ENV_VAR_HOST_TRANSFER_SFTP_BASE_PORT), 0);
307 framework_environment.sdn_controller.protocol = getenv(ENV_VAR_SDN_CONTROLLER_IP) ? strdup(getenv(ENV_VAR_SDN_CONTROLLER_PROTOCOL)) : strdup("https");
308 framework_environment.sdn_controller.ip = getenv(ENV_VAR_SDN_CONTROLLER_IP) ? strdup(getenv(ENV_VAR_SDN_CONTROLLER_IP)) : strdup("127.0.0.1");
309 framework_environment.sdn_controller.port = get_int_from_string_with_default(getenv(ENV_VAR_SDN_CONTROLLER_PORT), 8181);
310 framework_environment.sdn_controller.callhome_ip = getenv(ENV_VAR_SDN_CONTROLLER_CALLHOME_IP) ? strdup(getenv(ENV_VAR_SDN_CONTROLLER_CALLHOME_IP)) : strdup("127.0.0.1");
311 framework_environment.sdn_controller.callhome_port = get_int_from_string_with_default(getenv(ENV_VAR_SDN_CONTROLLER_CALLHOME_PORT), 6666);
312 framework_environment.sdn_controller.username = getenv(ENV_VAR_SDN_CONTROLLER_USERNAME) ? strdup(getenv(ENV_VAR_SDN_CONTROLLER_USERNAME)) : strdup("admin");
313 framework_environment.sdn_controller.password = getenv(ENV_VAR_SDN_CONTROLLER_PASSWORD) ? strdup(getenv(ENV_VAR_SDN_CONTROLLER_PASSWORD)) : strdup("admin");
314 framework_environment.sdn_controller.port_absent = (getenv(ENV_VAR_SDN_CONTROLLER_PORT) == 0) ? true : false;
316 framework_environment.ves_endpoint.common_header_version = getenv(ENV_VAR_VES_COMMON_HEADER_VERSION) ? strdup(getenv(ENV_VAR_VES_COMMON_HEADER_VERSION)) : strdup("7.2");
317 framework_environment.ves_endpoint.protocol = getenv(ENV_VAR_VES_ENDPOINT_PROTOCOL) ? strdup(getenv(ENV_VAR_VES_ENDPOINT_PROTOCOL)) : strdup("https");
318 framework_environment.ves_endpoint.ip = getenv(ENV_VAR_VES_ENDPOINT_IP) ? strdup(getenv(ENV_VAR_VES_ENDPOINT_IP)) : strdup("127.0.0.1");
319 framework_environment.ves_endpoint.port = get_int_from_string_with_default(getenv(ENV_VAR_VES_ENDPOINT_PORT), 1234);
320 framework_environment.ves_endpoint.auth_method = getenv(ENV_VAR_VES_ENDPOINT_AUTH_METHOD) ? strdup(getenv(ENV_VAR_VES_ENDPOINT_AUTH_METHOD)) : strdup("no-auth");
321 framework_environment.ves_endpoint.username = getenv(ENV_VAR_VES_ENDPOINT_USERNAME) ? strdup(getenv(ENV_VAR_VES_ENDPOINT_USERNAME)) : strdup("admin");
322 framework_environment.ves_endpoint.password = getenv(ENV_VAR_VES_ENDPOINT_PASSWORD) ? strdup(getenv(ENV_VAR_VES_ENDPOINT_PASSWORD)) : strdup("admin");
323 framework_environment.ves_endpoint.certificate = getenv(ENV_VAR_VES_ENDPOINT_CERTIFICATE) ? strdup(getenv(ENV_VAR_VES_ENDPOINT_CERTIFICATE)) : strdup("");
324 framework_environment.ves_endpoint.port_absent = (getenv(ENV_VAR_VES_ENDPOINT_PORT) == 0) ? true : false;
326 log_add_verbose(2, "[framework-env] nts.manual = %d\n", framework_environment.nts.manual);
327 log_add_verbose(2, "[framework-env] nts.version = %s\n", framework_environment.nts.version);
328 log_add_verbose(2, "[framework-env] nts.build_time = %s\n", framework_environment.nts.build_time);
329 log_add_verbose(2, "[framework-env] nts.function_type = %s\n", framework_environment.nts.function_type);
330 log_add_verbose(2, "[framework-env] nts.nf_standalone_start_features = %s\n", framework_environment.nts.nf_standalone_start_features);
331 log_add_verbose(2, "[framework-env] nts.nf_mount_point_addressing_method = %s\n", framework_environment.nts.nf_mount_point_addressing_method);
333 log_add_verbose(2, "[framework-env] settings.docker_engine_version = %s\n", framework_environment.settings.docker_engine_version);
334 log_add_verbose(2, "[framework-env] settings.docker_repository = %s\n", framework_environment.settings.docker_repository);
335 log_add_verbose(2, "[framework-env] settings.hostname = %s\n", framework_environment.settings.hostname);
336 log_add_verbose(2, "[framework-env] settings.ip_v4 = %s\n", framework_environment.settings.ip_v4);
337 log_add_verbose(2, "[framework-env] settings.ip_v6 = %s\n", framework_environment.settings.ip_v6);
338 log_add_verbose(2, "[framework-env] settings.ip_v6_enabled = %s\n", framework_environment.settings.ip_v6_enabled ? "true" : "false");
339 log_add_verbose(2, "[framework-env] settings.ssh_connections = %d\n", framework_environment.settings.ssh_connections);
340 log_add_verbose(2, "[framework-env] settings.tls_connections = %d\n", framework_environment.settings.tls_connections);
341 log_add_verbose(2, "[framework-env] settings.ftp_connections = %d\n", framework_environment.settings.ftp_connections);
342 log_add_verbose(2, "[framework-env] settings.sftp_connections = %d\n", framework_environment.settings.sftp_connections);
345 if(framework_environment.host.base_port < 1000) {
346 log_add_verbose(2, "[framework-env] host.base_port < 1000 -> disabling\n");
347 framework_environment.host.base_port = 0;
350 if(framework_environment.host.ssh_base_port < 1000) {
351 log_add_verbose(2, "[framework-env] host.ssh_base_port < 1000 -> using base_port\n");
352 framework_environment.host.ssh_base_port = framework_environment.host.base_port;
355 if(framework_environment.host.tls_base_port < 1000) {
356 log_add_verbose(2, "[framework-env] host.tls_base_port < 1000 -> using base_port\n");
357 framework_environment.host.tls_base_port = framework_environment.host.base_port;
360 if(framework_environment.host.ftp_base_port < 1000) {
361 log_add_verbose(2, "[framework-env] host.ftp_base_port < 1000 -> using base_port\n");
362 framework_environment.host.ftp_base_port = framework_environment.host.base_port;
365 if(framework_environment.host.sftp_base_port < 1000) {
366 log_add_verbose(2, "[framework-env] host.sftp_base_port < 1000 -> using base_port\n");
367 framework_environment.host.sftp_base_port = framework_environment.host.base_port;
370 if(framework_environment.host.base_port == 0) {
371 if(framework_environment.host.ssh_base_port == 0) {
372 log_error("[framework-env] host.ssh_base_port unknown\n");
373 return NTS_ERR_FAILED;
376 if(framework_environment.host.tls_base_port == 0) {
377 log_error("[framework-env] host.tls_base_port unknown\n");
378 return NTS_ERR_FAILED;
381 if(framework_environment.host.ftp_base_port == 0) {
382 log_error("[framework-env] host.ftp_base_port unknown\n");
383 return NTS_ERR_FAILED;
386 if(framework_environment.host.sftp_base_port == 0) {
387 log_error("[framework-env] host.sftp_base_port unknown\n");
388 return NTS_ERR_FAILED;
392 log_add_verbose(2, "[framework-env] host.ip = %s\n", framework_environment.host.ip);
393 if(framework_environment.settings.ip_v6_enabled) {
394 if(strstr(framework_environment.host.ip, ".")) {
395 log_error("[framework-env] host.ip is an invalid IP v6\n");
396 return NTS_ERR_FAILED;
400 if(strstr(framework_environment.host.ip, ":")) {
401 log_error("[framework-env] host.ip is an invalid IP v4\n");
402 return NTS_ERR_FAILED;
406 log_add_verbose(2, "[framework-env] host.base_port = %d\n", framework_environment.host.base_port);
407 log_add_verbose(2, "[framework-env] host.ssh_base_port = %d\n", framework_environment.host.ssh_base_port);
408 log_add_verbose(2, "[framework-env] host.tls_base_port = %d\n", framework_environment.host.tls_base_port);
409 log_add_verbose(2, "[framework-env] host.ftp_base_port = %d\n", framework_environment.host.ftp_base_port);
410 log_add_verbose(2, "[framework-env] host.sftp_base_port = %d\n", framework_environment.host.sftp_base_port);
412 log_add_verbose(2, "[framework-env] sdn_controller.protocol = %s\n", framework_environment.sdn_controller.protocol);
413 log_add_verbose(2, "[framework-env] sdn_controller.ip = %s\n", framework_environment.sdn_controller.ip);
414 log_add_verbose(2, "[framework-env] sdn_controller.port = %d\n", framework_environment.sdn_controller.port);
415 log_add_verbose(2, "[framework-env] sdn_controller.callhome_ip = %s\n", framework_environment.sdn_controller.callhome_ip);
416 log_add_verbose(2, "[framework-env] sdn_controller.callhome_port = %d\n", framework_environment.sdn_controller.callhome_port);
417 log_add_verbose(2, "[framework-env] sdn_controller.username = %s\n", framework_environment.sdn_controller.username);
418 log_add_verbose(2, "[framework-env] sdn_controller.password = %s\n", framework_environment.sdn_controller.password);
419 log_add_verbose(2, "[framework-env] sdn_controller.port_absent = %d\n", framework_environment.sdn_controller.port_absent);
421 log_add_verbose(2, "[framework-env] ves_endpoint.common_header_version = %s\n", framework_environment.ves_endpoint.common_header_version);
422 log_add_verbose(2, "[framework-env] ves_endpoint.protocol = %s\n", framework_environment.ves_endpoint.protocol);
423 log_add_verbose(2, "[framework-env] ves_endpoint.ip = %s\n", framework_environment.ves_endpoint.ip);
424 log_add_verbose(2, "[framework-env] ves_endpoint.port = %d\n", framework_environment.ves_endpoint.port);
425 log_add_verbose(2, "[framework-env] ves_endpoint.auth_method = %s\n", framework_environment.ves_endpoint.auth_method);
426 log_add_verbose(2, "[framework-env] ves_endpoint.username = %s\n", framework_environment.ves_endpoint.username);
427 log_add_verbose(2, "[framework-env] ves_endpoint.password = %s\n", framework_environment.ves_endpoint.password);
428 log_add_verbose(2, "[framework-env] ves_endpoint.certificate = %s\n", framework_environment.ves_endpoint.certificate);
429 log_add_verbose(2, "[framework-env] ves_endpoint.port_absent = %d\n", framework_environment.ves_endpoint.port_absent);
431 log_add_verbose(2, "[framework-env] finished\n");
435 static int framework_config_init(void) {
436 log_add_verbose(2, "[framework-config] started\n");
439 framework_config.docker.excluded_modules = 0;
440 framework_config.docker.excluded_modules_count = 0;
441 framework_config.docker.excluded_features = 0;
442 framework_config.docker.excluded_features_count = 0;
444 framework_config.supervisor.rules_count = 0;
445 framework_config.supervisor.rules = 0;
447 framework_config.datastore_generate.debug_max_string_size = 0;
448 framework_config.datastore_generate.excluded_modules = 0;
449 framework_config.datastore_generate.excluded_modules_count = 0;
450 framework_config.datastore_generate.default_list_instances = 1;
451 framework_config.datastore_generate.custom_list_instances_count = 0;
452 framework_config.datastore_generate.custom_list_instances = 0;
453 framework_config.datastore_generate.restrict_schema_count = 0;
454 framework_config.datastore_generate.restrict_schema = 0;
456 framework_config.datastore_populate.random_generation_enabled = 1;
457 framework_config.datastore_populate.preg_operational_count = 0;
458 framework_config.datastore_populate.preg_operational = 0;
459 framework_config.datastore_populate.preg_running_count = 0;
460 framework_config.datastore_populate.preg_running = 0;
463 char *config_file = "config/config.json";
464 if(file_exists("/opt/dev/config/config.json")) {
465 config_file = "/opt/dev/config/config.json";
466 log_add_verbose(1, LOG_COLOR_BOLD_MAGENTA"config.json is loaded from external volume!\n"LOG_COLOR_RESET);
469 if(!dir_exists("config")) {
470 log_add_verbose(2, "[framework-config] config/ folder wasn't found; created.\n");
471 mkdir("config", 0777);
474 if(!file_exists("config/config.json")) {
475 log_add_verbose(2, "[framework-config] config.json file missing; created.\n");
476 file_touch("config/config.json", "{}");
480 log_add_verbose(2, "[framework-config] parsing config.json from %s\n", config_file);
481 char *config_contents = file_read_content(config_file);
482 cJSON *json = cJSON_Parse(config_contents);
483 free(config_contents);
485 log_error("[framework-config] config.json error: %s\n", cJSON_GetErrorPtr());
491 if(framework_arguments.nts_mode == NTS_MODE_CONTAINER_INIT) {
492 main_node = cJSON_GetObjectItem(json, "container-rules");
494 node = cJSON_GetObjectItem(main_node, "excluded-modules");
496 if(cJSON_IsArray(node)) {
498 cJSON_ArrayForEach(element, node) {
499 if(cJSON_IsString(element)) {
500 log_add_verbose(2, "[framework-config] adding container-rules/exclude-modules: %s\n", element->valuestring);
501 framework_config.docker.excluded_modules = (char **)realloc(framework_config.docker.excluded_modules, sizeof(char*) * (framework_config.docker.excluded_modules_count + 1));
502 if(!framework_config.docker.excluded_modules) {
503 log_error("[framework-config] bad realloc\n");
505 framework_config.docker.excluded_modules[framework_config.docker.excluded_modules_count] = (char *)malloc(sizeof(char) * (strlen(element->valuestring) + 1));
506 if(!framework_config.docker.excluded_modules[framework_config.docker.excluded_modules_count]) {
507 log_error("[framework-config] bad malloc\n");
509 strcpy(framework_config.docker.excluded_modules[framework_config.docker.excluded_modules_count], element->valuestring);
510 framework_config.docker.excluded_modules_count++;
516 node = cJSON_GetObjectItem(main_node, "excluded-features");
518 if(cJSON_IsArray(node)) {
520 cJSON_ArrayForEach(element, node) {
521 if(cJSON_IsString(element)) {
522 log_add_verbose(2, "[framework-config] adding container-rules/excluded-features: %s\n", element->valuestring);
523 framework_config.docker.excluded_features = (char **)realloc(framework_config.docker.excluded_features, sizeof(char*) * (framework_config.docker.excluded_features_count + 1));
524 if(!framework_config.docker.excluded_features) {
525 log_error("[framework-config] bad realloc\n");
527 framework_config.docker.excluded_features[framework_config.docker.excluded_features_count] = (char *)malloc(sizeof(char) * (strlen(element->valuestring) + 1));
528 if(!framework_config.docker.excluded_features[framework_config.docker.excluded_features_count]) {
529 log_error("[framework-config] bad malloc\n");
531 strcpy(framework_config.docker.excluded_features[framework_config.docker.excluded_features_count], element->valuestring);
532 framework_config.docker.excluded_features_count++;
539 else if(framework_arguments.nts_mode == NTS_MODE_SUPERVISOR) {
540 main_node = cJSON_GetObjectItem(json, "supervisor-rules");
543 cJSON_ArrayForEach(app, main_node) {
544 if(cJSON_IsObject(app)) {
545 cJSON *object = cJSON_GetObjectItem(app, "path");
547 framework_config.supervisor.rules = (supervisor_rules_t *)realloc(framework_config.supervisor.rules, sizeof(supervisor_rules_t) * (framework_config.supervisor.rules_count + 1));
548 if(!framework_config.supervisor.rules) {
549 log_error("[framework-config] bad realloc\n");
552 char *path = strdup(object->valuestring);
553 bool autorestart = false;
554 bool nomanual = false;
555 char *stdout_path = 0;
556 char *stderr_path = 0;
560 cJSON *args_json = cJSON_GetObjectItem(app, "args");
562 args_count = cJSON_GetArraySize(args_json);
564 args = malloc(sizeof(char *) * args_count);
567 cJSON_ArrayForEach(arg, args_json) {
568 args[i] = strdup(arg->valuestring);
574 object = cJSON_GetObjectItem(app, "autorestart");
576 autorestart = object->valueint;
579 object = cJSON_GetObjectItem(app, "nomanual");
581 nomanual = object->valueint;
584 object = cJSON_GetObjectItem(app, "stdout");
586 stdout_path = strdup(object->valuestring);
589 object = cJSON_GetObjectItem(app, "stderr");
591 stderr_path = strdup(object->valuestring);
594 framework_config.supervisor.rules[framework_config.supervisor.rules_count].name = strdup(app->string);
595 framework_config.supervisor.rules[framework_config.supervisor.rules_count].path = path;
596 framework_config.supervisor.rules[framework_config.supervisor.rules_count].args = args;
597 framework_config.supervisor.rules[framework_config.supervisor.rules_count].args_count = args_count;
598 framework_config.supervisor.rules[framework_config.supervisor.rules_count].autorestart = autorestart;
599 framework_config.supervisor.rules[framework_config.supervisor.rules_count].nomanual = nomanual;
600 framework_config.supervisor.rules[framework_config.supervisor.rules_count].stdout_path = stdout_path;
601 framework_config.supervisor.rules[framework_config.supervisor.rules_count].stderr_path = stderr_path;
603 log_add_verbose(2, "[framework-config] adding supervisor command: %s with autorestart: %d\n", path, autorestart);
604 framework_config.supervisor.rules_count++;
611 main_node = cJSON_GetObjectItem(json, "datastore-random-generation-rules");
613 node = cJSON_GetObjectItem(main_node, "excluded-modules");
615 if(cJSON_IsArray(node)) {
617 cJSON_ArrayForEach(element, node) {
618 if(cJSON_IsString(element)) {
619 log_add_verbose(2, "[framework-config] adding datastore-random-generation-rules/excluded-modules: %s\n", element->valuestring);
620 framework_config.datastore_generate.excluded_modules = (char **)realloc(framework_config.datastore_generate.excluded_modules, sizeof(char*) * (framework_config.datastore_generate.excluded_modules_count + 1));
621 if(!framework_config.datastore_generate.excluded_modules) {
622 log_error("[framework-config] bad realloc\n");
624 framework_config.datastore_generate.excluded_modules[framework_config.datastore_generate.excluded_modules_count] = (char *)malloc(sizeof(char) * (strlen(element->valuestring) + 1));
625 if(!framework_config.datastore_generate.excluded_modules[framework_config.datastore_generate.excluded_modules_count]) {
626 log_error("[framework-config] bad malloc\n");
628 strcpy(framework_config.datastore_generate.excluded_modules[framework_config.datastore_generate.excluded_modules_count], element->valuestring);
629 framework_config.datastore_generate.excluded_modules_count++;
635 node = cJSON_GetObjectItem(main_node, "debug-max-string-size");
637 framework_config.datastore_generate.debug_max_string_size = node->valueint;
638 log_add_verbose(2, "[framework-config] setting datastore-random-generation-rules/debug-max-string-size: %d\n", framework_config.datastore_generate.debug_max_string_size);
641 node = cJSON_GetObjectItem(main_node, "default-list-instances");
643 if(cJSON_IsNumber(node)) {
644 framework_config.datastore_generate.default_list_instances = node->valueint;
645 log_add_verbose(2, "[framework-config] setting datastore-random-generation-rules/default-list-instances: %d\n", framework_config.datastore_generate.default_list_instances);
649 node = cJSON_GetObjectItem(main_node, "custom-list-instances");
651 if(cJSON_IsArray(node)) {
653 cJSON_ArrayForEach(element, node) {
654 if(cJSON_IsObject(element)) {
656 cJSON_ArrayForEach(object, element) {
657 char *path = object->string;
658 int count = object->valueint;
659 log_add_verbose(2, "[framework-config] adding datastore-random-generation-rules/custom-list-instances %s - %d\n", path, count);
660 framework_config.datastore_generate.custom_list_instances = (custom_list_instances_t *)realloc(framework_config.datastore_generate.custom_list_instances, sizeof(custom_list_instances_t) * (framework_config.datastore_generate.custom_list_instances_count + 1));
661 if(!framework_config.datastore_generate.custom_list_instances) {
662 log_error("[framework-config] bad realloc\n");
665 framework_config.datastore_generate.custom_list_instances[framework_config.datastore_generate.custom_list_instances_count].path = (char *)malloc(sizeof(char) * (strlen(path) + 1));
666 if(!framework_config.datastore_generate.custom_list_instances[framework_config.datastore_generate.custom_list_instances_count].path) {
667 log_error("[framework-config] bad malloc\n");
669 strcpy(framework_config.datastore_generate.custom_list_instances[framework_config.datastore_generate.custom_list_instances_count].path, path);
670 framework_config.datastore_generate.custom_list_instances[framework_config.datastore_generate.custom_list_instances_count].count = count;
671 framework_config.datastore_generate.custom_list_instances_count++;
678 node = cJSON_GetObjectItem(main_node, "restrict-schema");
680 if(cJSON_IsArray(node)) {
682 cJSON_ArrayForEach(element, node) {
683 if(cJSON_IsObject(element)) {
685 cJSON_ArrayForEach(object, element) {
686 char *path = object->string;
688 log_add_verbose(2, "[framework-config] adding datastore-random-generation-rules/restrict-schema: %s with values:", path);
689 framework_config.datastore_generate.restrict_schema = (restrict_schema_t *)realloc(framework_config.datastore_generate.restrict_schema, sizeof(restrict_schema_t) * (framework_config.datastore_generate.restrict_schema_count + 1));
690 if(!framework_config.datastore_generate.restrict_schema) {
691 log_error("[framework-config] bad realloc\n");
694 framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].path = (char *)malloc(sizeof(char) * (strlen(path) + 1));
695 if(!framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].path) {
696 log_error("[framework-config] bad malloc\n");
698 strcpy(framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].path, path);
701 framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].values_count = 0;
702 framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].values = 0;
703 framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].index = 0;
705 cJSON_ArrayForEach(value, object) {
706 if(cJSON_IsString(value)) {
707 framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].values = (char **)realloc(framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].values, sizeof(char*) * (framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].values_count + 1));
708 if(!framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].values) {
709 log_error("[framework-config] bad realloc\n");
711 framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].values[framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].values_count] = (char *)malloc(sizeof(char) * (strlen(value->valuestring) + 1));
712 if(!framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].values[framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].values_count]) {
713 log_error("[framework-config] bad malloc\n");
715 strcpy(framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].values[framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].values_count], value->valuestring);
716 framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].values_count++;
718 log_add(2, " %s", value->valuestring);
723 framework_config.datastore_generate.restrict_schema_count++;
731 main_node = cJSON_GetObjectItem(json, "datastore-populate-rules");
733 node = cJSON_GetObjectItem(main_node, "random-generation-enabled");
735 framework_config.datastore_populate.random_generation_enabled = node->valueint;
736 log_add_verbose(2, "[framework-config] setting datastore-populate-rules/random-generation-enabled: %d\n", framework_config.datastore_populate.random_generation_enabled);
739 log_add_verbose(2, "[framework-config] setting datastore-populate-rules/random-generation-enabled: %d [default value]\n", framework_config.datastore_populate.random_generation_enabled);
742 node = cJSON_GetObjectItem(main_node, "pre-generated-operational-data");
744 if(cJSON_IsArray(node)) {
746 cJSON_ArrayForEach(element, node) {
747 if(cJSON_IsString(element)) {
748 log_add_verbose(2, "[framework-config] adding datastore-populate-rules/pre-generated-operational-data: %s\n", element->valuestring);
749 framework_config.datastore_populate.preg_operational = (char **)realloc(framework_config.datastore_populate.preg_operational, sizeof(char*) * (framework_config.datastore_populate.preg_operational_count + 1));
750 if(!framework_config.datastore_populate.preg_operational) {
751 log_error("[framework-config] bad realloc\n");
753 framework_config.datastore_populate.preg_operational[framework_config.datastore_populate.preg_operational_count] = (char *)malloc(sizeof(char) * (strlen(element->valuestring) + 1));
754 if(!framework_config.datastore_populate.preg_operational[framework_config.datastore_populate.preg_operational_count]) {
755 log_error("[framework-config] bad malloc\n");
757 strcpy(framework_config.datastore_populate.preg_operational[framework_config.datastore_populate.preg_operational_count], element->valuestring);
758 framework_config.datastore_populate.preg_operational_count++;
764 node = cJSON_GetObjectItem(main_node, "pre-generated-running-data");
766 if(cJSON_IsArray(node)) {
768 cJSON_ArrayForEach(element, node) {
769 if(cJSON_IsString(element)) {
770 log_add_verbose(2, "[framework-config] adding datastore-populate-rules/pre-generated-running-data: %s\n", element->valuestring);
771 framework_config.datastore_populate.preg_running = (char **)realloc(framework_config.datastore_populate.preg_running, sizeof(char*) * (framework_config.datastore_populate.preg_running_count + 1));
772 if(!framework_config.datastore_populate.preg_running) {
773 log_error("[framework-config] bad realloc\n");
775 framework_config.datastore_populate.preg_running[framework_config.datastore_populate.preg_running_count] = (char *)malloc(sizeof(char) * (strlen(element->valuestring) + 1));
776 if(!framework_config.datastore_populate.preg_running[framework_config.datastore_populate.preg_running_count]) {
777 log_error("[framework-config] bad malloc\n");
779 strcpy(framework_config.datastore_populate.preg_running[framework_config.datastore_populate.preg_running_count], element->valuestring);
780 framework_config.datastore_populate.preg_running_count++;
792 log_add_verbose(2, "[framework-config] finished parsing config.json\n");
797 void framework_free(void) {
798 log_add_verbose(2, "[framework-config] framework_free()... ");
804 free((char *)argp_program_version);
805 argp_program_version = 0;
807 free(framework_environment.nts.version);
808 free(framework_environment.nts.build_time);
809 free(framework_environment.nts.function_type);
810 free(framework_environment.nts.nf_standalone_start_features);
811 free(framework_environment.nts.nf_mount_point_addressing_method);
812 free(framework_environment.settings.ip_v4);
813 free(framework_environment.settings.ip_v6);
814 free(framework_environment.settings.docker_engine_version);
815 free(framework_environment.settings.docker_repository);
816 free(framework_environment.settings.hostname);
817 free(framework_environment.host.ip);
818 free(framework_environment.sdn_controller.protocol);
819 free(framework_environment.sdn_controller.ip);
820 free(framework_environment.sdn_controller.callhome_ip);
821 free(framework_environment.sdn_controller.username);
822 free(framework_environment.sdn_controller.password);
823 free(framework_environment.ves_endpoint.common_header_version);
824 free(framework_environment.ves_endpoint.protocol);
825 free(framework_environment.ves_endpoint.ip);
826 free(framework_environment.ves_endpoint.auth_method);
827 free(framework_environment.ves_endpoint.username);
828 free(framework_environment.ves_endpoint.password);
829 free(framework_environment.ves_endpoint.certificate);
831 free(framework_arguments.print_structure_xpath);
832 framework_arguments.print_structure_xpath = 0;
834 for(int i = 0; i < framework_config.supervisor.rules_count; i++) {
835 free(framework_config.supervisor.rules[i].name);
836 free(framework_config.supervisor.rules[i].path);
837 for(int j = 0; j < framework_config.supervisor.rules[i].args_count; j++) {
838 free(framework_config.supervisor.rules[i].args[j]);
840 free(framework_config.supervisor.rules[i].args);
841 free(framework_config.supervisor.rules[i].stdout_path);
842 free(framework_config.supervisor.rules[i].stderr_path);
845 free(framework_config.supervisor.rules);
847 for(int i = 0; i < framework_config.docker.excluded_modules_count; i++) {
848 free(framework_config.docker.excluded_modules[i]);
850 free(framework_config.docker.excluded_modules);
852 for(int i = 0; i < framework_config.docker.excluded_features_count; i++) {
853 free(framework_config.docker.excluded_features[i]);
855 free(framework_config.docker.excluded_features);
857 for(int i = 0; i < framework_config.datastore_generate.excluded_modules_count; i++) {
858 free(framework_config.datastore_generate.excluded_modules[i]);
860 free(framework_config.datastore_generate.excluded_modules);
863 for(int i = 0; i < framework_config.datastore_generate.custom_list_instances_count; i++) {
864 free(framework_config.datastore_generate.custom_list_instances[i].path);
867 free(framework_config.datastore_generate.custom_list_instances);
869 for(int i = 0; i < framework_config.datastore_generate.restrict_schema_count; i++) {
870 free(framework_config.datastore_generate.restrict_schema[i].path);
871 for(int j = 0; j < framework_config.datastore_generate.restrict_schema[i].values_count; j++) {
872 free(framework_config.datastore_generate.restrict_schema[i].values[j]);
874 free(framework_config.datastore_generate.restrict_schema[i].values);
876 free(framework_config.datastore_generate.restrict_schema);
878 for(int i = 0; i < framework_config.datastore_populate.preg_operational_count; i++) {
879 free(framework_config.datastore_populate.preg_operational[i]);
881 free(framework_config.datastore_populate.preg_operational);
883 for(int i = 0; i < framework_config.datastore_populate.preg_running_count; i++) {
884 free(framework_config.datastore_populate.preg_running[i]);
886 free(framework_config.datastore_populate.preg_running);
889 log_add(2, "done\n");
893 static void framework_signal_handler(int signo) {
894 framework_sigint = 1;
897 static error_t parse_opt(int key, char *arg, struct argp_state *state) {
898 framework_arguments_t *iter_arguments = state->input;
901 iter_arguments->nts_mode = NTS_MODE_CONTAINER_INIT;
905 iter_arguments->nts_mode = NTS_MODE_SUPERVISOR;
909 iter_arguments->nts_mode = NTS_MODE_MANAGER;
913 iter_arguments->nts_mode = NTS_MODE_NETWORK_FUNCTION;
917 iter_arguments->nts_mode = NTS_MODE_BLANK;
921 iter_arguments->nts_mode = NTS_MODE_GENERATE_DATA;
925 iter_arguments->nts_mode = NTS_MODE_TEST;
929 iter_arguments->no_rand = true;
930 framework_arguments.fixed_seed = 0;
933 framework_arguments.fixed_seed *= 10;
934 framework_arguments.fixed_seed += arg[i] - '0';
940 iter_arguments->verbosity_level = arg[0] - '0';
948 iter_arguments->print_root_paths = true;
952 iter_arguments->print_structure_xpath = (char *)malloc(sizeof(char) * (strlen(arg) + 1));
953 if(!iter_arguments->print_structure_xpath) {
954 log_error("[framework-arg] bad malloc\n");
957 strcpy(iter_arguments->print_structure_xpath, arg);
958 if(arg[strlen(arg) - 1] == '/') {
959 iter_arguments->print_structure_xpath[strlen(arg) - 1] = 0;
964 if (state->arg_num >= 2) {
974 return ARGP_ERR_UNKNOWN;