Add supoprt for D release use-case.
[sim/o1-interface.git] / ntsimulator / ntsim-ng / core / framework.c
index c241468..c916d96 100644 (file)
 #include "utils/rand_utils.h"
 
 framework_arguments_t framework_arguments;
-framework_config_t framework_config;
 framework_environment_t framework_environment;
+framework_config_t framework_config;
 
-const char *argp_program_version = "ntsim-ng v1.0.6";
+const char *argp_program_version = 0;    //is set later
 const char *argp_program_bug_address = "<alexandru.stancu@highstreet-technologies.com> / <adrian.lita@highstreet-technologies.com>";
 static char doc[] = "ntsim - new generation";
 
 static struct argp_option options[] = {
-    // docker init functionality, independent from rest of the app
-    { "docker-init", 'i', 0, 0, "Runs initialization tasks for the Docker container that's being built. Do not run manually." },
-
-    // daemon modes (choose only one)
+    { "container-init", 'i', 0, 0, "Runs initialization tasks for the Docker container that's being built. Do not run manually." },
+    { "supervisor", 's', 0, 0, "Run as supervisor; manager/network-function is chosen via config.json"},
     { "manager", 'm', 0, 0, "Run the daemon as manager." },
     { "network-function", 'f', 0, 0, "Run the daemon as network function." },
-
-    // global settings, can be combined
-    { "operational-only", 'o', 0, 0, "When this is set, the RUNNING datastore is actually the OPERATIONAL one." },
+    { "generate", 'g', 0, 0, "Generate population data without commiting." },
+    { "test-mode", 't', 0, 0, "Test mode." },
+    
+    // tools
+    { "ls", '1', 0, 0, "Print all available root paths." },
+    { "schema", '2', "XPATH", 0, "Print schema for XPATH." },
+    
     { "fixed-rand", 'r', "SEED", 0, "Initialize RAND seed to a fixed value (for debugging purposes)." },
     { "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" },
     { "workspace", 'w', "PATH", 0, "Initialize workspace to a different one than the current working directory." },
-
-    // test modes (choose only one)
-    { "test-mode", 't', 0, 0, "Test mode to be deleted after." },
-    { "exhaustive-test", '0', 0, 0, "Do an automated test on the whole delpoy." },
-
-    // functions, can be combined
-    { "ls", '1', 0, 0, "Print all available root paths." },
-    { "schema", '2', "XPATH", 0, "Print schema for XPATH." },
-    { "populate", '3', 0, 0, "Populate everything." },
-    { "enable-features", '4', 0, 0, "Enables features. Usually works combined with populate." },
-
-    // function settings, can be combined with functions as well
-    { "nc-server-init", 'n', 0, 0, "Sets netconf server configuration." },
-    { "loop", 'l', 0, 0, "After doing the job, don't exit until CTRL+C is pressed." },
     { 0 } 
 };
 
 volatile sig_atomic_t framework_sigint;
-static void framework_signal_handler(int signo);
 
+static int framework_env_init(void);
+static int framework_config_init(void);
+
+static void framework_signal_handler(int signo);
 static error_t parse_opt(int key, char *arg, struct argp_state *state);
 
