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 { "generate", 'g', 0, 0, "Generate population data without commiting." },
49 { "test-mode", 't', 0, 0, "Test mode." },
52 { "ls", '1', 0, 0, "Print all available root paths." },
53 { "schema", '2', "XPATH", 0, "Print schema for XPATH." },
55 { "fixed-rand", 'r', "SEED", 0, "Initialize RAND seed to a fixed value (for debugging purposes)." },
56 { "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" },
57 { "workspace", 'w', "PATH", 0, "Initialize workspace to a different one than the current working directory." },
61 volatile sig_atomic_t framework_sigint;
63 static int framework_env_init(void);
64 static int framework_config_init(void);
66 static void framework_signal_handler(int signo);
67 static error_t parse_opt(int key, char *arg, struct argp_state *state);
69 int framework_init(int argc, char **argv) {
71 framework_environment.nts.version = getenv(ENV_VAR_NTS_BUILD_VERSION) ? strdup(getenv(ENV_VAR_NTS_BUILD_VERSION)) : strdup("N/A");
72 framework_environment.nts.build_time = getenv(ENV_VAR_NTS_BUILD_TIME) ? strdup(getenv(ENV_VAR_NTS_BUILD_TIME)) : strdup("N/A");
76 asprintf(&version, "ntsim-ng v%s build %s", framework_environment.nts.version, framework_environment.nts.build_time);
77 argp_program_version = version;
79 //initialize app arguments
80 framework_arguments.nts_mode = NTS_MODE_DEFAULT;
82 framework_arguments.argc = argc;
83 framework_arguments.argv = argv;
85 framework_arguments.no_rand = false;
86 framework_arguments.fixed_seed = 0;
87 framework_arguments.verbosity_level = 1;
89 framework_arguments.print_root_paths = false;
90 framework_arguments.print_structure_xpath = 0;
92 //parse provided command line arguments
93 struct argp argp = { options, parse_opt, 0, doc, 0, 0, 0 };
94 argp_parse(&argp, argc, argv, 0, 0, &framework_arguments);
98 signal(SIGINT, framework_signal_handler);
99 signal(SIGTERM, framework_signal_handler);
100 signal(SIGQUIT, framework_signal_handler);
102 //disable buffering for stdout
103 setbuf(stdout, NULL);
105 //init logging subsystem
107 char *stderr_file = 0;
109 if(!dir_exists("log")) {
113 switch(framework_arguments.nts_mode) {
114 case NTS_MODE_CONTAINER_INIT:
115 log_file = "log/log-install.txt";
116 stderr_file = "log/stderr-install.txt";
119 case NTS_MODE_SUPERVISOR:
120 log_file = "log/log-supervisor.txt";
121 stderr_file = "log/stderr-supervisor.txt";
124 case NTS_MODE_GENERATE_DATA:
125 log_file = "log/log-generate.txt";
126 stderr_file = "log/stderr-generate.txt";
130 log_file = "log/log.txt";
131 stderr_file = "log/stderr.txt";
136 log_redirect_stderr(stderr_file);
139 getcwd(cwd, sizeof(cwd));
140 log_add_verbose(2, "[framework] current working dir is: %s\n", cwd);
142 //init rand generator if needed
143 if(framework_arguments.no_rand == false) {
147 rand_init_fixed(framework_arguments.fixed_seed);
150 log_add_verbose(2, "[framework] app was called: ");
151 for(int i = 0; i < argc; i++) {
152 log_add(2, "%s ", argv[i]);
156 if(framework_env_init() != NTS_ERR_OK) {
157 log_error("[framework] framework_env_init() failed\n");
158 return NTS_ERR_FAILED;
161 if(framework_config_init() != NTS_ERR_OK) {
162 log_error("[framework] framework_config_init() failed\n");
163 return NTS_ERR_FAILED;
166 log_add_verbose(2, "[framework] init complete\n");
170 static int framework_env_init(void) {
171 log_add_verbose(2, "[framework-env] started\n");
174 The following env vars are taken care of by framework_init()
175 framework_environment.nts.version
176 framework_environment.nts.build_time
179 framework_environment.nts.manual = getenv(ENV_VAR_NTS_MANUAL) ? true : false;
180 framework_environment.nts.function_type = getenv(ENV_VAR_NTS_FUNCTION_TYPE) ? strdup(getenv(ENV_VAR_NTS_FUNCTION_TYPE)) : strdup("");
181 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("");
183 framework_environment.settings.docker_engine_version = getenv(ENV_VAR_DOCKER_ENGINE_VERSION) ? strdup(getenv(ENV_VAR_DOCKER_ENGINE_VERSION)) : strdup("1.40");
184 framework_environment.settings.hostname = getenv(ENV_VAR_HOSTNAME) ? strdup(getenv(ENV_VAR_HOSTNAME)) : strdup("localhost");
186 bool ip_ok = get_local_ips("eth0", &framework_environment.settings.ip_v4, &framework_environment.settings.ip_v6);
188 log_error("[framework-env] could not get local IP addresses\n");
191 char *ipv6_env_var = getenv(ENV_VAR_IPV6ENABLED);
192 if(ipv6_env_var == 0) {
193 log_error("[framework-env] could not get the IPv6 Enabled env variable\n");
195 framework_environment.settings.ip_v6_enabled = (strcmp(ipv6_env_var, "true") == 0) ? true : false;
196 framework_environment.settings.ssh_connections = get_int_from_string_with_default(getenv(ENV_VAR_SSH_CONNECTIONS), 1);
197 framework_environment.settings.tls_connections = get_int_from_string_with_default(getenv(ENV_VAR_TLS_CONNECTIONS), 0);
198 framework_environment.settings.ftp_connections = 1;
199 framework_environment.settings.sftp_connections = 1;
201 //build version and build time are set in the begining of the function
202 framework_environment.host.ip = getenv(ENV_VAR_HOST_IP) ? strdup(getenv(ENV_VAR_HOST_IP)) : strdup("127.0.0.1");
203 framework_environment.host.base_port = get_int_from_string_with_default(getenv(ENV_VAR_HOST_BASE_PORT), 1000);
204 framework_environment.host.ssh_base_port = get_int_from_string_with_default(getenv(ENV_VAR_HOST_NETCONF_SSH_BASE_PORT), 0);
205 framework_environment.host.tls_base_port = get_int_from_string_with_default(getenv(ENV_VAR_HOST_NETCONF_TLS_BASE_PORT), 0);
206 framework_environment.host.ftp_base_port = get_int_from_string_with_default(getenv(ENV_VAR_HOST_TRANSFER_FTP_BASE_PORT), 0);
207 framework_environment.host.sftp_base_port = get_int_from_string_with_default(getenv(ENV_VAR_HOST_TRANSFER_SFTP_BASE_PORT), 0);
209 framework_environment.sdn_controller.protocol = getenv(ENV_VAR_SDN_CONTROLLER_IP) ? strdup(getenv(ENV_VAR_SDN_CONTROLLER_PROTOCOL)) : strdup("https");
210 framework_environment.sdn_controller.ip = getenv(ENV_VAR_SDN_CONTROLLER_IP) ? strdup(getenv(ENV_VAR_SDN_CONTROLLER_IP)) : strdup("127.0.0.1");
211 framework_environment.sdn_controller.port = get_int_from_string_with_default(getenv(ENV_VAR_SDN_CONTROLLER_PORT), 8181);
212 framework_environment.sdn_controller.callhome_port = get_int_from_string_with_default(getenv(ENV_VAR_SDN_CONTROLLER_CALLHOME_PORT), 6666);
213 framework_environment.sdn_controller.username = getenv(ENV_VAR_SDN_CONTROLLER_USERNAME) ? strdup(getenv(ENV_VAR_SDN_CONTROLLER_USERNAME)) : strdup("admin");
214 framework_environment.sdn_controller.password = getenv(ENV_VAR_SDN_CONTROLLER_PASSWORD) ? strdup(getenv(ENV_VAR_SDN_CONTROLLER_PASSWORD)) : strdup("admin");
216 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");
217 framework_environment.ves_endpoint.protocol = getenv(ENV_VAR_VES_ENDPOINT_PROTOCOL) ? strdup(getenv(ENV_VAR_VES_ENDPOINT_PROTOCOL)) : strdup("https");
218 framework_environment.ves_endpoint.ip = getenv(ENV_VAR_VES_ENDPOINT_IP) ? strdup(getenv(ENV_VAR_VES_ENDPOINT_IP)) : strdup("127.0.0.1");
219 framework_environment.ves_endpoint.port = get_int_from_string_with_default(getenv(ENV_VAR_VES_ENDPOINT_PORT), 1234);
220 framework_environment.ves_endpoint.auth_method = getenv(ENV_VAR_VES_ENDPOINT_AUTH_METHOD) ? strdup(getenv(ENV_VAR_VES_ENDPOINT_AUTH_METHOD)) : strdup("no-auth");
221 framework_environment.ves_endpoint.username = getenv(ENV_VAR_VES_ENDPOINT_USERNAME) ? strdup(getenv(ENV_VAR_VES_ENDPOINT_USERNAME)) : strdup("admin");
222 framework_environment.ves_endpoint.password = getenv(ENV_VAR_VES_ENDPOINT_PASSWORD) ? strdup(getenv(ENV_VAR_VES_ENDPOINT_PASSWORD)) : strdup("admin");
223 framework_environment.ves_endpoint.certificate = getenv(ENV_VAR_VES_ENDPOINT_CERTIFICATE) ? strdup(getenv(ENV_VAR_VES_ENDPOINT_CERTIFICATE)) : strdup("");
225 log_add_verbose(2, "[framework-env] nts.manual = %d\n", framework_environment.nts.manual);
226 log_add_verbose(2, "[framework-env] nts.version = %s\n", framework_environment.nts.version);
227 log_add_verbose(2, "[framework-env] nts.build_time = %s\n", framework_environment.nts.build_time);
228 log_add_verbose(2, "[framework-env] nts.function_type = %s\n", framework_environment.nts.function_type);
229 log_add_verbose(2, "[framework-env] nts.nf_standalone_start_features = %s\n", framework_environment.nts.nf_standalone_start_features);
231 log_add_verbose(2, "[framework-env] settings.docker_engine_version = %s\n", framework_environment.settings.docker_engine_version);
232 log_add_verbose(2, "[framework-env] settings.hostname = %s\n", framework_environment.settings.hostname);
233 log_add_verbose(2, "[framework-env] settings.ip_v4 = %s\n", framework_environment.settings.ip_v4);
234 log_add_verbose(2, "[framework-env] settings.ip_v6 = %s\n", framework_environment.settings.ip_v6);
235 log_add_verbose(2, "[framework-env] settings.ip_v6_enabled = %s\n", framework_environment.settings.ip_v6_enabled ? "true" : "false");
236 log_add_verbose(2, "[framework-env] settings.ssh_connections = %d\n", framework_environment.settings.ssh_connections);
237 log_add_verbose(2, "[framework-env] settings.tls_connections = %d\n", framework_environment.settings.tls_connections);
238 log_add_verbose(2, "[framework-env] settings.ftp_connections = %d\n", framework_environment.settings.ftp_connections);
239 log_add_verbose(2, "[framework-env] settings.sftp_connections = %d\n", framework_environment.settings.sftp_connections);
242 if(framework_environment.host.base_port < 1000) {
243 log_add_verbose(2, "[framework-env] host.base_port < 1000 -> disabling\n");
244 framework_environment.host.base_port = 0;
247 if(framework_environment.host.ssh_base_port < 1000) {
248 log_add_verbose(2, "[framework-env] host.ssh_base_port < 1000 -> using base_port\n");
249 framework_environment.host.ssh_base_port = framework_environment.host.base_port;
252 if(framework_environment.host.tls_base_port < 1000) {
253 log_add_verbose(2, "[framework-env] host.tls_base_port < 1000 -> using base_port\n");
254 framework_environment.host.tls_base_port = framework_environment.host.base_port;
257 if(framework_environment.host.ftp_base_port < 1000) {
258 log_add_verbose(2, "[framework-env] host.ftp_base_port < 1000 -> using base_port\n");
259 framework_environment.host.ftp_base_port = framework_environment.host.base_port;
262 if(framework_environment.host.sftp_base_port < 1000) {
263 log_add_verbose(2, "[framework-env] host.sftp_base_port < 1000 -> using base_port\n");
264 framework_environment.host.sftp_base_port = framework_environment.host.base_port;
267 if(framework_environment.host.base_port == 0) {
268 if(framework_environment.host.ssh_base_port == 0) {
269 log_error("[framework-env] host.ssh_base_port unknown\n");
270 return NTS_ERR_FAILED;
273 if(framework_environment.host.tls_base_port == 0) {
274 log_error("[framework-env] host.tls_base_port unknown\n");
275 return NTS_ERR_FAILED;
278 if(framework_environment.host.ftp_base_port == 0) {
279 log_error("[framework-env] host.ftp_base_port unknown\n");
280 return NTS_ERR_FAILED;
283 if(framework_environment.host.sftp_base_port == 0) {
284 log_error("[framework-env] host.sftp_base_port unknown\n");
285 return NTS_ERR_FAILED;
289 log_add_verbose(2, "[framework-env] host.ip = %s\n", framework_environment.host.ip);
290 log_add_verbose(2, "[framework-env] host.base_port = %d\n", framework_environment.host.base_port);
291 log_add_verbose(2, "[framework-env] host.ssh_base_port = %d\n", framework_environment.host.ssh_base_port);
292 log_add_verbose(2, "[framework-env] host.tls_base_port = %d\n", framework_environment.host.tls_base_port);
293 log_add_verbose(2, "[framework-env] host.ftp_base_port = %d\n", framework_environment.host.ftp_base_port);
294 log_add_verbose(2, "[framework-env] host.sftp_base_port = %d\n", framework_environment.host.sftp_base_port);
296 log_add_verbose(2, "[framework-env] sdn_controller.protocol = %s\n", framework_environment.sdn_controller.protocol);
297 log_add_verbose(2, "[framework-env] sdn_controller.ip = %s\n", framework_environment.sdn_controller.ip);
298 log_add_verbose(2, "[framework-env] sdn_controller.port = %d\n", framework_environment.sdn_controller.port);
299 log_add_verbose(2, "[framework-env] sdn_controller.callhome_port = %d\n", framework_environment.sdn_controller.callhome_port);
300 log_add_verbose(2, "[framework-env] sdn_controller.username = %s\n", framework_environment.sdn_controller.username);
301 log_add_verbose(2, "[framework-env] sdn_controller.password = %s\n", framework_environment.sdn_controller.password);
303 log_add_verbose(2, "[framework-env] ves_endpoint.common_header_version = %s\n", framework_environment.ves_endpoint.common_header_version);
304 log_add_verbose(2, "[framework-env] ves_endpoint.protocol = %s\n", framework_environment.ves_endpoint.protocol);
305 log_add_verbose(2, "[framework-env] ves_endpoint.ip = %s\n", framework_environment.ves_endpoint.ip);
306 log_add_verbose(2, "[framework-env] ves_endpoint.port = %d\n", framework_environment.ves_endpoint.port);
307 log_add_verbose(2, "[framework-env] ves_endpoint.auth_method = %s\n", framework_environment.ves_endpoint.auth_method);
308 log_add_verbose(2, "[framework-env] ves_endpoint.username = %s\n", framework_environment.ves_endpoint.username);
309 log_add_verbose(2, "[framework-env] ves_endpoint.password = %s\n", framework_environment.ves_endpoint.password);
310 log_add_verbose(2, "[framework-env] ves_endpoint.certificate = %s\n", framework_environment.ves_endpoint.certificate);
312 log_add_verbose(2, "[framework-env] finished\n");
316 static int framework_config_init(void) {
317 log_add_verbose(2, "[framework-config] started\n");
320 framework_config.docker.excluded_modules = 0;
321 framework_config.docker.excluded_modules_count = 0;
322 framework_config.docker.excluded_features = 0;
323 framework_config.docker.excluded_features_count = 0;
325 framework_config.supervisor.rules_count = 0;
326 framework_config.supervisor.rules = 0;
328 framework_config.datastore_generate.debug_max_string_size = 0;
329 framework_config.datastore_generate.excluded_modules = 0;
330 framework_config.datastore_generate.excluded_modules_count = 0;
331 framework_config.datastore_generate.default_list_instances = 1;
332 framework_config.datastore_generate.custom_list_instances_count = 0;
333 framework_config.datastore_generate.custom_list_instances = 0;
334 framework_config.datastore_generate.restrict_schema_count = 0;
335 framework_config.datastore_generate.restrict_schema = 0;
337 framework_config.datastore_populate.random_generation_enabled = 1;
338 framework_config.datastore_populate.preg_operational_count = 0;
339 framework_config.datastore_populate.preg_operational = 0;
340 framework_config.datastore_populate.preg_running_count = 0;
341 framework_config.datastore_populate.preg_running = 0;
344 if(!dir_exists("config")) {
345 log_add_verbose(2, "[framework-config] config/ folder wasn't found; created.\n");
346 mkdir("config", 0777);
349 if(!file_exists("config/config.json")) {
350 log_add_verbose(2, "[framework-config] config.json file missing; created.\n");
351 file_touch("config/config.json", "{}");
354 log_add_verbose(2, "[framework-config] parsing config.json\n");
355 char *config_contents = file_read_content("config/config.json");
356 cJSON *json = cJSON_Parse(config_contents);
357 free(config_contents);
359 log_error("[framework-config] config.json error: %s\n", cJSON_GetErrorPtr());
365 if(framework_arguments.nts_mode == NTS_MODE_CONTAINER_INIT) {
366 main_node = cJSON_GetObjectItem(json, "container-rules");
368 node = cJSON_GetObjectItem(main_node, "excluded-modules");
370 if(cJSON_IsArray(node)) {
372 cJSON_ArrayForEach(element, node) {
373 if(cJSON_IsString(element)) {
374 log_add_verbose(2, "[framework-config] adding container-rules/exclude-modules: %s\n", element->valuestring);
375 framework_config.docker.excluded_modules = (char **)realloc(framework_config.docker.excluded_modules, sizeof(char*) * (framework_config.docker.excluded_modules_count + 1));
376 if(!framework_config.docker.excluded_modules) {
377 log_error("[framework-config] bad realloc\n");
379 framework_config.docker.excluded_modules[framework_config.docker.excluded_modules_count] = (char *)malloc(sizeof(char) * (strlen(element->valuestring) + 1));
380 if(!framework_config.docker.excluded_modules[framework_config.docker.excluded_modules_count]) {
381 log_error("[framework-config] bad malloc\n");
383 strcpy(framework_config.docker.excluded_modules[framework_config.docker.excluded_modules_count], element->valuestring);
384 framework_config.docker.excluded_modules_count++;
390 node = cJSON_GetObjectItem(main_node, "excluded-features");
392 if(cJSON_IsArray(node)) {
394 cJSON_ArrayForEach(element, node) {
395 if(cJSON_IsString(element)) {
396 log_add_verbose(2, "[framework-config] adding container-rules/excluded-features: %s\n", element->valuestring);
397 framework_config.docker.excluded_features = (char **)realloc(framework_config.docker.excluded_features, sizeof(char*) * (framework_config.docker.excluded_features_count + 1));
398 if(!framework_config.docker.excluded_features) {
399 log_error("[framework-config] bad realloc\n");
401 framework_config.docker.excluded_features[framework_config.docker.excluded_features_count] = (char *)malloc(sizeof(char) * (strlen(element->valuestring) + 1));
402 if(!framework_config.docker.excluded_features[framework_config.docker.excluded_features_count]) {
403 log_error("[framework-config] bad malloc\n");
405 strcpy(framework_config.docker.excluded_features[framework_config.docker.excluded_features_count], element->valuestring);
406 framework_config.docker.excluded_features_count++;
413 else if(framework_arguments.nts_mode == NTS_MODE_SUPERVISOR) {
414 main_node = cJSON_GetObjectItem(json, "supervisor-rules");
417 cJSON_ArrayForEach(app, main_node) {
418 if(cJSON_IsObject(app)) {
419 cJSON *object = cJSON_GetObjectItem(app, "path");
421 framework_config.supervisor.rules = (supervisor_rules_t *)realloc(framework_config.supervisor.rules, sizeof(supervisor_rules_t) * (framework_config.supervisor.rules_count + 1));
422 if(!framework_config.supervisor.rules) {
423 log_error("[framework-config] bad realloc\n");
426 char *path = strdup(object->valuestring);
427 bool autorestart = false;
428 bool nomanual = false;
429 char *stdout_path = 0;
430 char *stderr_path = 0;
434 cJSON *args_json = cJSON_GetObjectItem(app, "args");
436 args_count = cJSON_GetArraySize(args_json);
438 args = malloc(sizeof(char *) * args_count);
441 cJSON_ArrayForEach(arg, args_json) {
442 args[i] = strdup(arg->valuestring);
448 object = cJSON_GetObjectItem(app, "autorestart");
450 autorestart = object->valueint;
453 object = cJSON_GetObjectItem(app, "nomanual");
455 nomanual = object->valueint;
458 object = cJSON_GetObjectItem(app, "stdout");
460 stdout_path = strdup(object->valuestring);
463 object = cJSON_GetObjectItem(app, "stderr");
465 stderr_path = strdup(object->valuestring);
468 framework_config.supervisor.rules[framework_config.supervisor.rules_count].name = strdup(app->string);
469 framework_config.supervisor.rules[framework_config.supervisor.rules_count].path = path;
470 framework_config.supervisor.rules[framework_config.supervisor.rules_count].args = args;
471 framework_config.supervisor.rules[framework_config.supervisor.rules_count].args_count = args_count;
472 framework_config.supervisor.rules[framework_config.supervisor.rules_count].autorestart = autorestart;
473 framework_config.supervisor.rules[framework_config.supervisor.rules_count].nomanual = nomanual;
474 framework_config.supervisor.rules[framework_config.supervisor.rules_count].stdout_path = stdout_path;
475 framework_config.supervisor.rules[framework_config.supervisor.rules_count].stderr_path = stderr_path;
477 log_add_verbose(2, "[framework-config] adding supervisor command: %s with autorestart: %d\n", path, autorestart);
478 framework_config.supervisor.rules_count++;
485 main_node = cJSON_GetObjectItem(json, "datastore-random-generation-rules");
487 node = cJSON_GetObjectItem(main_node, "excluded-modules");
489 if(cJSON_IsArray(node)) {
491 cJSON_ArrayForEach(element, node) {
492 if(cJSON_IsString(element)) {
493 log_add_verbose(2, "[framework-config] adding datastore-random-generation-rules/excluded-modules: %s\n", element->valuestring);
494 framework_config.datastore_generate.excluded_modules = (char **)realloc(framework_config.datastore_generate.excluded_modules, sizeof(char*) * (framework_config.datastore_generate.excluded_modules_count + 1));
495 if(!framework_config.datastore_generate.excluded_modules) {
496 log_error("[framework-config] bad realloc\n");
498 framework_config.datastore_generate.excluded_modules[framework_config.datastore_generate.excluded_modules_count] = (char *)malloc(sizeof(char) * (strlen(element->valuestring) + 1));
499 if(!framework_config.datastore_generate.excluded_modules[framework_config.datastore_generate.excluded_modules_count]) {
500 log_error("[framework-config] bad malloc\n");
502 strcpy(framework_config.datastore_generate.excluded_modules[framework_config.datastore_generate.excluded_modules_count], element->valuestring);
503 framework_config.datastore_generate.excluded_modules_count++;
509 node = cJSON_GetObjectItem(main_node, "debug-max-string-size");
511 framework_config.datastore_generate.debug_max_string_size = node->valueint;
512 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);
515 node = cJSON_GetObjectItem(main_node, "default-list-instances");
517 if(cJSON_IsNumber(node)) {
518 framework_config.datastore_generate.default_list_instances = node->valueint;
519 log_add_verbose(2, "[framework-config] setting datastore-random-generation-rules/default-list-instances: %d\n", framework_config.datastore_generate.default_list_instances);
523 node = cJSON_GetObjectItem(main_node, "custom-list-instances");
525 if(cJSON_IsArray(node)) {
527 cJSON_ArrayForEach(element, node) {
528 if(cJSON_IsObject(element)) {
530 cJSON_ArrayForEach(object, element) {
531 char *path = object->string;
532 int count = object->valueint;
533 log_add_verbose(2, "[framework-config] adding datastore-random-generation-rules/custom-list-instances %s - %d\n", path, count);
534 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));
535 if(!framework_config.datastore_generate.custom_list_instances) {
536 log_error("[framework-config] bad realloc\n");
539 framework_config.datastore_generate.custom_list_instances[framework_config.datastore_generate.custom_list_instances_count].path = (char *)malloc(sizeof(char) * (strlen(path) + 1));
540 if(!framework_config.datastore_generate.custom_list_instances[framework_config.datastore_generate.custom_list_instances_count].path) {
541 log_error("[framework-config] bad malloc\n");
543 strcpy(framework_config.datastore_generate.custom_list_instances[framework_config.datastore_generate.custom_list_instances_count].path, path);
544 framework_config.datastore_generate.custom_list_instances[framework_config.datastore_generate.custom_list_instances_count].count = count;
545 framework_config.datastore_generate.custom_list_instances_count++;
552 node = cJSON_GetObjectItem(main_node, "restrict-schema");
554 if(cJSON_IsArray(node)) {
556 cJSON_ArrayForEach(element, node) {
557 if(cJSON_IsObject(element)) {
559 cJSON_ArrayForEach(object, element) {
560 char *path = object->string;
562 log_add_verbose(2, "[framework-config] adding datastore-random-generation-rules/restrict-schema: %s with values:", path);
563 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));
564 if(!framework_config.datastore_generate.restrict_schema) {
565 log_error("[framework-config] bad realloc\n");
568 framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].path = (char *)malloc(sizeof(char) * (strlen(path) + 1));
569 if(!framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].path) {
570 log_error("[framework-config] bad malloc\n");
572 strcpy(framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].path, path);
575 framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].values_count = 0;
576 framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].values = 0;
577 framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].index = 0;
579 cJSON_ArrayForEach(value, object) {
580 if(cJSON_IsString(value)) {
581 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));
582 if(!framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].values) {
583 log_error("[framework-config] bad realloc\n");
585 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));
586 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]) {
587 log_error("[framework-config] bad malloc\n");
589 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);
590 framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].values_count++;
592 log_add(2, " %s", value->valuestring);
597 framework_config.datastore_generate.restrict_schema_count++;
605 main_node = cJSON_GetObjectItem(json, "datastore-populate-rules");
607 node = cJSON_GetObjectItem(main_node, "random-generation-enabled");
609 framework_config.datastore_populate.random_generation_enabled = node->valueint;
610 log_add_verbose(2, "[framework-config] setting datastore-populate-rules/random-generation-enabled: %d\n", framework_config.datastore_populate.random_generation_enabled);
613 log_add_verbose(2, "[framework-config] setting datastore-populate-rules/random-generation-enabled: %d [default value]\n", framework_config.datastore_populate.random_generation_enabled);
616 node = cJSON_GetObjectItem(main_node, "pre-generated-operational-data");
618 if(cJSON_IsArray(node)) {
620 cJSON_ArrayForEach(element, node) {
621 if(cJSON_IsString(element)) {
622 log_add_verbose(2, "[framework-config] adding datastore-populate-rules/pre-generated-operational-data: %s\n", element->valuestring);
623 framework_config.datastore_populate.preg_operational = (char **)realloc(framework_config.datastore_populate.preg_operational, sizeof(char*) * (framework_config.datastore_populate.preg_operational_count + 1));
624 if(!framework_config.datastore_populate.preg_operational) {
625 log_error("[framework-config] bad realloc\n");
627 framework_config.datastore_populate.preg_operational[framework_config.datastore_populate.preg_operational_count] = (char *)malloc(sizeof(char) * (strlen(element->valuestring) + 1));
628 if(!framework_config.datastore_populate.preg_operational[framework_config.datastore_populate.preg_operational_count]) {
629 log_error("[framework-config] bad malloc\n");
631 strcpy(framework_config.datastore_populate.preg_operational[framework_config.datastore_populate.preg_operational_count], element->valuestring);
632 framework_config.datastore_populate.preg_operational_count++;
638 node = cJSON_GetObjectItem(main_node, "pre-generated-running-data");
640 if(cJSON_IsArray(node)) {
642 cJSON_ArrayForEach(element, node) {
643 if(cJSON_IsString(element)) {
644 log_add_verbose(2, "[framework-config] adding datastore-populate-rules/pre-generated-running-data: %s\n", element->valuestring);
645 framework_config.datastore_populate.preg_running = (char **)realloc(framework_config.datastore_populate.preg_running, sizeof(char*) * (framework_config.datastore_populate.preg_running_count + 1));
646 if(!framework_config.datastore_populate.preg_running) {
647 log_error("[framework-config] bad realloc\n");
649 framework_config.datastore_populate.preg_running[framework_config.datastore_populate.preg_running_count] = (char *)malloc(sizeof(char) * (strlen(element->valuestring) + 1));
650 if(!framework_config.datastore_populate.preg_running[framework_config.datastore_populate.preg_running_count]) {
651 log_error("[framework-config] bad malloc\n");
653 strcpy(framework_config.datastore_populate.preg_running[framework_config.datastore_populate.preg_running_count], element->valuestring);
654 framework_config.datastore_populate.preg_running_count++;
666 log_add_verbose(2, "[framework-config] finished parsing config.json\n");
671 void framework_free(void) {
672 log_add_verbose(2, "[framework-config] framework_free()... ");
678 free((char *)argp_program_version);
679 argp_program_version = 0;
681 free(framework_environment.nts.version);
682 free(framework_environment.nts.build_time);
683 free(framework_environment.nts.function_type);
684 free(framework_environment.nts.nf_standalone_start_features);
685 free(framework_environment.settings.ip_v4);
686 free(framework_environment.settings.ip_v6);
687 free(framework_environment.settings.docker_engine_version);
688 free(framework_environment.settings.hostname);
689 free(framework_environment.host.ip);
690 free(framework_environment.sdn_controller.protocol);
691 free(framework_environment.sdn_controller.ip);
692 free(framework_environment.sdn_controller.username);
693 free(framework_environment.sdn_controller.password);
694 free(framework_environment.ves_endpoint.common_header_version);
695 free(framework_environment.ves_endpoint.protocol);
696 free(framework_environment.ves_endpoint.ip);
697 free(framework_environment.ves_endpoint.auth_method);
698 free(framework_environment.ves_endpoint.username);
699 free(framework_environment.ves_endpoint.password);
700 free(framework_environment.ves_endpoint.certificate);
702 free(framework_arguments.print_structure_xpath);
703 framework_arguments.print_structure_xpath = 0;
705 for(int i = 0; i < framework_config.supervisor.rules_count; i++) {
706 free(framework_config.supervisor.rules[i].name);
707 free(framework_config.supervisor.rules[i].path);
708 for(int j = 0; j < framework_config.supervisor.rules[i].args_count; j++) {
709 free(framework_config.supervisor.rules[i].args[j]);
711 free(framework_config.supervisor.rules[i].args);
712 free(framework_config.supervisor.rules[i].stdout_path);
713 free(framework_config.supervisor.rules[i].stderr_path);
716 free(framework_config.supervisor.rules);
718 for(int i = 0; i < framework_config.docker.excluded_modules_count; i++) {
719 free(framework_config.docker.excluded_modules[i]);
721 free(framework_config.docker.excluded_modules);
723 for(int i = 0; i < framework_config.docker.excluded_features_count; i++) {
724 free(framework_config.docker.excluded_features[i]);
726 free(framework_config.docker.excluded_features);
728 for(int i = 0; i < framework_config.datastore_generate.excluded_modules_count; i++) {
729 free(framework_config.datastore_generate.excluded_modules[i]);
731 free(framework_config.datastore_generate.excluded_modules);
734 for(int i = 0; i < framework_config.datastore_generate.custom_list_instances_count; i++) {
735 free(framework_config.datastore_generate.custom_list_instances[i].path);
738 free(framework_config.datastore_generate.custom_list_instances);
740 for(int i = 0; i < framework_config.datastore_generate.restrict_schema_count; i++) {
741 free(framework_config.datastore_generate.restrict_schema[i].path);
742 for(int j = 0; j < framework_config.datastore_generate.restrict_schema[i].values_count; j++) {
743 free(framework_config.datastore_generate.restrict_schema[i].values[j]);
745 free(framework_config.datastore_generate.restrict_schema[i].values);
747 free(framework_config.datastore_generate.restrict_schema);
749 for(int i = 0; i < framework_config.datastore_populate.preg_operational_count; i++) {
750 free(framework_config.datastore_populate.preg_operational[i]);
752 free(framework_config.datastore_populate.preg_operational);
754 for(int i = 0; i < framework_config.datastore_populate.preg_running_count; i++) {
755 free(framework_config.datastore_populate.preg_running[i]);
757 free(framework_config.datastore_populate.preg_running);
760 log_add(2, "done\n");
764 static void framework_signal_handler(int signo) {
765 framework_sigint = 1;
768 static error_t parse_opt(int key, char *arg, struct argp_state *state) {
769 framework_arguments_t *iter_arguments = state->input;
772 iter_arguments->nts_mode = NTS_MODE_CONTAINER_INIT;
776 iter_arguments->nts_mode = NTS_MODE_SUPERVISOR;
780 iter_arguments->nts_mode = NTS_MODE_MANAGER;
784 iter_arguments->nts_mode = NTS_MODE_NETWORK_FUNCTION;
788 iter_arguments->nts_mode = NTS_MODE_GENERATE_DATA;
792 iter_arguments->nts_mode = NTS_MODE_TEST;
796 iter_arguments->no_rand = true;
797 framework_arguments.fixed_seed = 0;
800 framework_arguments.fixed_seed *= 10;
801 framework_arguments.fixed_seed += arg[i] - '0';
807 iter_arguments->verbosity_level = arg[0] - '0';
815 iter_arguments->print_root_paths = true;
819 iter_arguments->print_structure_xpath = (char *)malloc(sizeof(char) * (strlen(arg) + 1));
820 if(!iter_arguments->print_structure_xpath) {
821 log_error("[framework-arg] bad malloc\n");
824 strcpy(iter_arguments->print_structure_xpath, arg);
825 if(arg[strlen(arg) - 1] == '/') {
826 iter_arguments->print_structure_xpath[strlen(arg) - 1] = 0;
831 if (state->arg_num >= 2) {
841 return ARGP_ERR_UNKNOWN;