-void framework_init(int argc, char **argv) {
+int framework_init(int argc, char **argv) {
+    //environment vars
+    framework_environment.nts.version = getenv(ENV_VAR_NTS_BUILD_VERSION) ? strdup(getenv(ENV_VAR_NTS_BUILD_VERSION)) : strdup("N/A");
+    framework_environment.nts.build_time = getenv(ENV_VAR_NTS_BUILD_TIME) ? strdup(getenv(ENV_VAR_NTS_BUILD_TIME)) : strdup("N/A");
+
+    //set argp_version
+    char *version = 0;
+    asprintf(&version, "ntsim-ng v%s build %s", framework_environment.nts.version, framework_environment.nts.build_time);
+    argp_program_version = version;
+
     //initialize app arguments
-    framework_arguments.container_init = false;
-    framework_arguments.nc_server_init = false;
+    framework_arguments.nts_mode = NTS_MODE_DEFAULT;
+
+    framework_arguments.argc = argc;
+    framework_arguments.argv = argv;
 
-    framework_arguments.manager = false;
-    framework_arguments.network_function = false;
-    
     framework_arguments.no_rand = false;
     framework_arguments.fixed_seed = 0;
-    framework_arguments.operational_only = false;
     framework_arguments.verbosity_level = 1;
-    framework_arguments.loop = false;
-    framework_arguments.test_mode = false;
-    
-    framework_arguments.exhaustive_test = false;
+
     framework_arguments.print_root_paths = false;
     framework_arguments.print_structure_xpath = 0;
-    framework_arguments.populate_all = false;
-    framework_arguments.enable_features = false;
 
+    //parse provided command line arguments
+    struct argp argp = { options, parse_opt, 0, doc, 0, 0, 0 };
+    argp_parse(&argp, argc, argv, 0, 0, &framework_arguments);
+
+    //manage signals
     framework_sigint = 0;
     signal(SIGINT, framework_signal_handler);
     signal(SIGTERM, framework_signal_handler);
-    signal(SIGKILL, framework_signal_handler);
     signal(SIGQUIT, framework_signal_handler);
 
-    //parse provided command line arguments
-    struct argp argp = { options, parse_opt, 0, doc, 0, 0, 0 };
-    argp_parse(&argp, argc, argv, 0, 0, &framework_arguments);
-
     //disable buffering for stdout
     setbuf(stdout, NULL);
 
-    int status = 0;
-
-    //test whether log and config folders are ok
-    if(!dir_exists("config")) {
-        status |= 1;
-        mkdir("config", 0777);
-    }
+    //init logging subsystem
+    char *log_file = 0;
+    char *stderr_file = 0;
 
     if(!dir_exists("log")) {
-        status |= 2;
         mkdir("log", 0777);
     }
 
-    //init logging subsystem
-    log_init("log/log.txt");
-    log_message(2, "app was called: ");
-    for(int i = 0; i < argc; i++) {
-        log_message(2, "%s ", argv[i]);
-    }
-    log_message(2, "\n");
+    switch(framework_arguments.nts_mode) {
+        case NTS_MODE_CONTAINER_INIT:
+            log_file = "log/log-install.txt";
+            stderr_file = "log/stderr-install.txt";
+            break;
 
-    char cwd[PATH_MAX];
-    getcwd(cwd, sizeof(cwd));
-    log_message(2, "current working dir is: %s\n", cwd);
+        case NTS_MODE_SUPERVISOR:
+            log_file = "log/log-supervisor.txt";
+            stderr_file = "log/stderr-supervisor.txt";
+            break;
 
-    if(status & 1) {
-        log_message(2, "config folder wasn't found, and was created.\n");
-    }
+        case NTS_MODE_GENERATE_DATA:
+            log_file = "log/log-generate.txt";
+            stderr_file = "log/stderr-generate.txt";
+            break;
 
-    if(status & 2) {
-        log_message(2, "log folder wasn't found, and was created.\n");
+        default:
+            log_file = "log/log.txt";
+            stderr_file = "log/stderr.txt";
+            break;
     }
 
-    if(!file_exists("config/config.json")) {
-        log_message(2, "config.json file missing. created.\n");
-        file_touch("config/config.json", "{}");
-    }
+    log_init(log_file);
+    log_redirect_stderr(stderr_file);
+
+    char cwd[PATH_MAX];
+    getcwd(cwd, sizeof(cwd));
+    log_add_verbose(2, "[framework] current working dir is: %s\n", cwd);
 
     //init rand generator if needed
     if(framework_arguments.no_rand == false) {
@@ -155,397 +147,618 @@ void framework_init(int argc, char **argv) {
         rand_init_fixed(framework_arguments.fixed_seed);
     }
 
+    log_add_verbose(2, "[framework] app was called: ");
+    for(int i = 0; i < argc; i++) {
+        log_add(2, "%s ", argv[i]);
+    }
+    log_add(2, "\n");
+
+    if(framework_env_init() != NTS_ERR_OK) {
+        log_error("[framework] framework_env_init() failed\n");
+        return NTS_ERR_FAILED;
+    }
+
+    if(framework_config_init() != NTS_ERR_OK) {
+        log_error("[framework] framework_config_init() failed\n");
+        return NTS_ERR_FAILED;
+    }
+
+    log_add_verbose(2, "[framework] init complete\n");
+    return NTS_ERR_OK;
+}
+
+static int framework_env_init(void) {
+    log_add_verbose(2, "[framework-env] started\n");
+
+    /*
+    The following env vars are taken care of by framework_init()
+        framework_environment.nts.version
+        framework_environment.nts.build_time
+    */
+
+    framework_environment.nts.manual = getenv(ENV_VAR_NTS_MANUAL) ? true : false;
+    framework_environment.nts.function_type = getenv(ENV_VAR_NTS_FUNCTION_TYPE) ? strdup(getenv(ENV_VAR_NTS_FUNCTION_TYPE)) : strdup("");
+    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("");
+
+    framework_environment.settings.docker_engine_version = getenv(ENV_VAR_DOCKER_ENGINE_VERSION) ? strdup(getenv(ENV_VAR_DOCKER_ENGINE_VERSION)) : strdup("1.40");
+    framework_environment.settings.hostname = getenv(ENV_VAR_HOSTNAME) ? strdup(getenv(ENV_VAR_HOSTNAME)) : strdup("localhost");
+
+    bool ip_ok = get_local_ips("eth0", &framework_environment.settings.ip_v4, &framework_environment.settings.ip_v6);
+    if(!ip_ok) {
+        log_error("[framework-env] could not get local IP addresses\n");
+    }
+
+    char *ipv6_env_var = getenv(ENV_VAR_IPV6ENABLED);
+    if(ipv6_env_var == 0) {
+        log_error("[framework-env] could not get the IPv6 Enabled env variable\n");
+    }
+    framework_environment.settings.ip_v6_enabled = (strcmp(ipv6_env_var, "true") == 0) ? true : false;
+    framework_environment.settings.ssh_connections = get_int_from_string_with_default(getenv(ENV_VAR_SSH_CONNECTIONS), 1);
+    framework_environment.settings.tls_connections = get_int_from_string_with_default(getenv(ENV_VAR_TLS_CONNECTIONS), 0);
+    framework_environment.settings.ftp_connections = 1;
+    framework_environment.settings.sftp_connections = 1;
+
+    //build version and build time are set in the begining of the function
+    framework_environment.host.ip = getenv(ENV_VAR_HOST_IP) ? strdup(getenv(ENV_VAR_HOST_IP)) : strdup("127.0.0.1");
+    framework_environment.host.base_port = get_int_from_string_with_default(getenv(ENV_VAR_HOST_BASE_PORT), 1000);
+    framework_environment.host.ssh_base_port = get_int_from_string_with_default(getenv(ENV_VAR_HOST_NETCONF_SSH_BASE_PORT), 0);
+    framework_environment.host.tls_base_port = get_int_from_string_with_default(getenv(ENV_VAR_HOST_NETCONF_TLS_BASE_PORT), 0);
+    framework_environment.host.ftp_base_port = get_int_from_string_with_default(getenv(ENV_VAR_HOST_TRANSFER_FTP_BASE_PORT), 0);
+    framework_environment.host.sftp_base_port = get_int_from_string_with_default(getenv(ENV_VAR_HOST_TRANSFER_SFTP_BASE_PORT), 0);
+    
+    framework_environment.sdn_controller.protocol = getenv(ENV_VAR_SDN_CONTROLLER_IP) ? strdup(getenv(ENV_VAR_SDN_CONTROLLER_PROTOCOL)) : strdup("https");
+    framework_environment.sdn_controller.ip = getenv(ENV_VAR_SDN_CONTROLLER_IP) ? strdup(getenv(ENV_VAR_SDN_CONTROLLER_IP)) : strdup("127.0.0.1");
+    framework_environment.sdn_controller.port = get_int_from_string_with_default(getenv(ENV_VAR_SDN_CONTROLLER_PORT), 8181);
+    framework_environment.sdn_controller.callhome_port = get_int_from_string_with_default(getenv(ENV_VAR_SDN_CONTROLLER_CALLHOME_PORT), 6666);
+    framework_environment.sdn_controller.username = getenv(ENV_VAR_SDN_CONTROLLER_USERNAME) ? strdup(getenv(ENV_VAR_SDN_CONTROLLER_USERNAME)) : strdup("admin");
+    framework_environment.sdn_controller.password = getenv(ENV_VAR_SDN_CONTROLLER_PASSWORD) ? strdup(getenv(ENV_VAR_SDN_CONTROLLER_PASSWORD)) : strdup("admin");
+
+    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");
+    framework_environment.ves_endpoint.protocol = getenv(ENV_VAR_VES_ENDPOINT_PROTOCOL) ? strdup(getenv(ENV_VAR_VES_ENDPOINT_PROTOCOL)) : strdup("https");
+    framework_environment.ves_endpoint.ip = getenv(ENV_VAR_VES_ENDPOINT_IP) ? strdup(getenv(ENV_VAR_VES_ENDPOINT_IP)) : strdup("127.0.0.1");
+    framework_environment.ves_endpoint.port = get_int_from_string_with_default(getenv(ENV_VAR_VES_ENDPOINT_PORT), 1234);
+    framework_environment.ves_endpoint.auth_method = getenv(ENV_VAR_VES_ENDPOINT_AUTH_METHOD) ? strdup(getenv(ENV_VAR_VES_ENDPOINT_AUTH_METHOD)) : strdup("no-auth");
+    framework_environment.ves_endpoint.username = getenv(ENV_VAR_VES_ENDPOINT_USERNAME) ? strdup(getenv(ENV_VAR_VES_ENDPOINT_USERNAME)) : strdup("admin");
+    framework_environment.ves_endpoint.password = getenv(ENV_VAR_VES_ENDPOINT_PASSWORD) ? strdup(getenv(ENV_VAR_VES_ENDPOINT_PASSWORD)) : strdup("admin");
+    framework_environment.ves_endpoint.certificate = getenv(ENV_VAR_VES_ENDPOINT_CERTIFICATE) ? strdup(getenv(ENV_VAR_VES_ENDPOINT_CERTIFICATE)) : strdup("");
+
+    log_add_verbose(2, "[framework-env] nts.manual = %d\n", framework_environment.nts.manual);
+    log_add_verbose(2, "[framework-env] nts.version = %s\n", framework_environment.nts.version);
+    log_add_verbose(2, "[framework-env] nts.build_time = %s\n", framework_environment.nts.build_time);
+    log_add_verbose(2, "[framework-env] nts.function_type = %s\n", framework_environment.nts.function_type);
+    log_add_verbose(2, "[framework-env] nts.nf_standalone_start_features = %s\n", framework_environment.nts.nf_standalone_start_features);
+
+    log_add_verbose(2, "[framework-env] settings.docker_engine_version = %s\n", framework_environment.settings.docker_engine_version);
+    log_add_verbose(2, "[framework-env] settings.hostname = %s\n", framework_environment.settings.hostname);
+    log_add_verbose(2, "[framework-env] settings.ip_v4 = %s\n", framework_environment.settings.ip_v4);
+    log_add_verbose(2, "[framework-env] settings.ip_v6 = %s\n", framework_environment.settings.ip_v6);
+    log_add_verbose(2, "[framework-env] settings.ip_v6_enabled = %s\n", framework_environment.settings.ip_v6_enabled ? "true" : "false");
+    log_add_verbose(2, "[framework-env] settings.ssh_connections = %d\n", framework_environment.settings.ssh_connections);
+    log_add_verbose(2, "[framework-env] settings.tls_connections = %d\n", framework_environment.settings.tls_connections);
+    log_add_verbose(2, "[framework-env] settings.ftp_connections = %d\n", framework_environment.settings.ftp_connections);
+    log_add_verbose(2, "[framework-env] settings.sftp_connections = %d\n", framework_environment.settings.sftp_connections);
+
+    //check ports
+    if(framework_environment.host.base_port < 1000) {
+        log_add_verbose(2, "[framework-env] host.base_port < 1000 -> disabling\n");
+        framework_environment.host.base_port = 0;
+    }
+
+    if(framework_environment.host.ssh_base_port < 1000) {
+        log_add_verbose(2, "[framework-env] host.ssh_base_port < 1000 -> using base_port\n");
+        framework_environment.host.ssh_base_port = framework_environment.host.base_port;
+    }
+
+    if(framework_environment.host.tls_base_port < 1000) {
+        log_add_verbose(2, "[framework-env] host.tls_base_port < 1000 -> using base_port\n");
+        framework_environment.host.tls_base_port = framework_environment.host.base_port;
+    }
+
+    if(framework_environment.host.ftp_base_port < 1000) {
+        log_add_verbose(2, "[framework-env] host.ftp_base_port < 1000 -> using base_port\n");
+        framework_environment.host.ftp_base_port = framework_environment.host.base_port;
+    }
+
+    if(framework_environment.host.sftp_base_port < 1000) {
+        log_add_verbose(2, "[framework-env] host.sftp_base_port < 1000 -> using base_port\n");
+        framework_environment.host.sftp_base_port = framework_environment.host.base_port;
+    }
+
+    if(framework_environment.host.base_port == 0) {
+        if(framework_environment.host.ssh_base_port == 0) {
+            log_error("[framework-env] host.ssh_base_port unknown\n");
+            return NTS_ERR_FAILED;
+        }
+
+        if(framework_environment.host.tls_base_port == 0) {
+            log_error("[framework-env] host.tls_base_port unknown\n");
+            return NTS_ERR_FAILED;
+        }
+
+        if(framework_environment.host.ftp_base_port == 0) {
+            log_error("[framework-env] host.ftp_base_port unknown\n");
+            return NTS_ERR_FAILED;
+        }
+
+        if(framework_environment.host.sftp_base_port == 0) {
+            log_error("[framework-env] host.sftp_base_port unknown\n");
+            return NTS_ERR_FAILED;
+        }
+    }
+    
+    log_add_verbose(2, "[framework-env] host.ip = %s\n", framework_environment.host.ip);
+    log_add_verbose(2, "[framework-env] host.base_port = %d\n", framework_environment.host.base_port);
+    log_add_verbose(2, "[framework-env] host.ssh_base_port = %d\n", framework_environment.host.ssh_base_port);
+    log_add_verbose(2, "[framework-env] host.tls_base_port = %d\n", framework_environment.host.tls_base_port);
+    log_add_verbose(2, "[framework-env] host.ftp_base_port = %d\n", framework_environment.host.ftp_base_port);
+    log_add_verbose(2, "[framework-env] host.sftp_base_port = %d\n", framework_environment.host.sftp_base_port);
+    
+    log_add_verbose(2, "[framework-env] sdn_controller.protocol = %s\n", framework_environment.sdn_controller.protocol);
+    log_add_verbose(2, "[framework-env] sdn_controller.ip = %s\n", framework_environment.sdn_controller.ip);
+    log_add_verbose(2, "[framework-env] sdn_controller.port = %d\n", framework_environment.sdn_controller.port);
+    log_add_verbose(2, "[framework-env] sdn_controller.callhome_port = %d\n", framework_environment.sdn_controller.callhome_port);
+    log_add_verbose(2, "[framework-env] sdn_controller.username = %s\n", framework_environment.sdn_controller.username);
+    log_add_verbose(2, "[framework-env] sdn_controller.password = %s\n", framework_environment.sdn_controller.password);
+
+    log_add_verbose(2, "[framework-env] ves_endpoint.common_header_version = %s\n", framework_environment.ves_endpoint.common_header_version);
+    log_add_verbose(2, "[framework-env] ves_endpoint.protocol = %s\n", framework_environment.ves_endpoint.protocol);
+    log_add_verbose(2, "[framework-env] ves_endpoint.ip = %s\n", framework_environment.ves_endpoint.ip);
+    log_add_verbose(2, "[framework-env] ves_endpoint.port = %d\n", framework_environment.ves_endpoint.port);
+    log_add_verbose(2, "[framework-env] ves_endpoint.auth_method = %s\n", framework_environment.ves_endpoint.auth_method);
+    log_add_verbose(2, "[framework-env] ves_endpoint.username = %s\n", framework_environment.ves_endpoint.username);
+    log_add_verbose(2, "[framework-env] ves_endpoint.password = %s\n", framework_environment.ves_endpoint.password);
+    log_add_verbose(2, "[framework-env] ves_endpoint.certificate = %s\n", framework_environment.ves_endpoint.certificate);
+
+    log_add_verbose(2, "[framework-env] finished\n");
+    return NTS_ERR_OK;
+}
+
+static int framework_config_init(void) {
+    log_add_verbose(2, "[framework-config] started\n");
+
     //init app config
-    framework_config.docker_excluded_modules = 0;
-    framework_config.docker_excluded_modules_count = 0;
-    framework_config.docker_excluded_features = 0;
-    framework_config.docker_excluded_features_count = 0;
-    framework_config.debug_max_string_size = 0;
-    framework_config.populate_excluded_modules = 0;
-    framework_config.populate_excluded_modules_count = 0;
-    framework_config.default_list_instances = 1;
-    framework_config.custom_list_instances_count = 0;
-    framework_config.custom_list_instances = 0;
-    framework_config.restrict_schema_count = 0;
-    framework_config.restrict_schema = 0;
-
-    log_message(2, "starting parsing config.json\n");
+    framework_config.docker.excluded_modules = 0;
+    framework_config.docker.excluded_modules_count = 0;
+    framework_config.docker.excluded_features = 0;
+    framework_config.docker.excluded_features_count = 0;
+
+    framework_config.supervisor.rules_count = 0;
+    framework_config.supervisor.rules = 0;
+
+    framework_config.datastore_generate.debug_max_string_size = 0;
+    framework_config.datastore_generate.excluded_modules = 0;
+    framework_config.datastore_generate.excluded_modules_count = 0;
+    framework_config.datastore_generate.default_list_instances = 1;
+    framework_config.datastore_generate.custom_list_instances_count = 0;
+    framework_config.datastore_generate.custom_list_instances = 0;
+    framework_config.datastore_generate.restrict_schema_count = 0;
+    framework_config.datastore_generate.restrict_schema = 0;
+
+    framework_config.datastore_populate.random_generation_enabled = 1;
+    framework_config.datastore_populate.preg_operational_count = 0;
+    framework_config.datastore_populate.preg_operational = 0;
+    framework_config.datastore_populate.preg_running_count = 0;
+    framework_config.datastore_populate.preg_running = 0;
+
+    //config init
+    if(!dir_exists("config")) {
+        log_add_verbose(2, "[framework-config] config/ folder wasn't found; created.\n");
+        mkdir("config", 0777);
+    }
+
+    if(!file_exists("config/config.json")) {
+        log_add_verbose(2, "[framework-config] config.json file missing; created.\n");
+        file_touch("config/config.json", "{}");
+    }    
+
+    log_add_verbose(2, "[framework-config] parsing config.json\n");
     char *config_contents = file_read_content("config/config.json");
     cJSON *json = cJSON_Parse(config_contents);
     free(config_contents);
     if(!json) {
-        log_error("config.json :%s", cJSON_GetErrorPtr());
+        log_error("[framework-config] config.json error: %s\n", cJSON_GetErrorPtr());
     }
     else {
         cJSON *main_node;
         cJSON *node;
 
-        main_node = cJSON_GetObjectItem(json, "docker-rules");
-        if(main_node) {
-            node = cJSON_GetObjectItem(main_node, "excluded-modules");
-            if(node) {
-                if(cJSON_IsArray(node)) {
-                    cJSON *element;
-                    cJSON_ArrayForEach(element, node) {
-                        if(cJSON_IsString(element)) {
-                            log_message(2, "adding docker-rules/exclude-modules: %s\n", element->valuestring);
-                            framework_config.docker_excluded_modules = (char **)realloc(framework_config.docker_excluded_modules, sizeof(char*) * (framework_config.docker_excluded_modules_count + 1));
-                            if(!framework_config.docker_excluded_modules) {
-                                log_error("bad realloc");
-                            }
-                            framework_config.docker_excluded_modules[framework_config.docker_excluded_modules_count] = (char *)malloc(sizeof(char) * (strlen(element->valuestring) + 1));
-                            if(!framework_config.docker_excluded_modules[framework_config.docker_excluded_modules_count]) {
-                                log_error("bad malloc");
+        if(framework_arguments.nts_mode == NTS_MODE_CONTAINER_INIT) {
+            main_node = cJSON_GetObjectItem(json, "container-rules");
+            if(main_node) {
+                node = cJSON_GetObjectItem(main_node, "excluded-modules");
+                if(node) {
+                    if(cJSON_IsArray(node)) {
+                        cJSON *element;
+                        cJSON_ArrayForEach(element, node) {
+                            if(cJSON_IsString(element)) {
+                                log_add_verbose(2, "[framework-config] adding container-rules/exclude-modules: %s\n", element->valuestring);
+                                framework_config.docker.excluded_modules = (char **)realloc(framework_config.docker.excluded_modules, sizeof(char*) * (framework_config.docker.excluded_modules_count + 1));
+                                if(!framework_config.docker.excluded_modules) {
+                                    log_error("[framework-config] bad realloc\n");
+                                }
+                                framework_config.docker.excluded_modules[framework_config.docker.excluded_modules_count] = (char *)malloc(sizeof(char) * (strlen(element->valuestring) + 1));
+                                if(!framework_config.docker.excluded_modules[framework_config.docker.excluded_modules_count]) {
+                                    log_error("[framework-config] bad malloc\n");
+                                }
+                                strcpy(framework_config.docker.excluded_modules[framework_config.docker.excluded_modules_count], element->valuestring);
+                                framework_config.docker.excluded_modules_count++;
                             }
-                            strcpy(framework_config.docker_excluded_modules[framework_config.docker_excluded_modules_count], element->valuestring);
-                            framework_config.docker_excluded_modules_count++;
                         }
                     }
                 }
-            }
 
-            node = cJSON_GetObjectItem(main_node, "excluded-features");
-            if(node) {
-                if(cJSON_IsArray(node)) {
-                    cJSON *element;
-                    cJSON_ArrayForEach(element, node) {
-                        if(cJSON_IsString(element)) {
-                            log_message(2, "adding docker-rules/excluded-features: %s\n", element->valuestring);
-                            framework_config.docker_excluded_features = (char **)realloc(framework_config.docker_excluded_features, sizeof(char*) * (framework_config.docker_excluded_features_count + 1));
-                            if(!framework_config.docker_excluded_features) {
-                                log_error("bad realloc");
-                            }
-                            framework_config.docker_excluded_features[framework_config.docker_excluded_features_count] = (char *)malloc(sizeof(char) * (strlen(element->valuestring) + 1));
-                            if(!framework_config.docker_excluded_features[framework_config.docker_excluded_features_count]) {
-                                log_error("bad malloc");
+                node = cJSON_GetObjectItem(main_node, "excluded-features");
+                if(node) {
+                    if(cJSON_IsArray(node)) {
+                        cJSON *element;
+                        cJSON_ArrayForEach(element, node) {
+                            if(cJSON_IsString(element)) {
+                                log_add_verbose(2, "[framework-config] adding container-rules/excluded-features: %s\n", element->valuestring);
+                                framework_config.docker.excluded_features = (char **)realloc(framework_config.docker.excluded_features, sizeof(char*) * (framework_config.docker.excluded_features_count + 1));
+                                if(!framework_config.docker.excluded_features) {
+                                    log_error("[framework-config] bad realloc\n");
+                                }
+                                framework_config.docker.excluded_features[framework_config.docker.excluded_features_count] = (char *)malloc(sizeof(char) * (strlen(element->valuestring) + 1));
+                                if(!framework_config.docker.excluded_features[framework_config.docker.excluded_features_count]) {
+                                    log_error("[framework-config] bad malloc\n");
+                                }
+                                strcpy(framework_config.docker.excluded_features[framework_config.docker.excluded_features_count], element->valuestring);
+                                framework_config.docker.excluded_features_count++;
                             }
-                            strcpy(framework_config.docker_excluded_features[framework_config.docker_excluded_features_count], element->valuestring);
-                            framework_config.docker_excluded_features_count++;
                         }
                     }
                 }
             }
         }
+        else if(framework_arguments.nts_mode == NTS_MODE_SUPERVISOR) {
+            main_node = cJSON_GetObjectItem(json, "supervisor-rules");
+            if(main_node) {
+                cJSON *app;
+                cJSON_ArrayForEach(app, main_node) {
+                    if(cJSON_IsObject(app)) {
+                        cJSON *object = cJSON_GetObjectItem(app, "path");
+                        if(object) {
+                            framework_config.supervisor.rules = (supervisor_rules_t *)realloc(framework_config.supervisor.rules, sizeof(supervisor_rules_t) * (framework_config.supervisor.rules_count + 1));
+                            if(!framework_config.supervisor.rules) {
+                                log_error("[framework-config] bad realloc\n");
+                            }
+                            
+                            char *path = strdup(object->valuestring);
+                            bool autorestart = false;
+                            bool nomanual = false;
+                            char *stdout_path = 0;
+                            char *stderr_path = 0;
+
+                            int args_count = 0;
+                            char **args = 0;
+                            cJSON *args_json = cJSON_GetObjectItem(app, "args");
+                            if(args_json) {
+                                args_count = cJSON_GetArraySize(args_json);
+                                if(args_count) {
+                                    args = malloc(sizeof(char *) * args_count);
+                                    int i = 0;
+                                    cJSON *arg;
+                                    cJSON_ArrayForEach(arg, args_json) {
+                                        args[i] = strdup(arg->valuestring);
+                                        i++;
+                                    }
+                                }
+                            }
 
-        main_node = cJSON_GetObjectItem(json, "debug-max-string-size");
-        if(main_node) {
-            framework_config.debug_max_string_size = main_node->valueint;
-            log_message(2, "setting debug-max-string-sizes: %d\n", framework_config.debug_max_string_size);
-        }
+                            object = cJSON_GetObjectItem(app, "autorestart");
+                            if(object) {
+                                autorestart = object->valueint;
+                            }
+
+                            object = cJSON_GetObjectItem(app, "nomanual");
+                            if(object) {
+                                nomanual = object->valueint;
+                            }
 
-        main_node = cJSON_GetObjectItem(json, "populate-rules");
-        if(main_node) {
-            node = cJSON_GetObjectItem(main_node, "excluded-modules");
-            if(node) {
-                if(cJSON_IsArray(node)) {
-                    cJSON *element;
-                    cJSON_ArrayForEach(element, node) {
-                        if(cJSON_IsString(element)) {
-                            log_message(2, "adding populate-rules/excluded-modules: %s\n", element->valuestring);
-                            framework_config.populate_excluded_modules = (char **)realloc(framework_config.populate_excluded_modules, sizeof(char*) * (framework_config.populate_excluded_modules_count + 1));
-                            if(!framework_config.populate_excluded_modules) {
-                                log_error("bad realloc");
+                            object = cJSON_GetObjectItem(app, "stdout");
+                            if(object) {
+                                stdout_path = strdup(object->valuestring);
                             }
-                            framework_config.populate_excluded_modules[framework_config.populate_excluded_modules_count] = (char *)malloc(sizeof(char) * (strlen(element->valuestring) + 1));
-                            if(!framework_config.populate_excluded_modules[framework_config.populate_excluded_modules_count]) {
-                                log_error("bad malloc");
+
+                            object = cJSON_GetObjectItem(app, "stderr");
+                            if(object) {
+                                stderr_path = strdup(object->valuestring);
                             }
-                            strcpy(framework_config.populate_excluded_modules[framework_config.populate_excluded_modules_count], element->valuestring);
-                            framework_config.populate_excluded_modules_count++;
+
+                            framework_config.supervisor.rules[framework_config.supervisor.rules_count].name = strdup(app->string);
+                            framework_config.supervisor.rules[framework_config.supervisor.rules_count].path = path;
+                            framework_config.supervisor.rules[framework_config.supervisor.rules_count].args = args;
+                            framework_config.supervisor.rules[framework_config.supervisor.rules_count].args_count = args_count;
+                            framework_config.supervisor.rules[framework_config.supervisor.rules_count].autorestart = autorestart;
+                            framework_config.supervisor.rules[framework_config.supervisor.rules_count].nomanual = nomanual;
+                            framework_config.supervisor.rules[framework_config.supervisor.rules_count].stdout_path = stdout_path;
+                            framework_config.supervisor.rules[framework_config.supervisor.rules_count].stderr_path = stderr_path;
+
+                            log_add_verbose(2, "[framework-config] adding supervisor command: %s with autorestart: %d\n", path, autorestart);
+                            framework_config.supervisor.rules_count++;
                         }
                     }
                 }
             }
+        }
+        else {
+            main_node = cJSON_GetObjectItem(json, "datastore-random-generation-rules");
+            if(main_node) {
+                node = cJSON_GetObjectItem(main_node, "excluded-modules");
+                if(node) {
+                    if(cJSON_IsArray(node)) {
+                        cJSON *element;
+                        cJSON_ArrayForEach(element, node) {
+                            if(cJSON_IsString(element)) {
+                                log_add_verbose(2, "[framework-config] adding datastore-random-generation-rules/excluded-modules: %s\n", element->valuestring);
+                                framework_config.datastore_generate.excluded_modules = (char **)realloc(framework_config.datastore_generate.excluded_modules, sizeof(char*) * (framework_config.datastore_generate.excluded_modules_count + 1));
+                                if(!framework_config.datastore_generate.excluded_modules) {
+                                    log_error("[framework-config] bad realloc\n");
+                                }
+                                framework_config.datastore_generate.excluded_modules[framework_config.datastore_generate.excluded_modules_count] = (char *)malloc(sizeof(char) * (strlen(element->valuestring) + 1));
+                                if(!framework_config.datastore_generate.excluded_modules[framework_config.datastore_generate.excluded_modules_count]) {
+                                    log_error("[framework-config] bad malloc\n");
+                                }
+                                strcpy(framework_config.datastore_generate.excluded_modules[framework_config.datastore_generate.excluded_modules_count], element->valuestring);
+                                framework_config.datastore_generate.excluded_modules_count++;
+                            }
+                        }
+                    }
+                }
 
-            node = cJSON_GetObjectItem(main_node, "default-list-instances");
-            if(node) {
-                if(cJSON_IsNumber(node)) {
-                    framework_config.default_list_instances = node->valueint;
-                    log_message(2, "found populate-rules/default-list-instances to be: %d\n", framework_config.default_list_instances);
+                node = cJSON_GetObjectItem(main_node, "debug-max-string-size");
+                if(node) {
+                    framework_config.datastore_generate.debug_max_string_size = node->valueint;
+                    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);
+                }
+
+                node = cJSON_GetObjectItem(main_node, "default-list-instances");
+                if(node) {
+                    if(cJSON_IsNumber(node)) {
+                        framework_config.datastore_generate.default_list_instances = node->valueint;
+                        log_add_verbose(2, "[framework-config] setting datastore-random-generation-rules/default-list-instances: %d\n", framework_config.datastore_generate.default_list_instances);
+                    }
                 }
-            }
 
-            node = cJSON_GetObjectItem(main_node, "custom-list-instances");
-            if(node) {
-                if(cJSON_IsArray(node)) {
-                    cJSON *element;
-                    cJSON_ArrayForEach(element, node) {
-                        if(cJSON_IsObject(element)) {
-                            cJSON *object;
-                            cJSON_ArrayForEach(object, element) {
-                                char *path = object->string;
-                                int count = object->valueint;
-                                log_message(2, "adding populate-rules/custom-list-instances %s - %d\n", path, count);
-                                framework_config.custom_list_instances = (custom_list_instances_t *)realloc(framework_config.custom_list_instances, sizeof(custom_list_instances_t) * (framework_config.custom_list_instances_count + 1));
-                                if(!framework_config.custom_list_instances) {
-                                    log_error("bad realloc");
+                node = cJSON_GetObjectItem(main_node, "custom-list-instances");
+                if(node) {
+                    if(cJSON_IsArray(node)) {
+                        cJSON *element;
+                        cJSON_ArrayForEach(element, node) {
+                            if(cJSON_IsObject(element)) {
+                                cJSON *object;
+                                cJSON_ArrayForEach(object, element) {
+                                    char *path = object->string;
+                                    int count = object->valueint;
+                                    log_add_verbose(2, "[framework-config] adding datastore-random-generation-rules/custom-list-instances %s - %d\n", path, count);
+                                    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));
+                                    if(!framework_config.datastore_generate.custom_list_instances) {
+                                        log_error("[framework-config] bad realloc\n");
+                                    }
+                                    
+                                    framework_config.datastore_generate.custom_list_instances[framework_config.datastore_generate.custom_list_instances_count].path = (char *)malloc(sizeof(char) * (strlen(path) + 1));
+                                    if(!framework_config.datastore_generate.custom_list_instances[framework_config.datastore_generate.custom_list_instances_count].path) {
+                                        log_error("[framework-config] bad malloc\n");
+                                    }
+                                    strcpy(framework_config.datastore_generate.custom_list_instances[framework_config.datastore_generate.custom_list_instances_count].path, path);
+                                    framework_config.datastore_generate.custom_list_instances[framework_config.datastore_generate.custom_list_instances_count].count = count;
+                                    framework_config.datastore_generate.custom_list_instances_count++;
                                 }
-                                
-                                framework_config.custom_list_instances[framework_config.custom_list_instances_count].path = (char *)malloc(sizeof(char) * (strlen(path) + 1));
-                                if(!framework_config.custom_list_instances[framework_config.custom_list_instances_count].path) {
-                                    log_error("bad malloc");
+                            }
+                        }
+                    }
+                }
+
+                node = cJSON_GetObjectItem(main_node, "restrict-schema");
+                if(node) {
+                    if(cJSON_IsArray(node)) {
+                        cJSON *element;
+                        cJSON_ArrayForEach(element, node) {
+                            if(cJSON_IsObject(element)) {
+                                cJSON *object;
+                                cJSON_ArrayForEach(object, element) {
+                                    char *path = object->string;
+
+                                    log_add_verbose(2, "[framework-config] adding datastore-random-generation-rules/restrict-schema: %s with values:", path);
+                                    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));
+                                    if(!framework_config.datastore_generate.restrict_schema) {
+                                        log_error("[framework-config] bad realloc\n");
+                                    }
+                                    
+                                    framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].path = (char *)malloc(sizeof(char) * (strlen(path) + 1));
+                                    if(!framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].path) {
+                                        log_error("[framework-config] bad malloc\n");
+                                    }
+                                    strcpy(framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].path, path);
+
+
+                                    framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].values_count = 0;
+                                    framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].values = 0;
+                                    framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].index = 0;
+                                    cJSON *value;
+                                    cJSON_ArrayForEach(value, object) {
+                                        if(cJSON_IsString(value)) {
+                                            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));
+                                            if(!framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].values) {
+                                                log_error("[framework-config] bad realloc\n");
+                                            }
+                                            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));
+                                            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]) {
+                                                log_error("[framework-config] bad malloc\n");
+                                            }
+                                            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);
+                                            framework_config.datastore_generate.restrict_schema[framework_config.datastore_generate.restrict_schema_count].values_count++;
+
+                                            log_add(2, " %s", value->valuestring);
+                                        }
+                                    }
+                                    log_add(2, "\n");
+
+                                    framework_config.datastore_generate.restrict_schema_count++;
                                 }
-                                strcpy(framework_config.custom_list_instances[framework_config.custom_list_instances_count].path, path);
-                                framework_config.custom_list_instances[framework_config.custom_list_instances_count].count = count;
-                                framework_config.custom_list_instances_count++;
                             }
                         }
                     }
                 }
             }
 
-            node = cJSON_GetObjectItem(main_node, "restrict-schema");
-            if(node) {
-                if(cJSON_IsArray(node)) {
-                    cJSON *element;
-                    cJSON_ArrayForEach(element, node) {
-                        if(cJSON_IsObject(element)) {
-                            cJSON *object;
-                            cJSON_ArrayForEach(object, element) {
-                                char *path = object->string;
-
-                                log_message(2, "adding populate-rules/restrict-schema: %s with values:", path);
-                                framework_config.restrict_schema = (restrict_schema_t *)realloc(framework_config.restrict_schema, sizeof(restrict_schema_t) * (framework_config.restrict_schema_count + 1));
-                                if(!framework_config.restrict_schema) {
-                                    log_error("bad realloc");
+            main_node = cJSON_GetObjectItem(json, "datastore-populate-rules");
+            if(main_node) {
+                node = cJSON_GetObjectItem(main_node, "random-generation-enabled");
+                if(node) {
+                    framework_config.datastore_populate.random_generation_enabled = node->valueint;
+                    log_add_verbose(2, "[framework-config] setting datastore-populate-rules/random-generation-enabled: %d\n", framework_config.datastore_populate.random_generation_enabled);
+                }
+                else {
+                    log_add_verbose(2, "[framework-config] setting datastore-populate-rules/random-generation-enabled: %d [default value]\n", framework_config.datastore_populate.random_generation_enabled);
+                }
+                
+                node = cJSON_GetObjectItem(main_node, "pre-generated-operational-data");
+                if(node) {
+                    if(cJSON_IsArray(node)) {
+                        cJSON *element;
+                        cJSON_ArrayForEach(element, node) {
+                            if(cJSON_IsString(element)) {
+                                log_add_verbose(2, "[framework-config] adding datastore-populate-rules/pre-generated-operational-data: %s\n", element->valuestring);
+                                framework_config.datastore_populate.preg_operational = (char **)realloc(framework_config.datastore_populate.preg_operational, sizeof(char*) * (framework_config.datastore_populate.preg_operational_count + 1));
+                                if(!framework_config.datastore_populate.preg_operational) {
+                                    log_error("[framework-config] bad realloc\n");
                                 }
-                                
-                                framework_config.restrict_schema[framework_config.restrict_schema_count].path = (char *)malloc(sizeof(char) * (strlen(path) + 1));
-                                if(!framework_config.restrict_schema[framework_config.restrict_schema_count].path) {
-                                    log_error("bad malloc");
+                                framework_config.datastore_populate.preg_operational[framework_config.datastore_populate.preg_operational_count] = (char *)malloc(sizeof(char) * (strlen(element->valuestring) + 1));
+                                if(!framework_config.datastore_populate.preg_operational[framework_config.datastore_populate.preg_operational_count]) {
+                                    log_error("[framework-config] bad malloc\n");
                                 }
-                                strcpy(framework_config.restrict_schema[framework_config.restrict_schema_count].path, path);
-
-
-                                framework_config.restrict_schema[framework_config.restrict_schema_count].values_count = 0;
-                                framework_config.restrict_schema[framework_config.restrict_schema_count].values = 0;
-                                framework_config.restrict_schema[framework_config.restrict_schema_count].index = 0;
-                                cJSON *value;
-                                cJSON_ArrayForEach(value, object) {
-                                    if(cJSON_IsString(value)) {
-                                        framework_config.restrict_schema[framework_config.restrict_schema_count].values = (char **)realloc(framework_config.restrict_schema[framework_config.restrict_schema_count].values, sizeof(char*) * (framework_config.restrict_schema[framework_config.restrict_schema_count].values_count + 1));
-                                        if(!framework_config.restrict_schema[framework_config.restrict_schema_count].values) {
-                                            log_error("bad realloc");
-                                        }
-                                        framework_config.restrict_schema[framework_config.restrict_schema_count].values[framework_config.restrict_schema[framework_config.restrict_schema_count].values_count] = (char *)malloc(sizeof(char) * (strlen(value->valuestring) + 1));
-                                        if(!framework_config.restrict_schema[framework_config.restrict_schema_count].values[framework_config.restrict_schema[framework_config.restrict_schema_count].values_count]) {
-                                            log_error("bad malloc");
-                                        }
-                                        strcpy(framework_config.restrict_schema[framework_config.restrict_schema_count].values[framework_config.restrict_schema[framework_config.restrict_schema_count].values_count], value->valuestring);
-                                        framework_config.restrict_schema[framework_config.restrict_schema_count].values_count++;
+                                strcpy(framework_config.datastore_populate.preg_operational[framework_config.datastore_populate.preg_operational_count], element->valuestring);
+                                framework_config.datastore_populate.preg_operational_count++;
+                            }
+                        }
+                    }
+                }
 
-                                        log_message(2, " %s", value->valuestring);
-                                    }
+                node = cJSON_GetObjectItem(main_node, "pre-generated-running-data");
+                if(node) {
+                    if(cJSON_IsArray(node)) {
+                        cJSON *element;
+                        cJSON_ArrayForEach(element, node) {
+                            if(cJSON_IsString(element)) {
+                                log_add_verbose(2, "[framework-config] adding datastore-populate-rules/pre-generated-running-data: %s\n", element->valuestring);
+                                framework_config.datastore_populate.preg_running = (char **)realloc(framework_config.datastore_populate.preg_running, sizeof(char*) * (framework_config.datastore_populate.preg_running_count + 1));
+                                if(!framework_config.datastore_populate.preg_running) {
+                                    log_error("[framework-config] bad realloc\n");
                                 }
-                                log_message(2, "\n");
-
-                                framework_config.restrict_schema_count++;
+                                framework_config.datastore_populate.preg_running[framework_config.datastore_populate.preg_running_count] = (char *)malloc(sizeof(char) * (strlen(element->valuestring) + 1));
+                                if(!framework_config.datastore_populate.preg_running[framework_config.datastore_populate.preg_running_count]) {
+                                    log_error("[framework-config] bad malloc\n");
+                                }
+                                strcpy(framework_config.datastore_populate.preg_running[framework_config.datastore_populate.preg_running_count], element->valuestring);
+                                framework_config.datastore_populate.preg_running_count++;
                             }
                         }
                     }
                 }
+
             }
         }
 
-        cJSON_free(json);
+        cJSON_Delete(json);
         
     }
-    log_message(2, "finished parsing config.json\n");
-
-    //environment vars
-    bool ip_ok = get_local_ips("eth0", &framework_environment.ip_v4, &framework_environment.ip_v6);
-    if(!ip_ok) {
-        log_error("could not get local IP addresses");
-    }
+    log_add_verbose(2, "[framework-config] finished parsing config.json\n");
 
-    char *ipv6_env_var = getenv(ENV_VAR_IPV6ENABLED);
-    if(ipv6_env_var == 0) {
-        log_error("could not get the IPv6 Enabled env variable");
-    }
-    framework_environment.ip_v6_enabled = (strcmp(ipv6_env_var, "true") == 0) ? true : false;
-
-
-    framework_environment.docker_engine_version = getenv(ENV_VAR_DOCKER_ENGINE_VERSION) ? strdup(getenv(ENV_VAR_DOCKER_ENGINE_VERSION)) : strdup("1.40");
-    framework_environment.hostname = getenv(ENV_VAR_HOSTNAME) ? strdup(getenv(ENV_VAR_HOSTNAME)) : strdup("localhost");
-    framework_environment.host_ip = getenv(ENV_VAR_HOST_IP) ? strdup(getenv(ENV_VAR_HOST_IP)) : strdup("127.0.0.1");
-    framework_environment.host_base_port = get_int_from_string_with_default(getenv(ENV_VAR_HOST_BASE_PORT), 1000);
-    framework_environment.ssh_connections = get_int_from_string_with_default(getenv(ENV_VAR_SSH_CONNECTIONS), 1);
-    framework_environment.tls_connections = get_int_from_string_with_default(getenv(ENV_VAR_TLS_CONNECTIONS), 0);
-    framework_environment.ftp_connections = 1;
-    framework_environment.sftp_connections = 1;
-
-    framework_environment.sdn_controller_ip = getenv(ENV_VAR_SDN_CONTROLLER_IP) ? strdup(getenv(ENV_VAR_SDN_CONTROLLER_IP)) : strdup("127.0.0.1");
-    framework_environment.sdn_controller_port = get_int_from_string_with_default(getenv(ENV_VAR_SDN_CONTROLLER_PORT), 8181);
-    framework_environment.sdn_controller_callhome_port = get_int_from_string_with_default(getenv(ENV_VAR_SDN_CONTROLLER_CALLHOME_PORT), 6666);
-    framework_environment.sdn_controller_username = getenv(ENV_VAR_SDN_CONTROLLER_USERNAME) ? strdup(getenv(ENV_VAR_SDN_CONTROLLER_USERNAME)) : strdup("admin");
-    framework_environment.sdn_controller_password = getenv(ENV_VAR_SDN_CONTROLLER_PASSWORD) ? strdup(getenv(ENV_VAR_SDN_CONTROLLER_PASSWORD)) : strdup("admin");
-
-    framework_environment.ves_endpoint_protocol = getenv(ENV_VAR_VES_ENDPOINT_PROTOCOL) ? strdup(getenv(ENV_VAR_VES_ENDPOINT_PROTOCOL)) : strdup("https");
-    framework_environment.ves_endpoint_ip = getenv(ENV_VAR_VES_ENDPOINT_IP) ? strdup(getenv(ENV_VAR_VES_ENDPOINT_IP)) : strdup("127.0.0.1");
-    framework_environment.ves_endpoint_port = get_int_from_string_with_default(getenv(ENV_VAR_VES_ENDPOINT_PORT), 1234);
-    framework_environment.ves_endpoint_auth_method = getenv(ENV_VAR_VES_ENDPOINT_AUTH_METHOD) ? strdup(getenv(ENV_VAR_VES_ENDPOINT_AUTH_METHOD)) : strdup("no-auth");
-    framework_environment.ves_endpoint_username = getenv(ENV_VAR_VES_ENDPOINT_USERNAME) ? strdup(getenv(ENV_VAR_VES_ENDPOINT_USERNAME)) : strdup("admin");
-    framework_environment.ves_endpoint_password = getenv(ENV_VAR_VES_ENDPOINT_PASSWORD) ? strdup(getenv(ENV_VAR_VES_ENDPOINT_PASSWORD)) : strdup("admin");
-    framework_environment.ves_endpoint_certificate = getenv(ENV_VAR_VES_ENDPOINT_CERTIFICATE) ? strdup(getenv(ENV_VAR_VES_ENDPOINT_CERTIFICATE)) : strdup("");
-
-    log_message(2, "[env] ip_v6_enabled = %s\n", framework_environment.ip_v6_enabled ? "true" : "false");
-    log_message(2, "[env] ip_v4 = %s\n", framework_environment.ip_v4);
-    log_message(2, "[env] ip_v6 = %s\n", framework_environment.ip_v6);
-    log_message(2, "[env] docker_engine_version = %s\n", framework_environment.docker_engine_version);
-    log_message(2, "[env] hostname = %s\n", framework_environment.hostname);
-    log_message(2, "[env] host_ip = %s\n", framework_environment.host_ip);
-    log_message(2, "[env] host_base_port = %d\n", framework_environment.host_base_port);
-    log_message(2, "[env] ssh_connections = %d\n", framework_environment.ssh_connections);
-    log_message(2, "[env] tls_connections = %d\n", framework_environment.tls_connections);
-    log_message(2, "[env] ftp_connections = %d\n", framework_environment.ftp_connections);
-    log_message(2, "[env] sftp_connections = %d\n", framework_environment.sftp_connections);
-
-    log_message(2, "[env] sdn_controller_ip = %s\n", framework_environment.sdn_controller_ip);
-    log_message(2, "[env] sdn_controller_port = %d\n", framework_environment.sdn_controller_port);
-    log_message(2, "[env] sdn_controller_callhome_port = %d\n", framework_environment.sdn_controller_callhome_port);
-    log_message(2, "[env] sdn_controller_username = %s\n", framework_environment.sdn_controller_username);
-    log_message(2, "[env] sdn_controller_password = %s\n", framework_environment.sdn_controller_password);
-
-    log_message(2, "[env] ves_endpoint_protocol = %s\n", framework_environment.ves_endpoint_protocol);
-    log_message(2, "[env] ves_endpoint_ip = %s\n", framework_environment.ves_endpoint_ip);
-    log_message(2, "[env] ves_endpoint_port = %d\n", framework_environment.ves_endpoint_port);
-    log_message(2, "[env] ves_endpoint_auth_method = %s\n", framework_environment.ves_endpoint_auth_method);
-    log_message(2, "[env] ves_endpoint_username = %s\n", framework_environment.ves_endpoint_username);
-    log_message(2, "[env] ves_endpoint_password = %s\n", framework_environment.ves_endpoint_password);
-    log_message(2, "[env] ves_endpoint_certificate = %s\n", framework_environment.ves_endpoint_certificate);
-
-    log_message(2, "finished environment vars\n");
+    return NTS_ERR_OK;
 }
 
 void framework_free(void) {
-    log_message(2, "framework_free()... ");
-
-    free(framework_environment.ip_v4);
-    free(framework_environment.ip_v6);
-    free(framework_environment.docker_engine_version);
-    free(framework_environment.hostname);
-    free(framework_environment.host_ip);
-    free(framework_environment.sdn_controller_ip);
-    free(framework_environment.sdn_controller_username);
-    free(framework_environment.sdn_controller_password);
-    free(framework_environment.ves_endpoint_protocol);
-    free(framework_environment.ves_endpoint_ip);
-    free(framework_environment.ves_endpoint_auth_method);
-    free(framework_environment.ves_endpoint_username);
-    free(framework_environment.ves_endpoint_password);
-    free(framework_environment.ves_endpoint_certificate);
-
-    if(framework_arguments.print_structure_xpath) {
-        free(framework_arguments.print_structure_xpath);
-        framework_arguments.print_structure_xpath = 0;
-    }
-
-    if(framework_config.docker_excluded_modules_count) {
-        for(int i = 0; i < framework_config.docker_excluded_modules_count; i++) {
-            free(framework_config.docker_excluded_modules[i]);
-        }
-        free(framework_config.docker_excluded_modules);
-    }
+    log_add_verbose(2, "[framework-config] framework_free()... ");
+
+    signal(SIGINT, 0);
+    signal(SIGTERM, 0);
+    signal(SIGQUIT, 0);
+
+    free((char *)argp_program_version);
+    argp_program_version = 0;
+
+    free(framework_environment.nts.version);
+    free(framework_environment.nts.build_time);
+    free(framework_environment.nts.function_type);
+    free(framework_environment.nts.nf_standalone_start_features);
+    free(framework_environment.settings.ip_v4);
+    free(framework_environment.settings.ip_v6);
+    free(framework_environment.settings.docker_engine_version);
+    free(framework_environment.settings.hostname);
+    free(framework_environment.host.ip);
+    free(framework_environment.sdn_controller.protocol);
+    free(framework_environment.sdn_controller.ip);
+    free(framework_environment.sdn_controller.username);
+    free(framework_environment.sdn_controller.password);
+    free(framework_environment.ves_endpoint.common_header_version);
+    free(framework_environment.ves_endpoint.protocol);
+    free(framework_environment.ves_endpoint.ip);
+    free(framework_environment.ves_endpoint.auth_method);
+    free(framework_environment.ves_endpoint.username);
+    free(framework_environment.ves_endpoint.password);
+    free(framework_environment.ves_endpoint.certificate);
+
+    free(framework_arguments.print_structure_xpath);
+    framework_arguments.print_structure_xpath = 0;
 
-    if(framework_config.docker_excluded_features_count) {
-        for(int i = 0; i < framework_config.docker_excluded_features_count; i++) {
-            free(framework_config.docker_excluded_features[i]);
+    for(int i = 0; i < framework_config.supervisor.rules_count; i++) {
+        free(framework_config.supervisor.rules[i].name);
+        free(framework_config.supervisor.rules[i].path);
+        for(int j = 0; j < framework_config.supervisor.rules[i].args_count; j++) {
+            free(framework_config.supervisor.rules[i].args[j]);
         }
-        free(framework_config.docker_excluded_features);
+        free(framework_config.supervisor.rules[i].args);
+        free(framework_config.supervisor.rules[i].stdout_path);
+        free(framework_config.supervisor.rules[i].stderr_path);
     }
 
-    if(framework_config.populate_excluded_modules_count) {
-        for(int i = 0; i < framework_config.populate_excluded_modules_count; i++) {
-            free(framework_config.populate_excluded_modules[i]);
-        }
-        free(framework_config.populate_excluded_modules);
-    }
+    free(framework_config.supervisor.rules);
 
-    for(int i = 0; i < framework_config.custom_list_instances_count; i++) {
-        free(framework_config.custom_list_instances[i].path);
-        
+    for(int i = 0; i < framework_config.docker.excluded_modules_count; i++) {
+        free(framework_config.docker.excluded_modules[i]);
     }
-    free(framework_config.custom_list_instances);
+    free(framework_config.docker.excluded_modules);
 
-    for(int i = 0; i < framework_config.restrict_schema_count; i++) {
-        free(framework_config.restrict_schema[i].path);
-        for(int j = 0; j < framework_config.restrict_schema[i].values_count; j++) {
-            free(framework_config.restrict_schema[i].values[j]);
-        }
-        free(framework_config.restrict_schema[i].values);
+    for(int i = 0; i < framework_config.docker.excluded_features_count; i++) {
+        free(framework_config.docker.excluded_features[i]);
     }
-    free(framework_config.restrict_schema);
-
-    log_message(2, "done\n");
-    log_close();
-    if(framework_arguments.container_init) {
-        rename("log/log.txt", "log/install_log.txt");
+    free(framework_config.docker.excluded_features);
+    
+    for(int i = 0; i < framework_config.datastore_generate.excluded_modules_count; i++) {
+        free(framework_config.datastore_generate.excluded_modules[i]);
     }
-}
+    free(framework_config.datastore_generate.excluded_modules);
 
-bool framework_is_docker_excluded_module(const char *module) {
-    assert(module);
 
-    for(int i = 0; i < framework_config.docker_excluded_modules_count; i++) {
-        if(strstr(module, framework_config.docker_excluded_modules[i]) != 0) {
-            return true;
-        }
+    for(int i = 0; i < framework_config.datastore_generate.custom_list_instances_count; i++) {
+        free(framework_config.datastore_generate.custom_list_instances[i].path);
+        
     }
-    
-    return false;
-}
+    free(framework_config.datastore_generate.custom_list_instances);
 
-bool framework_is_docker_excluded_feature(const char *feature) {
-    assert(feature);
-
-    for(int i = 0; i < framework_config.docker_excluded_features_count; i++) {
-        if(strstr(feature, framework_config.docker_excluded_features[i]) != 0) {
-            return true;
+    for(int i = 0; i < framework_config.datastore_generate.restrict_schema_count; i++) {
+        free(framework_config.datastore_generate.restrict_schema[i].path);
+        for(int j = 0; j < framework_config.datastore_generate.restrict_schema[i].values_count; j++) {
+            free(framework_config.datastore_generate.restrict_schema[i].values[j]);
         }
+        free(framework_config.datastore_generate.restrict_schema[i].values);
     }
-    
-    return false;
-}
+    free(framework_config.datastore_generate.restrict_schema);
 
-bool framework_is_populate_excluded_module(const char *module) {
-    assert(module);
-
-    for(int i = 0; i < framework_config.populate_excluded_modules_count; i++) {
-        if(strstr(module, framework_config.populate_excluded_modules[i]) != 0) {
-            return true;
-        }
+    for(int i = 0; i < framework_config.datastore_populate.preg_operational_count; i++) {
+        free(framework_config.datastore_populate.preg_operational[i]);
     }
-    
-    return false;
-}
+    free(framework_config.datastore_populate.preg_operational);
 
-int framework_populate_get_instance_count(const char *path) {
-    assert(path);
-
-    for(int i = 0; i < framework_config.custom_list_instances_count; i++) {
-        if(strcmp(path, framework_config.custom_list_instances[i].path) == 0) {
-            return framework_config.custom_list_instances[i].count;
-        }
+    for(int i = 0; i < framework_config.datastore_populate.preg_running_count; i++) {
+        free(framework_config.datastore_populate.preg_running[i]);
     }
-    return framework_config.default_list_instances;
-}
+    free(framework_config.datastore_populate.preg_running);
 
-char *framework_populate_get_restrict_schema(const char *path) {
-    assert(path);
-    char *ret = 0;
 
-    for(int i = 0; i < framework_config.restrict_schema_count; i++) {
-        if(strcmp(path, framework_config.restrict_schema[i].path) == 0) {
-            ret = strdup(framework_config.restrict_schema[i].values[framework_config.restrict_schema[i].index]);
-            framework_config.restrict_schema[i].index++;
-            if(framework_config.restrict_schema[i].index >= framework_config.restrict_schema[i].values_count) {
-                framework_config.restrict_schema[i].index = 0;
-            }
-            break;
-        }
-    }
-
-    return ret;
+    log_add(2, "done\n");
+    log_close();
 }
 
 static void framework_signal_handler(int signo) {
@@ -556,24 +769,27 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) {
     framework_arguments_t *iter_arguments = state->input;
     switch (key) {
         case 'i':
-            iter_arguments->container_init = true;
+            iter_arguments->nts_mode = NTS_MODE_CONTAINER_INIT;
             break;
 
-        case 'n':
-            iter_arguments->nc_server_init = true;
+        case 's':
+            iter_arguments->nts_mode = NTS_MODE_SUPERVISOR;
             break;
 
         case 'm':
-            iter_arguments->manager = true;
+            iter_arguments->nts_mode = NTS_MODE_MANAGER;
             break;
 
         case 'f':
-            iter_arguments->network_function = true;
+            iter_arguments->nts_mode = NTS_MODE_NETWORK_FUNCTION;
             break;
 
+        case 'g':
+            iter_arguments->nts_mode = NTS_MODE_GENERATE_DATA;
+            break;
 
-        case 'l':
-            iter_arguments->loop = true;
+        case 't':
+            iter_arguments->nts_mode = NTS_MODE_TEST;
             break;
 
         case 'r':
@@ -587,14 +803,6 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) {
             }
             break;
 
-        case 'o':
-            iter_arguments->operational_only = true;
-            break;
-
-        case 't':
-            iter_arguments->test_mode = true;
-            break;
-
         case 'v':
             iter_arguments->verbosity_level = arg[0] - '0';
             break;
@@ -603,10 +811,6 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) {
             chdir(arg);
             break;
 
-        case '0':
-            iter_arguments->exhaustive_test = true;
-            break;
-
         case '1':
             iter_arguments->print_root_paths = true;
             break;
@@ -614,7 +818,7 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) {
         case '2':
             iter_arguments->print_structure_xpath = (char *)malloc(sizeof(char) * (strlen(arg) + 1));
             if(!iter_arguments->print_structure_xpath) {
-                log_error("very bad malloc failure here");
+                log_error("[framework-arg] bad malloc\n");
                 return 1;
             }
             strcpy(iter_arguments->print_structure_xpath, arg);
@@ -623,14 +827,6 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) {
             }
             break;
 
-        case '3':
-            iter_arguments->populate_all = true;
-            break;
-
-        case '4':
-            iter_arguments->enable_features = true;
-            break;
-
         case ARGP_KEY_ARG:
             if (state->arg_num >= 2) {
                 argp_usage(state);