diff --git a/.gitignore b/.gitignore index c2818cc..0ac6c2a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ cmake-build-debug .env scratch .idea -cgi-bin \ No newline at end of file +cgi-bin +generated \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 8526a86..9d337bf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ set(CMAKE_CXX_STANDARD 14) include_directories(src) find_path(JSON_C_INCLUDE_DIR json-c/json.h) -find_path(UCI_INCLUDE_DIR uci.h) +find_path(UCI_INCLUDE_DIR uci/uci.h) include_directories(${JSON_C_INCLUDE_DIR}) include_directories(${UCI_INCLUDE_DIR}) diff --git a/src/cgi.c b/src/cgi.c index ede3971..f1d8823 100644 --- a/src/cgi.c +++ b/src/cgi.c @@ -5,6 +5,8 @@ #include "cgi.h" #include "restconf.h" +#define MAX_BUFFER_SIZE 1024 + /** * Create the cgi_context from environment variables * @return cgi_context @@ -54,19 +56,46 @@ char *get_content() { char *post_data; char *length_str; char *trailing; + char *file_path; unsigned long length; length_str = getenv("CONTENT_LENGTH"); - if (!length_str || !*length_str) return NULL; + if (!length_str || !*length_str) { + file_path = getenv("CONTENT_FILE_PATH"); + if (!file_path || !*file_path) { + return NULL; + } + + FILE *fp = fopen(file_path, "rb"); + if (!fp) { + return NULL; + } + + fseek(fp, 0L, SEEK_END); + long size = ftell(fp); + fseek(fp, 0L, SEEK_SET); + + post_data = (char *) malloc(sizeof(char) * size); + if (!post_data) { + fclose(fp); + return NULL; + } + + if (fread(post_data, sizeof(char), size, fp) == size) { + post_data[size] = '\0'; + } + fclose(fp); - length = strtoul(length_str, &trailing, 10); - if (*trailing != '\0' || !length || length > 1024UL * 1024UL) return NULL; + } else { + length = strtoul(length_str, &trailing, 10); + if (*trailing != '\0' || !length || length > 1024UL * 1024UL) return NULL; - post_data = (char *)malloc(length + 1); - if (!post_data) return NULL; + post_data = (char *)malloc(length + 1); + if (!post_data) return NULL; - if (fread(post_data, sizeof(char), length, stdin) == length) { - post_data[length] = '\0'; + if (fread(post_data, sizeof(char), length, stdin) == length) { + post_data[length] = '\0'; + } } return post_data; diff --git a/src/generated/yang.h b/src/generated/yang.h index 3986f7b..f20d8bd 100644 --- a/src/generated/yang.h +++ b/src/generated/yang.h @@ -12,12 +12,32 @@ struct map_str2str{ typedef struct map_str2str map_str2str; static const map_str2str modulemap[] = { - {"restconf-example", "{\"type\": \"module\", \"map\": {\"course\": {\"type\": \"container\", \"map\": {\"name\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"name\", \"leaf-type\": \"string\"}, \"semester\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"semester\", \"leaf-type\": {\"leaf-type\": \"uint8\", \"from\": \"1\", \"to\": \"6\"}}, \"instructors\": {\"type\": \"leaf-list\", \"map\": {}, \"option\": \"instructors\", \"leaf-type\": \"string\"}, \"students\": {\"type\": \"list\", \"map\": {\"firstname\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"firstname\", \"leaf-type\": \"string\"}, \"lastname\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"lastname\", \"leaf-type\": \"string\"}, \"age\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"age\", \"leaf-type\": {\"leaf-type\": \"uint8\", \"from\": \"0\", \"to\": \"120\"}}, \"major\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"major\", \"leaf-type\": {\"leaf-type\": \"string\", \"pattern\": \"^(CS|IMS)$\"}}, \"grade\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"grade\", \"leaf-type\": \"grade\"}}, \"section\": \"student\", \"leaf-as-name\": \"lastname\", \"keys\": [\"firstname\", \"lastname\", \"age\"]}, \"instructor\": {\"type\": \"container\", \"map\": {\"name\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"name\", \"leaf-type\": \"string\"}, \"email\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"email\", \"leaf-type\": \"email\"}}, \"section-name\": \"instructor\", \"section\": \"instructor\"}}, \"section-name\": \"course\", \"section\": \"course\"}}, \"package\": \"restconf-example\"}"} + {"restconf-example", "{\"type\": \"module\", \"map\": {\"course\": {\"type\": \"container\", \"map\": {\"name\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"name\", \"leaf-type\": \"string\"}, \"semester\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"semester\", \"leaf-type\": {\"leaf-type\": \"uint8\", \"from\": \"1\", \"to\": \"6\"}}, \"instructors\": {\"type\": \"leaf-list\", \"map\": {}, \"option\": \"instructors\", \"leaf-type\": \"string\"}, \"students\": {\"type\": \"list\", \"map\": {\"firstname\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"firstname\", \"leaf-type\": \"string\"}, \"lastname\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"lastname\", \"leaf-type\": \"string\"}, \"age\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"age\", \"leaf-type\": {\"leaf-type\": \"uint8\", \"from\": \"0\", \"to\": \"120\"}}, \"major\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"major\", \"leaf-type\": {\"leaf-type\": \"string\", \"pattern\": \"^(CS|IMS)$\"}}, \"grade\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"grade\", \"leaf-type\": \"grade\"}, \"contact-option\": {\"type\": \"list\", \"map\": {\"email\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"email\", \"leaf-type\": \"string\"}, \"example-leaf\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"example-leaf\", \"leaf-type\": \"string\"}}, \"section\": \"contact_option\", \"leaf-as-name\": \"email\", \"keys\": [\"email\"]}, \"option\": {\"type\": \"list\", \"map\": {\"id\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"id\", \"leaf-type\": \"string\"}, \"name\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"name\", \"leaf-type\": \"string\"}, \"more-options\": {\"type\": \"list\", \"map\": {\"id\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"id\", \"leaf-type\": \"string\"}, \"value\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"value\", \"leaf-type\": \"string\"}}, \"section\": \"more_options\", \"leaf-as-name\": \"id\", \"keys\": [\"id\"]}}, \"section\": \"options\", \"leaf-as-name\": \"id\", \"keys\": [\"id\"]}}, \"section\": \"student\", \"leaf-as-name\": \"lastname\", \"keys\": [\"firstname\", \"lastname\", \"age\"]}, \"instructor\": {\"type\": \"container\", \"map\": {\"name\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"name\", \"leaf-type\": \"string\"}, \"email\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"email\", \"leaf-type\": \"email\"}}, \"section-name\": \"instructor\", \"section\": \"instructor\"}}, \"section-name\": \"course\", \"section\": \"course\"}}, \"package\": \"restconf-example\"}"}, + {"lmapd", "{\"type\": \"module\", \"map\": {\"lmap\": {\"type\": \"container\", \"map\": {\"capabilities\": {\"type\": \"container\", \"map\": {\"version\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"version\", \"leaf-type\": \"string\", \"mandatory\": true}, \"tag\": {\"type\": \"leaf-list\", \"map\": {}, \"option\": \"tag\", \"leaf-type\": \"lmap:tag\"}, \"tasks\": {\"type\": \"container\", \"map\": {\"task\": {\"type\": \"list\", \"map\": {\"name\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"name\", \"leaf-type\": \"lmap:identifier\"}, \"version\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"version\", \"leaf-type\": \"string\"}, \"program\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"program\", \"leaf-type\": \"string\"}, \"function\": {\"type\": \"list\", \"map\": {\"uri\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"uri\", \"leaf-type\": \"inet:uri\"}, \"role\": {\"type\": \"leaf-list\", \"map\": {}, \"option\": \"role\", \"leaf-type\": \"string\"}}, \"section\": \"function\", \"leaf-as-name\": \"uri\", \"keys\": [\"uri\"]}}, \"section\": \"task\", \"leaf-as-name\": \"name\", \"keys\": [\"name\"]}}, \"section\": \"tasks\", \"section-name\": \"tasks\"}}, \"section\": \"capabilities\", \"section-name\": \"capabilities\", \"mandatory\": [\"version\"]}, \"agent\": {\"type\": \"container\", \"map\": {\"agent-id\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"agent_id\", \"leaf-type\": \"yang:uuid\"}, \"group-id\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"group_id\", \"leaf-type\": \"string\"}, \"measurement-point\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"measurement_point\", \"leaf-type\": \"string\"}, \"report-agent-id\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"report_agent_id\", \"leaf-type\": \"boolean\"}, \"report-group-id\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"report_group_id\", \"leaf-type\": \"boolean\"}, \"report-measurement-point\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"report_measurement_point\", \"leaf-type\": \"boolean\"}, \"controller-timeout\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"controller_timeout\", \"leaf-type\": \"uint32\"}, \"last-started\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"last_started\", \"leaf-type\": \"yang:date-and-time\", \"mandatory\": true}}, \"section\": \"agent\", \"section-name\": \"agent\", \"mandatory\": [\"last-started\"]}, \"tasks\": {\"type\": \"container\", \"map\": {\"task\": {\"type\": \"list\", \"map\": {\"name\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"name\", \"leaf-type\": \"lmap:identifier\"}, \"program\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"program\", \"leaf-type\": \"string\"}, \"function\": {\"type\": \"list\", \"map\": {\"uri\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"uri\", \"leaf-type\": \"inet:uri\"}, \"role\": {\"type\": \"leaf-list\", \"map\": {}, \"option\": \"role\", \"leaf-type\": \"string\"}}, \"section\": \"function\", \"leaf-as-name\": \"uri\", \"keys\": [\"uri\"]}, \"option\": {\"type\": \"list\", \"map\": {\"id\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"id\", \"leaf-type\": \"lmap:identifier\"}, \"name\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"name\", \"leaf-type\": \"string\"}, \"value\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"value\", \"leaf-type\": \"string\"}}, \"section\": \"task_option\", \"leaf-as-name\": \"id\", \"keys\": [\"id\"]}, \"tag\": {\"type\": \"leaf-list\", \"map\": {}, \"option\": \"tag\", \"leaf-type\": \"lmap:identifier\"}}, \"section\": \"task\", \"leaf-as-name\": \"name\", \"keys\": [\"name\"]}}, \"section\": \"tasks\", \"section-name\": \"tasks\"}, \"schedules\": {\"type\": \"container\", \"map\": {\"schedule\": {\"type\": \"list\", \"map\": {\"name\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"name\", \"leaf-type\": \"lmap:identifier\"}, \"start\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"start\", \"leaf-type\": \"event-ref\", \"mandatory\": true}, \"end\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"end\", \"leaf-type\": \"event-ref\"}, \"duration\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"duration\", \"leaf-type\": \"uint32\"}, \"execution-mode\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"execution_mode\", \"leaf-type\": \"enumeration\"}, \"state\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"state\", \"leaf-type\": \"enumeration\", \"mandatory\": true}, \"storage\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"storage\", \"leaf-type\": \"yang:gauge64\", \"mandatory\": true}, \"invocations\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"invocations\", \"leaf-type\": \"yang:counter32\", \"mandatory\": true}, \"suppressions\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"suppressions\", \"leaf-type\": \"yang:counter32\", \"mandatory\": true}, \"overlaps\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"overlaps\", \"leaf-type\": \"yang:counter32\", \"mandatory\": true}, \"failures\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"failures\", \"leaf-type\": \"yang:counter32\", \"mandatory\": true}, \"last-invocation\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"last_invocation\", \"leaf-type\": \"yang:date-and-time\"}, \"tag\": {\"type\": \"leaf-list\", \"map\": {}, \"option\": \"tag\", \"leaf-type\": \"lmap:tag\"}, \"suppression-tag\": {\"type\": \"leaf-list\", \"map\": {}, \"option\": \"suppression_tag\", \"leaf-type\": \"lmap:tag\"}, \"action\": {\"type\": \"list\", \"map\": {\"name\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"name\", \"leaf-type\": \"lmap:identifier\"}, \"task\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"task\", \"leaf-type\": \"task-ref\", \"mandatory\": true}, \"state\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"state\", \"leaf-type\": \"enumeration\", \"mandatory\": true}, \"storage\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"storage\", \"leaf-type\": \"yang:gauge64\", \"mandatory\": true}, \"invocations\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"invocations\", \"leaf-type\": \"yang:counter32\", \"mandatory\": true}, \"suppressions\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"suppressions\", \"leaf-type\": \"yang:counter32\", \"mandatory\": true}, \"overlaps\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"overlaps\", \"leaf-type\": \"yang:counter32\", \"mandatory\": true}, \"failures\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"failures\", \"leaf-type\": \"yang:counter32\", \"mandatory\": true}, \"last-invocation\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"last_invocation\", \"leaf-type\": \"yang:date-and-time\", \"mandatory\": true}, \"last-completion\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"last_completion\", \"leaf-type\": \"yang:date-and-time\", \"mandatory\": true}, \"last-status\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"last_status\", \"leaf-type\": \"lmap:status-code\", \"mandatory\": true}, \"last-message\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"last_message\", \"leaf-type\": \"string\", \"mandatory\": true}, \"last-failed-completion\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"last_failed_completion\", \"leaf-type\": \"yang:date-and-time\", \"mandatory\": true}, \"last-failed-status\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"last_failed_status\", \"leaf-type\": \"lmap:status-code\", \"mandatory\": true}, \"last-failed-message\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"last_failed_message\", \"leaf-type\": \"string\", \"mandatory\": true}, \"option\": {\"type\": \"list\", \"map\": {\"id\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"id\", \"leaf-type\": \"lmap:identifier\"}, \"name\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"name\", \"leaf-type\": \"string\"}, \"value\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"value\", \"leaf-type\": \"string\"}}, \"section\": \"task_option\", \"leaf-as-name\": \"id\", \"keys\": [\"id\"]}, \"destination\": {\"type\": \"leaf-list\", \"map\": {}, \"option\": \"destination\", \"leaf-type\": \"schedule-ref\"}, \"tag\": {\"type\": \"leaf-list\", \"map\": {}, \"option\": \"tag\", \"leaf-type\": \"lmap:tag\"}, \"suppression-tag\": {\"type\": \"leaf-list\", \"map\": {}, \"option\": \"suppression_tag\", \"leaf-type\": \"lmap:tag\"}}, \"section\": \"action\", \"leaf-as-name\": \"name\", \"keys\": [\"name\"], \"mandatory\": [\"task\", \"state\", \"storage\", \"invocations\", \"suppressions\", \"overlaps\", \"failures\", \"last-invocation\", \"last-completion\", \"last-status\", \"last-message\", \"last-failed-completion\", \"last-failed-status\", \"last-failed-message\"]}}, \"section\": \"schedule\", \"leaf-as-name\": \"name\", \"keys\": [\"name\"], \"mandatory\": [\"start\", \"state\", \"storage\", \"invocations\", \"suppressions\", \"overlaps\", \"failures\"]}}, \"section\": \"schedules\", \"section-name\": \"schedules\"}, \"suppressions\": {\"type\": \"container\", \"map\": {\"suppression\": {\"type\": \"list\", \"map\": {\"name\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"name\", \"leaf-type\": \"lmap:identifier\"}, \"start\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"start\", \"leaf-type\": \"event-ref\"}, \"end\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"end\", \"leaf-type\": \"event-ref\"}, \"stop-running\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"stop_running\", \"leaf-type\": \"boolean\"}, \"state\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"state\", \"leaf-type\": \"enumeration\", \"mandatory\": true}, \"match\": {\"type\": \"leaf-list\", \"map\": {}, \"option\": \"match\", \"leaf-type\": \"lmap:glob-pattern\"}}, \"section\": \"suppression\", \"leaf-as-name\": \"name\", \"keys\": [\"name\"], \"mandatory\": [\"state\"]}}, \"section\": \"suppressions\", \"section-name\": \"suppressions\"}, \"events\": {\"type\": \"container\", \"map\": {\"event\": {\"type\": \"list\", \"map\": {\"name\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"name\", \"leaf-type\": \"lmap:identifier\"}, \"random-spread\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"random_spread\", \"leaf-type\": \"uint32\"}, \"cycle-interval\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"cycle_interval\", \"leaf-type\": \"uint32\"}, \"event-type\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"event_type\", \"leaf-type\": \"uint32\"}, \"interval\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"interval\", \"leaf-type\": {\"leaf-type\": \"uint32\", \"from\": 1, \"to\": 4294967295}, \"mandatory\": true}, \"timezone-offset\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"timezone_offset\", \"leaf-type\": \"lmap:timezone-offset\"}, \"time\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"time\", \"leaf-type\": \"yang:date-and-time\", \"mandatory\": true}, \"immediate\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"immediate\", \"leaf-type\": \"empty\", \"mandatory\": true}, \"startup\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"startup\", \"leaf-type\": \"empty\", \"mandatory\": true}, \"controller-lost\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"controller_lost\", \"leaf-type\": \"empty\", \"mandatory\": true}, \"controller-connected\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"controller_connected\", \"leaf-type\": \"empty\", \"mandatory\": true}, \"month\": {\"type\": \"leaf-list\", \"map\": {}, \"option\": \"month\", \"leaf-type\": \"lmap:month-or-all\"}, \"day-of-month\": {\"type\": \"leaf-list\", \"map\": {}, \"option\": \"day_of_month\", \"leaf-type\": \"lmap:day-of-months-or-all\"}, \"day-of-week\": {\"type\": \"leaf-list\", \"map\": {}, \"option\": \"day_of_week\", \"leaf-type\": \"lmap:weekday-or-all\"}, \"hour\": {\"type\": \"leaf-list\", \"map\": {}, \"option\": \"hour\", \"leaf-type\": \"lmap:hour-or-all\"}, \"minute\": {\"type\": \"leaf-list\", \"map\": {}, \"option\": \"minute\", \"leaf-type\": \"lmap:minute-or-all\"}, \"second\": {\"type\": \"leaf-list\", \"map\": {}, \"option\": \"second\", \"leaf-type\": \"lmap:second-or-all\"}, \"start\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"start\", \"leaf-type\": \"yang:date-and-time\"}, \"end\": {\"type\": \"leaf\", \"map\": {}, \"option\": \"end\", \"leaf-type\": \"yang:date-and-time\"}}, \"section\": \"event\", \"leaf-as-name\": \"name\", \"keys\": [\"name\"], \"mandatory\": [\"interval\", \"time\", \"immediate\", \"startup\", \"controller-lost\", \"controller-connected\"]}}, \"section\": \"events\", \"section-name\": \"events\"}}, \"section\": \"lmap\", \"section-name\": \"lmap\"}}, \"package\": \"lmapd\"}"} }; static const map_str2str yang2regex[] = { {"grade", "{\"leaf-type\": \"uint8\", \"from\": \"0\", \"to\": \"100\"}"}, - {"email", "{\"leaf-type\": \"string\", \"pattern\": \"^[A-Za-z0-9]*@university.de$\"}"} + {"email", "{\"leaf-type\": \"string\", \"pattern\": \"^[A-Za-z0-9]*@university.de$\"}"}, + {"event-ref", "{\"leaf-type\": \"leafref\"}"}, + {"task-ref", "{\"leaf-type\": \"leafref\"}"}, + {"schedule-ref", "{\"leaf-type\": \"leafref\"}"}, + {"lmap:identifier", "{\"leaf-type\": \"string\"}"}, + {"lmap:tag", "{\"leaf-type\": \"string\"}"}, + {"lmap:glob-pattern", "{\"leaf-type\": \"string\"}"}, + {"lmap:month-or-all", "{\"leaf-type\": \"union\"}"}, + {"lmap:day-of-months-or-all", "{\"leaf-type\": \"union\"}"}, + {"lmap:weekday-or-all", "{\"leaf-type\": \"union\"}"}, + {"lmap:hour-or-all", "{\"leaf-type\": \"union\"}"}, + {"lmap:minute-or-all", "{\"leaf-type\": \"union\"}"}, + {"lmap:second-or-all", "{\"leaf-type\": \"union\"}"}, + {"lmap:status-code", "{\"leaf-type\": \"int32\"}"}, + {"lmap:timezone-offset", "{\"leaf-type\": \"string\", \"pattern\": [\"^Z|[\\\\+\\\\-]\\\\d{2}:\\\\d{2}$\"]}"}, + {"inet:uri", "{\"leaf-type\": \"string\"}"}, + {"yang:counter32", "{\"leaf-type\": \"uint32\"}"}, + {"yang:gauge64", "{\"leaf-type\": \"uint64\"}"}, + {"yang:date-and-time", "{\"leaf-type\": \"string\", \"pattern\": [\"^\\\\d{4}-\\\\d{2}-\\\\d{2}T\\\\d{2}:\\\\d{2}:\\\\d{2}(\\\\.\\\\d+)?(Z|[\\\\+\\\\-]\\\\d{2}:\\\\d{2})$\"]}"}, + {"yang:uuid", "{\"leaf-type\": \"string\", \"pattern\": [\"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$\"]}"} }; enum yang_type { @@ -62,7 +82,13 @@ static const map_str2yang_type str2yang_type[] = { {"uint64", UINT_64}, {"binary", BINARY}, {"boolean", BOOLEAN}, - {"decimal64", DECIMAL_64} + {"decimal64", DECIMAL_64}, + {"enumeration", ENUMERATION}, + {"union", UNION}, + {"bits", BITS}, + {"yang:xpath1.0", STRING}, + {"counter32", INT_32}, + {"leafref", LEAF_REF} }; struct json_object* yang_module_exists(char* module); diff --git a/src/restconf-json.c b/src/restconf-json.c index 476cac0..b3df315 100644 --- a/src/restconf-json.c +++ b/src/restconf-json.c @@ -4,6 +4,8 @@ #include "restconf.h" #include "yang-util.h" +#define DEBUG + /** * Return json_object's value as a string * @param jobj input object to be searched @@ -166,13 +168,13 @@ error json_yang_verify_list(struct json_object* list, return KEY_NOT_PRESENT; } } - +#ifndef DEBUG if (mandatory_exist) { if (check_mandatory_values(mandatory, list_item) != RE_OK) { return MANDATORY_NOT_PRESENT; } } - +#endif for (size_t verify_i = list_i + 1; verify_i < json_object_array_length(list) && keys_exist; verify_i++) { int different = 0; diff --git a/src/restconf-method.c b/src/restconf-method.c index 8e207c8..9cd69f4 100644 --- a/src/restconf-method.c +++ b/src/restconf-method.c @@ -19,6 +19,7 @@ static UciWritePair **verify_content_yang(struct json_object *content, int root, int check_exists) { UciWritePair **command_list = NULL; const char *child_type = NULL; + struct UciPath *old_path = NULL; if (!(child_type = json_get_string(yang_node, YANG_TYPE))) { *err = YANG_SCHEMA_ERROR; return NULL; @@ -96,12 +97,19 @@ static UciWritePair **verify_content_yang(struct json_object *content, struct json_object *tmp = json_object_array_get_idx(content, index); path->index = pos; path->where = 1; + old_path = (struct UciPath *) malloc(sizeof(struct UciPath)); + if (!old_path) { + return NULL; + } + memcpy(old_path, path, sizeof(struct UciPath)); UciWritePair **tmp_list = verify_content_yang(tmp, yang_node, path, err, 0, check_exists); if (*err != RE_OK) { free_uci_write_list(tmp_list); return NULL; } + memcpy(path, old_path, sizeof(struct UciPath)); + free(old_path); for (size_t i = 0; i < vector_size(tmp_list); i++) { vector_push_back(command_list, tmp_list[i]); } @@ -705,6 +713,7 @@ int data_put(struct CgiContext *cgi, char **pathvec, int root) { if ((keys = json_get_array(top_level, YANG_KEYS))) { struct json_object *values = NULL; if (json_extract_key_values(keys, root_object, &values) == RE_OK) { + key_out[0] = '\0'; json_object_object_foreach(values, key, value) { strcat(key_out, json_object_get_string(value)); strcat(key_out, ","); diff --git a/src/restconf.c b/src/restconf.c index 0eae42d..44eb694 100644 --- a/src/restconf.c +++ b/src/restconf.c @@ -38,7 +38,7 @@ static int api_root(struct CgiContext *cgi) { static int data_root(struct CgiContext *cgi, char **pathvec) { int retval = 1; - if (pathvec[1] == NULL) { + if (vector_size(pathvec) <= 1) { // root if (is_OPTIONS(cgi->method)) { content_type_json(); diff --git a/src/uci/cmd.c b/src/uci/cmd.c index a3883e1..a854bc8 100644 --- a/src/uci/cmd.c +++ b/src/uci/cmd.c @@ -19,8 +19,7 @@ struct UciWritePair *initialize_uci_write_pair(struct UciPath *path, int free_uci_write_list(UciWritePair **list) { for (size_t i = 0; i < vector_size(list); i++) { - UciWritePair *cmd = list[i]; - free(cmd->value); + free(list[i]); } vector_free(list); return 0; diff --git a/src/uci/methods.c b/src/uci/methods.c index 78fa739..9ce00c8 100644 --- a/src/uci/methods.c +++ b/src/uci/methods.c @@ -1,6 +1,6 @@ #include "methods.h" #include -#include +#include #include "http.h" #include "uci-util.h" #include "util.h" diff --git a/src/uci/methods.h b/src/uci/methods.h index 0dbec8a..215ecd5 100644 --- a/src/uci/methods.h +++ b/src/uci/methods.h @@ -2,7 +2,7 @@ #define _RESTCONF_UCI_H #include -#include +#include #include "generated/yang.h" /** diff --git a/src/yang-verify.c b/src/yang-verify.c index 6ec9d39..bb367d3 100644 --- a/src/yang-verify.c +++ b/src/yang-verify.c @@ -206,7 +206,10 @@ static int yang_verify_value_type(struct json_object* type, const char* value) { yang_type converted = str_to_yang_type(leaf_type); switch (converted) { case BOOLEAN: - if (strcmp(value, "true") != 0 && strcmp(value, "false") != 0) return 1; + if (strcmp(value, "true") != 0 && strcmp(value, "false") != 0 && + strcmp(value, "1") != 0 && strcmp(value, "0") != 0) { + return 1; + } break; case EMPTY: break; diff --git a/test/acceptance/POST/lmapd-valid.json b/test/acceptance/POST/lmapd-valid.json new file mode 100644 index 0000000..6881569 --- /dev/null +++ b/test/acceptance/POST/lmapd-valid.json @@ -0,0 +1,167 @@ +{ + "lmapd:lmap":{ + "schedules":{ + "schedule":[ + { + "name":"demo", + "start":"every-minute", + "execution-mode": "sequential", + "action":[ + { + "name":"mtr0", + "task":"mtr", + "destination":[ + "report-primary" + ], + "option":[ + { + "id":"0", + "value":"www.ietf.org" + } + ] + }, + { + "name":"mtr1", + "task":"mtr", + "destination":[ + "report-primary" + ], + "option":[ + { + "id":"1", + "value":"www.ieee.org" + } + ] + }, + { + "name":"happy0", + "task":"happy", + "destination":[ + "report-primary", + "report-secondary" + ], + "option":[ + { + "id":"2", + "value":"www.ieee.org" + } + ] + }, + { + "name":"happy1", + "task":"happy", + "destination":[ + "report-primary", + "report-secondary" + ], + "option":[ + { + "id":"3", + "value":"www.ieee.org" + } + ] + } + ] + }, + { + "name":"report_primary", + "start":"every-six-hours", + "action":[ + { + "name":"report", + "task":"lmap-reporting-task", + "option":[ + { + "id":"collector_uri", + "value":"https://collector.example.com/restconf/operations/ietf-lmap-report:report" + } + ] + } + ] + }, + { + "name":"report_secondary", + "start":"daily", + "action":[ + { + "name":"report", + "task":"lmap-reporting-task", + "option":[ + { + "id":"collector_uri", + "value":"https://shadow.example.com/restconf/operations/ietf-lmap-report:report" + } + ] + } + ] + } + ] + }, + "agent":{ + "agent-id":"7984713289472", + "group-id":"network-measurement-at-the-north-pole", + "report-agent-id":true, + "report-group-id":false + }, + "tasks":{ + "task":[ + { + "name":"mtr", + "program":"/usr/bin/mtr", + "option":[ + { + "id":"numeric", + "name":"--no-dns" + }, + { + "id":"csv", + "name":"--csv" + }, + { + "id":"lookup_AS_numbers", + "name":"-z" + }, + { + "id":"one_cycle", + "name":"--report-cycles=3" + } + ] + }, + { + "name":"happy", + "program":"/usr/local/bin/happy", + "option":[ + { + "id":"csv", + "name":"-m" + }, + { + "id":"one_query", + "name":"-q", + "value":"1" + } + ] + }, + { + "name":"lmap_reporting_task", + "program":"/usr/bin/lmap-reporter", + "option":[ + { + "id":"collector_uri", + "value":"https://example.com/restconf/operations/ietf-lmap-report:report" + } + ] + } + ] + }, + "events":{ + "event":[ + { + "name":"every_minute", + "event-type": 0, + "interval": 60 + } + ] + } + } +} \ No newline at end of file diff --git a/test/acceptance/POST/root-valid.yaml b/test/acceptance/POST/root-valid.yaml index 7675ff0..b4d4f7d 100644 --- a/test/acceptance/POST/root-valid.yaml +++ b/test/acceptance/POST/root-valid.yaml @@ -16,7 +16,25 @@ "lastname": "student", "age": 21, "major": "CS", - "grade": 75 + "grade": 75, + "contact-option": [ + { + "email": "d_terzikj_jacobs_university_de", + "example-leaf": "example-leaf-example" + } + ], + "option": [ + { + "id": "0", + "name": "example-name", + "more-options": [ + { + "id": "1", + "value": "example-value" + } + ] + } + ] } ] } diff --git a/yang/ietf-lmap-common.yang b/yang/ietf-lmap-common.yang new file mode 100644 index 0000000..f1cb78f --- /dev/null +++ b/yang/ietf-lmap-common.yang @@ -0,0 +1,407 @@ +module ietf-lmap-common { + + yang-version 1.1; + namespace "urn:ietf:params:xml:ns:yang:ietf-lmap-common"; + prefix "lmap"; + + import ietf-inet-types { + prefix inet; + } + + import openwrt-uci-extension { + prefix uci; + } + + organization + "IETF Large-Scale Measurement of Broadband Performance + Working Group"; + + contact + "WG Web: + WG List: + + Editor: Juergen Schoenwaelder + + + Editor: Vaibhav Bajpai + "; + + description + "This module provides common definitions used by the data + models written for Large-Scale Measurement Platforms (LMAPs). + This module defines typedefs and groupings but no schema + tree elements."; + + revision "2017-08-08" { + description + "Initial version"; + reference + "RFC 8194: A YANG Data Model for LMAP Measurement Agents"; + } + + /* + * Typedefs + */ + + typedef identifier { + type string { + length "1..max"; + } + description + "A string value used to name something."; + } + + typedef tag { + type string { + length "1..max"; + } + description + "A tag consists of at least one character."; + } + + typedef glob-pattern { + type string { + length "1..max"; + } + description + 'A glob style pattern (following POSIX.2 fnmatch() without + special treatment of file paths): + + * matches a sequence of characters + ? matches a single character + [seq] matches any character in seq + [!seq] matches any character not in seq + + A backslash followed by a character matches the following + character. In particular: + + \* matches * + \? matches ? + \\ matches \ + + A sequence seq may be a sequence of characters (e.g., [abc] + or a range of characters (e.g., [a-c]).'; + } + + typedef wildcard { + type string { + pattern '\*'; + } + description + "A wildcard for calendar scheduling entries."; + } + + typedef cycle-number { + type string { + pattern '[0-9]{8}\.[0-9]{6}'; + } + description + "A cycle number represented in the format YYYYMMDD.HHMMSS + where YYYY represents the year, MM the month (1..12), DD + the day of the months (01..31), HH the hour (00..23), MM + the minute (00..59), and SS the second (00..59). The cycle + number is using Coordinated Universal Time (UTC)."; + } + + typedef month { + type enumeration { + enum january { + value 1; + description + "January of the Gregorian calendar."; + } + enum february { + value 2; + description + "February of the Gregorian calendar."; + } + enum march { + value 3; + description + "March of the Gregorian calendar."; + } + enum april { + value 4; + description + "April of the Gregorian calendar."; + } + + enum may { + value 5; + description + "May of the Gregorian calendar."; + } + enum june { + value 6; + description + "June of the Gregorian calendar."; + } + enum july { + value 7; + description + "July of the Gregorian calendar."; + } + enum august { + value 8; + description + "August of the Gregorian calendar."; + } + enum september { + value 9; + description + "September of the Gregorian calendar."; + } + enum october { + value 10; + description + "October of the Gregorian calendar."; + } + enum november { + value 11; + description + "November of the Gregorian calendar."; + } + enum december { + value 12; + description + "December of the Gregorian calendar."; + } + } + description + "A type modeling the month in the Gregorian calendar."; + } + + typedef month-or-all { + type union { + type month; + type wildcard; + } + description + "A month or a wildcard indicating all twelve months."; + } + + typedef day-of-month { + type uint8 { range "1..31"; } + description + "A day of a month of the Gregorian calendar."; + } + + typedef day-of-months-or-all { + type union { + type day-of-month; + type wildcard; + } + description + "A day of a month or a wildcard indicating all days + of a month."; + } + + typedef weekday { + type enumeration { + enum monday { + value 1; + description + "Monday of the Gregorian calendar."; + } + enum tuesday { + value 2; + description + "Tuesday of the Gregorian calendar."; + } + enum wednesday { + value 3; + description + "Wednesday of the Gregorian calendar."; + } + enum thursday { + value 4; + description + "Thursday of the Gregorian calendar."; + } + + enum friday { + value 5; + description + "Friday of the Gregorian calendar."; + } + enum saturday { + value 6; + description + "Saturday of the Gregorian calendar."; + } + enum sunday { + value 7; + description + "Sunday of the Gregorian calendar."; + } + } + description + "A type modeling the weekdays in the Gregorian calendar. + The numbering follows the ISO 8601 scheme."; + reference + "ISO 8601:2004: Data elements and interchange formats -- + Information interchange -- Representation + of dates and times"; + } + + typedef weekday-or-all { + type union { + type weekday; + type wildcard; + } + description + "A weekday or a wildcard indicating all seven weekdays."; + } + + typedef hour { + type uint8 { range "0..23"; } + description + "An hour of a day."; + } + + typedef hour-or-all { + type union { + type hour; + type wildcard; + } + description + "An hour of a day or a wildcard indicating all hours + of a day."; + } + + typedef minute { + type uint8 { range "0..59"; } + description + "A minute of an hour."; + } + + typedef minute-or-all { + type union { + type minute; + type wildcard; + } + description + "A minute of an hour or a wildcard indicating all + minutes of an hour."; + } + + typedef second { + type uint8 { range "0..59"; } + description + "A second of a minute."; + } + + typedef second-or-all { + type union { + type second; + type wildcard; + } + description + "A second of a minute or a wildcard indicating all + seconds of a minute."; + } + + typedef status-code { + type int32; + description + "A status code returned by the execution of a Task. Note + that the actual range is implementation dependent, but it + should be portable to use values in the range 0..127 for + regular exit codes. By convention, 0 indicates successful + termination. Negative values may be used to indicate + abnormal termination due to a signal; the absolute value + may identify the signal number in this case."; + } + + typedef timezone-offset { + type string { + pattern 'Z|[\+\-]\d{2}:\d{2}'; + } + description + "A time zone offset as it is used by the date-and-time type + defined in the ietf-yang-types module. The value Z is + equivalent to +00:00. The value -00:00 indicates an + unknown time-offset."; + reference + "RFC 6991: Common YANG Data Types"; + } + + /* + * Groupings + */ + + grouping registry-grouping { + description + "This grouping models a list of entries in a registry + that identify functions of a Task."; + + list function { + uci:section "function"; + uci:leaf-as-name "uri"; + + key uri; + description + "A list of entries in a registry identifying functions."; + + leaf uri { + uci:option "uri"; + type inet:uri; + description + "A URI identifying an entry in a registry."; + } + + leaf-list role { + uci:option "role"; + type string; + description + "A set of roles for the identified registry entry."; + } + } + } + + grouping options-grouping { + description + "A list of options of a Task. Each option is a name/value + pair (where the value may be absent)."; + + list option { + uci:section "option"; + uci:leaf-as-name "id"; + + key "id"; + ordered-by user; + description + "A list of options passed to the Task. It is a list of + key/value pairs and may be used to model options. + Options may be used to identify the role of a Task + or to pass a Channel name to a Task."; + + leaf id { + uci:option "id"; + + type lmap:identifier; + description + "An identifier uniquely identifying an option. This + identifier is required by YANG to uniquely identify + a name/value pair, but it otherwise has no semantic + value"; + } + + leaf name { + uci:option "name"; + + type string; + description + "The name of the option."; + } + + leaf value { + uci:option "value"; + + type string; + description + "The value of the option."; + } + } + } +} diff --git a/yang/ietf-netconf-acm.yang b/yang/ietf-netconf-acm.yang new file mode 100644 index 0000000..7a50d29 --- /dev/null +++ b/yang/ietf-netconf-acm.yang @@ -0,0 +1,496 @@ +module ietf-netconf-acm { + + namespace "urn:ietf:params:xml:ns:yang:ietf-netconf-acm"; + + prefix nacm; + + import ietf-yang-types { + prefix yang; + } + + import openwrt-uci-extension { + prefix uci; + } + + organization + "IETF NETCONF (Network Configuration) Working Group"; + + contact + "WG Web: + WG List: + + Author: Andy Bierman + + + Author: Martin Bjorklund + "; + + description + "Network Configuration Access Control Model. + + Copyright (c) 2012 - 2018 IETF Trust and the persons + identified as authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD + License set forth in Section 4.c of the IETF Trust's + Legal Provisions Relating to IETF Documents + (https://trustee.ietf.org/license-info). + + This version of this YANG module is part of RFC 8341; see + the RFC itself for full legal notices."; + + revision "2018-02-14" { + description + "Added support for YANG 1.1 actions and notifications tied to + data nodes. Clarified how NACM extensions can be used by + other data models."; + reference + "RFC 8341: Network Configuration Access Control Model"; + } + + revision "2012-02-22" { + description + "Initial version."; + reference + "RFC 6536: Network Configuration Protocol (NETCONF) + Access Control Model"; + } + + /* + * Extension statements + */ + + extension default-deny-write { + description + "Used to indicate that the data model node + represents a sensitive security system parameter. + + If present, the NETCONF server will only allow the designated + 'recovery session' to have write access to the node. An + explicit access control rule is required for all other users. + + If the NACM module is used, then it must be enabled (i.e., + /nacm/enable-nacm object equals 'true'), or this extension + is ignored. + + The 'default-deny-write' extension MAY appear within a data + definition statement. It is ignored otherwise."; + } + + extension default-deny-all { + description + "Used to indicate that the data model node + controls a very sensitive security system parameter. + + If present, the NETCONF server will only allow the designated + 'recovery session' to have read, write, or execute access to + the node. An explicit access control rule is required for all + other users. + + If the NACM module is used, then it must be enabled (i.e., + /nacm/enable-nacm object equals 'true'), or this extension + is ignored. + + The 'default-deny-all' extension MAY appear within a data + definition statement, 'rpc' statement, or 'notification' + statement. It is ignored otherwise."; + } + + /* + * Derived types + */ + + typedef user-name-type { + type string { + length "1..max"; + } + description + "General-purpose username string."; + } + + typedef matchall-string-type { + type string { + pattern '\*'; + } + description + "The string containing a single asterisk '*' is used + to conceptually represent all possible values + for the particular leaf using this data type."; + } + + typedef access-operations-type { + type bits { + bit create { + description + "Any protocol operation that creates a + new data node."; + } + bit read { + description + "Any protocol operation or notification that + returns the value of a data node."; + } + bit update { + description + "Any protocol operation that alters an existing + data node."; + } + bit delete { + description + "Any protocol operation that removes a data node."; + } + bit exec { + description + "Execution access to the specified protocol operation."; + } + } + description + "Access operation."; + } + + typedef group-name-type { + type string { + length "1..max"; + pattern '[^\*].*'; + } + description + "Name of administrative group to which + users can be assigned."; + } + + typedef action-type { + type enumeration { + enum permit { + description + "Requested action is permitted."; + } + enum deny { + description + "Requested action is denied."; + } + } + description + "Action taken by the server when a particular + rule matches."; + } + + typedef node-instance-identifier { + type yang:xpath1.0; + description + "Path expression used to represent a special + data node, action, or notification instance-identifier + string. + + A node-instance-identifier value is an + unrestricted YANG instance-identifier expression. + All the same rules as an instance-identifier apply, + except that predicates for keys are optional. If a key + predicate is missing, then the node-instance-identifier + represents all possible server instances for that key. + + This XML Path Language (XPath) expression is evaluated in the + following context: + + o The set of namespace declarations are those in scope on + the leaf element where this type is used. + + o The set of variable bindings contains one variable, + 'USER', which contains the name of the user of the + current session. + + o The function library is the core function library, but + note that due to the syntax restrictions of an + instance-identifier, no functions are allowed. + + o The context node is the root node in the data tree. + + The accessible tree includes actions and notifications tied + to data nodes."; + } + + /* + * Data definition statements + */ + + uci:package "ietf-netconf-acm"; + container nacm { + uci:section "nacm"; + uci:section-name "nacm"; + nacm:default-deny-all; + + description + "Parameters for NETCONF access control model."; + + leaf enable-nacm { + uci:option "enable-nacm"; + type boolean; + default "true"; + description + "Enables or disables all NETCONF access control + enforcement. If 'true', then enforcement + is enabled. If 'false', then enforcement + is disabled."; + } + + leaf read-default { + uci:option "read-default"; + type action-type; + default "permit"; + description + "Controls whether read access is granted if + no appropriate rule is found for a + particular read request."; + } + + leaf write-default { + uci:option "write-default"; + type action-type; + default "deny"; + description + "Controls whether create, update, or delete access + is granted if no appropriate rule is found for a + particular write request."; + } + + leaf exec-default { + uci:option "exec-default"; + type action-type; + default "permit"; + description + "Controls whether exec access is granted if no appropriate + rule is found for a particular protocol operation request."; + } + + leaf enable-external-groups { + uci:option "enable-external-groups"; + type boolean; + default "true"; + description + "Controls whether the server uses the groups reported by the + NETCONF transport layer when it assigns the user to a set of + NACM groups. If this leaf has the value 'false', any group + names reported by the transport layer are ignored by the + server."; + } + + leaf denied-operations { + uci:option "defined-operations"; + type yang:zero-based-counter32; + config false; + mandatory true; + description + "Number of times since the server last restarted that a + protocol operation request was denied."; + } + + leaf denied-data-writes { + uci:option "denied-data-writes"; + type yang:zero-based-counter32; + config false; + mandatory true; + description + "Number of times since the server last restarted that a + protocol operation request to alter + a configuration datastore was denied."; + } + + leaf denied-notifications { + uci:option "denied-notifications"; + type yang:zero-based-counter32; + config false; + mandatory true; + description + "Number of times since the server last restarted that + a notification was dropped for a subscription because + access to the event type was denied."; + } + + container groups { + uci:section "groups"; + uci:section-name "groups"; + description + "NETCONF access control groups."; + + list group { + uci:section "group"; + uci:leaf-as-name "name"; + key name; + + description + "One NACM group entry. This list will only contain + configured entries, not any entries learned from + any transport protocols."; + + leaf name { + uci:option "name"; + type group-name-type; + description + "Group name associated with this entry."; + } + + leaf-list user-name { + uci:option "user-name"; + type user-name-type; + description + "Each entry identifies the username of + a member of the group associated with + this entry."; + } + } + } + + list rule-list { + uci:section "rule-list"; + uci:leaf-as-name "name"; + key name; + ordered-by user; + description + "An ordered collection of access control rules."; + + leaf name { + uci:option "name"; + type string { + length "1..max"; + } + description + "Arbitrary name assigned to the rule-list."; + } + leaf-list group { + uci:option "group"; + type union { + type matchall-string-type; + type group-name-type; + } + description + "List of administrative groups that will be + assigned the associated access rights + defined by the 'rule' list. + + The string '*' indicates that all groups apply to the + entry."; + } + + list rule { + uci:section "rule"; + uci:leaf-as-name "name"; + key name; + ordered-by user; + description + "One access control rule. + + Rules are processed in user-defined order until a match is + found. A rule matches if 'module-name', 'rule-type', and + 'access-operations' match the request. If a rule + matches, the 'action' leaf determines whether or not + access is granted."; + + leaf name { + uci:option "name"; + type string { + length "1..max"; + } + description + "Arbitrary name assigned to the rule."; + } + + leaf module-name { + uci:option "module-name"; + type union { + type matchall-string-type; + type string; + } + default "*"; + description + "Name of the module associated with this rule. + + This leaf matches if it has the value '*' or if the + object being accessed is defined in the module with the + specified module name."; + } + + leaf rule-type { + uci:option "rule_type"; + type uint32; + description + "This choice matches if all leafs present in the rule + match the request. If no leafs are present, the + choice matches all requests."; + } + + leaf rpc-name { + uci:option "rpc-name"; + type union { + type matchall-string-type; + type string; + } + description + "This leaf matches if it has the value '*' or if + its value equals the requested protocol operation + name."; + } + leaf notification-name { + uci:option "notification-name"; + type union { + type matchall-string-type; + type string; + } + description + "This leaf matches if it has the value '*' or if its + value equals the requested notification name."; + } + leaf path { + uci:option "path"; + type node-instance-identifier; + mandatory true; + description + "Data node instance-identifier associated with the + data node, action, or notification controlled by + this rule. + + Configuration data or state data + instance-identifiers start with a top-level + data node. A complete instance-identifier is + required for this type of path value. + + The special value '/' refers to all possible + datastore contents."; + } + + leaf access-operations { + uci:option "access-operations"; + type union { + type matchall-string-type; + type access-operations-type; + } + default "*"; + description + "Access operations associated with this rule. + + This leaf matches if it has the value '*' or if the + bit corresponding to the requested operation is set."; + } + + leaf action { + uci:option "action"; + type action-type; + mandatory true; + description + "The access control action associated with the + rule. If a rule has been determined to match a + particular request, then this object is used + to determine whether to permit or deny the + request."; + } + + leaf comment { + uci:option "comment"; + type string; + description + "A textual description of the access rule."; + } + } + } + } +} \ No newline at end of file diff --git a/yang/lmapd.yang b/yang/lmapd.yang new file mode 100644 index 0000000..8ad5f91 --- /dev/null +++ b/yang/lmapd.yang @@ -0,0 +1,1138 @@ +module lmapd { + + yang-version 1.1; + namespace "urn:ietf:params:xml:ns:yang:lmapd"; + prefix "lmapd"; + + import ietf-yang-types { + prefix yang; + } + import ietf-inet-types { + prefix inet; + } + import ietf-netconf-acm { + prefix nacm; + } + import ietf-lmap-common { + prefix lmap; + } + import openwrt-uci-extension { + prefix uci; + } + + organization + "IETF Large-Scale Measurement of Broadband Performance + Working Group"; + + contact + "WG Web: + WG List: + + Editor: Juergen Schoenwaelder + + + Editor: Vaibhav Bajpai + "; + + description + "This module defines a data model for controlling Measurement + Agents that are part of a Large-Scale Measurement Platform + (LMAP). This data model is expected to be implemented by + Measurement Agents."; + + revision "2017-08-08" { + description + "Initial version"; + reference + "RFC 8194: A YANG Data Model for LMAP Measurement Agents"; + } + + /* + * Typedefs + */ + + typedef event-ref { + type leafref { + path "/lmap/events/event/name"; + } + description + "This type is used by data models that need to reference + a configured event source."; + } + + typedef task-ref { + type leafref { + path "/lmap/tasks/task/name"; + } + description + "This type is used by data models that need to reference + a configured Task."; + } + + typedef schedule-ref { + type leafref { + path "/lmap/schedules/schedule/name"; + } + description + "This type is used by data models that need to reference + a configured Schedule."; + } + + /* + * Groupings + */ + + grouping start-end-grouping { + description + "A grouping that provides start and end times for + Event objects."; + leaf start { + uci:option "start"; + type yang:date-and-time; + description + "The date and time when the Event object + starts to create triggers."; + } + leaf end { + uci:option "end"; + type yang:date-and-time; + description + "The date and time when the Event object + stops to create triggers. + + It is generally a good idea to always configure + an end time and to refresh the end time as needed + to ensure that agents that lose connectivity to + their Controller do not continue executing Schedules + forever."; + } + } + + grouping registry-grouping { + description + "This grouping models a list of entries in a registry + that identify functions of a Task."; + + list function { + uci:section "function"; + uci:leaf-as-name "uri"; + + key uri; + description + "A list of entries in a registry identifying functions."; + + leaf uri { + uci:option "uri"; + type inet:uri; + description + "A URI identifying an entry in a registry."; + } + + leaf-list role { + uci:option "role"; + type string; + description + "A set of roles for the identified registry entry."; + } + } + } + + grouping options-grouping { + description + "A list of options of a Task. Each option is a name/value + pair (where the value may be absent)."; + + list option { + uci:section "task_option"; + uci:leaf-as-name "id"; + + key "id"; + ordered-by user; + description + "A list of options passed to the Task. It is a list of + key/value pairs and may be used to model options. + Options may be used to identify the role of a Task + or to pass a Channel name to a Task."; + + leaf id { + uci:option "id"; + + type lmap:identifier; + description + "An identifier uniquely identifying an option. This + identifier is required by YANG to uniquely identify + a name/value pair, but it otherwise has no semantic + value"; + } + + leaf name { + uci:option "name"; + + type string; + description + "The name of the option."; + } + + leaf value { + uci:option "value"; + + type string; + description + "The value of the option."; + } + } + } + + /* + * Capability, configuration, and state data nodes + */ + + uci:package "lmapd"; + container lmap { + uci:section "lmap"; + uci:section-name "lmap"; + description + "Configuration and control of a Measurement Agent."; + + container capabilities { + uci:section "capabilities"; + uci:section-name "capabilities"; + config false; + description + "Agent capabilities including a list of supported Tasks."; + + leaf version { + uci:option "version"; + type string; + config false; + mandatory true; + description + "A short description of the software implementing the + Measurement Agent. This should include the version + number of the Measurement Agent software."; + } + + leaf-list tag { + uci:option "tag"; + type lmap:tag; + config false; + description + "An optional unordered set of tags that provide + additional information about the capabilities of + the Measurement Agent."; + } + + container tasks { + uci:section "tasks"; + uci:section-name "tasks"; + description + "A list of Tasks that the Measurement Agent supports."; + + list task { + uci:section "task"; + uci:leaf-as-name "name"; + key name; + description + "The list of Tasks supported by the Measurement Agent."; + + leaf name { + uci:option "name"; + type lmap:identifier; + description + "The unique name of a Task capability."; + } + + uses registry-grouping; + + leaf version { + uci:option "version"; + type string; + + description + "A short description of the software implementing + the Task. This should include the version + number of the Measurement Task software."; + } + + leaf program { + uci:option "program"; + type string; + description + "The (local) program to invoke in order to execute + the Task."; + } + } + } + } + + /* + * Agent Configuration + */ + + container agent { + uci:section "agent"; + uci:section-name "agent"; + description + "Configuration of parameters affecting the whole + Measurement Agent."; + + leaf agent-id { + uci:option "agent_id"; + type yang:uuid; + description + "The agent-id identifies a Measurement Agent with + a very low probability of collision. In certain + deployments, the agent-id may be considered + sensitive, and hence this object is optional."; + } + + leaf group-id { + uci:option "group_id"; + type string; + description + "The group-id identifies a group of Measurement + Agents. In certain deployments, the group-id + may be considered less sensitive than the + agent-id."; + } + + leaf measurement-point { + uci:option "measurement_point"; + type string; + description + "The measurement point indicating where the + Measurement Agent is located on a path."; + reference + "RFC 7398: A Reference Path and Measurement Points + for Large-Scale Measurement of Broadband + Performance"; + } + + leaf report-agent-id { + uci:option "report_agent_id"; + type boolean; + must '. != "true" or ../agent-id' { + description + "An agent-id must exist for this to be set + to true."; + } + default false; + description + "The 'report-agent-id' controls whether the + 'agent-id' is reported to Collectors."; + } + + leaf report-group-id { + uci:option "report_group_id"; + type boolean; + must '. != "true" or ../group-id' { + description + "A group-id must exist for this to be set + to true."; + } + default false; + description + "The 'report-group-id' controls whether the + 'group-id' is reported to Collectors."; + } + + leaf report-measurement-point { + uci:option "report_measurement_point"; + type boolean; + must '. != "true" or ../measurement-point' { + description + "A measurement-point must exist for this to be + set to true."; + } + default false; + description + "The 'report-measurement-point' controls whether + the 'measurement-point' is reported to Collectors."; + } + + leaf controller-timeout { + uci:option "controller_timeout"; + type uint32; + units "seconds"; + description + "A timer is started after each successful contact + with a Controller. When the timer reaches the + controller-timeout, an event (controller-lost) is + raised indicating that connectivity to the Controller + has been lost."; + } + + leaf last-started { + uci:option "last_started"; + type yang:date-and-time; + config false; + mandatory true; + description + "The date and time the Measurement Agent last started."; + } + } + + /* + * Task Configuration + */ + + container tasks { + uci:section "tasks"; + uci:section-name "tasks"; + description + "Configuration of LMAP Tasks."; + + list task { + uci:section "task"; + uci:leaf-as-name "name"; + key name; + description + "The list of Tasks configured on the Measurement + Agent. Note that a configured Task MUST resolve to a + Task listed in the capabilities. Attempts to execute + a configured Task that is not listed in the capabilities + result in a runtime execution error."; + + leaf name { + uci:option "name"; + type lmap:identifier; + description + "The unique name of a Task."; + } + + uses registry-grouping; + + leaf program { + uci:option "program"; + type string; + nacm:default-deny-write; + + description + "The (local) program to invoke in order to execute + the Task. If this leaf is not set, then the system + will try to identify a suitable program based on + the registry information present."; + } + + uses options-grouping; + + leaf-list tag { + uci:option "tag"; + type lmap:identifier; + description + "A set of Task-specific tags that are reported + together with the measurement results to a Collector. + A tag can be used, for example, to carry the + Measurement Cycle ID."; + } + } + } + + /* + * Schedule Instructions + */ + + container schedules { + uci:section "schedules"; + uci:section-name "schedules"; + description + "Configuration of LMAP Schedules. Schedules control + which Tasks are executed by the LMAP implementation."; + + list schedule { + uci:section "schedule"; + uci:leaf-as-name "name"; + key name; + description + "Configuration of a particular Schedule."; + + leaf name { + uci:option "name"; + type lmap:identifier; + description + "The locally unique, administratively assigned name + for this Schedule."; + } + + leaf start { + uci:option "start"; + type event-ref; + mandatory true; + + description + "The event source controlling the start of the + scheduled Actions."; + } + + leaf end { + uci:option "end"; + type event-ref; + description + "The event source controlling the graceful + forced termination of the scheduled Actions."; + } + + leaf duration { + uci:option "duration"; + type uint32; + units "seconds"; + description + "The duration controlling the graceful forced + termination of the scheduled Actions."; + } + + leaf execution-mode { + uci:option "execution_mode"; + type enumeration { + enum sequential { + value 1; + description + "The Actions of the Schedule are executed + sequentially."; + } + enum parallel { + value 2; + description + "The Actions of the Schedule are executed + concurrently."; + } + enum pipelined { + value 3; + + description + "The Actions of the Schedule are executed in a + pipelined mode. Output created by an Action is + passed as input to the subsequent Action."; + } + } + default pipelined; + description + "The execution mode of this Schedule determines in + which order the Actions of the Schedule are executed."; + } + + leaf-list tag { + uci:option "tag"; + type lmap:tag; + description + "A set of Schedule-specific tags that are reported + together with the measurement results to a Collector."; + } + + leaf-list suppression-tag { + uci:option "suppression_tag"; + type lmap:tag; + description + "A set of Suppression tags that are used to select + Schedules to be suppressed."; + } + + leaf state { + uci:option "state"; + type enumeration { + enum enabled { + value 1; + description + "The value 'enabled' indicates that the + Schedule is currently enabled."; + } + enum disabled { + value 2; + description + "The value 'disabled' indicates that the + Schedule is currently disabled."; + } + enum running { + value 3; + description + "The value 'running' indicates that the + Schedule is currently running."; + } + enum suppressed { + value 4; + description + "The value 'suppressed' indicates that the + Schedule is currently suppressed."; + } + } + config false; + mandatory true; + description + "The current state of the Schedule."; + } + + leaf storage { + uci:option "storage"; + type yang:gauge64; + units "bytes"; + config false; + mandatory true; + description + "The amount of secondary storage (e.g., allocated in a + file system) holding temporary data allocated to the + Schedule in bytes. This object reports the amount of + allocated physical storage and not the storage used + by logical data records."; + } + + leaf invocations { + uci:option "invocations"; + type yang:counter32; + config false; + mandatory true; + description + "Number of invocations of this Schedule. This counter + does not include suppressed invocations or invocations + that were prevented due to an overlap with a previous + invocation of this Schedule."; + } + + leaf suppressions { + uci:option "suppressions"; + type yang:counter32; + config false; + mandatory true; + description + "Number of suppressed executions of this Schedule."; + } + + leaf overlaps { + uci:option "overlaps"; + type yang:counter32; + config false; + mandatory true; + + description + "Number of executions prevented due to overlaps with + a previous invocation of this Schedule."; + } + + leaf failures { + uci:option "failures"; + type yang:counter32; + config false; + mandatory true; + description + "Number of failed executions of this Schedule. A + failed execution is an execution where at least + one Action failed."; + } + + leaf last-invocation { + uci:option "last_invocation"; + type yang:date-and-time; + config false; + description + "The date and time of the last invocation of + this Schedule."; + } + + list action { + uci:section "action"; + uci:leaf-as-name "name"; + key name; + description + "An Action describes a Task that is invoked by the + Schedule. Multiple Actions are invoked according to + the execution-mode of the Schedule."; + + leaf name { + uci:option "name"; + type lmap:identifier; + description + "The unique identifier for this Action."; + } + + leaf task { + uci:option "task"; + type task-ref; + mandatory true; + description + "The Task invoked by this Action."; + } + + uses options-grouping; + + leaf-list destination { + uci:option "destination"; + type schedule-ref; + description + "A set of Schedules receiving the output produced + by this Action. The output is stored temporarily + since the Destination Schedules will in general + not be running when output is passed to them. The + behavior of an Action passing data to its own + Schedule is implementation specific. + + Data passed to a sequential or pipelined Schedule + is received by the Schedule's first Action. Data + passed to a parallel Schedule is received by all + Actions of the Schedule."; + } + + leaf-list tag { + uci:option "tag"; + type lmap:tag; + description + "A set of Action-specific tags that are reported + together with the measurement results to a + Collector."; + } + + leaf-list suppression-tag { + uci:option "suppression_tag"; + type lmap:tag; + description + "A set of Suppression tags that are used to select + Actions to be suppressed."; + } + + leaf state { + uci:option "state"; + type enumeration { + enum enabled { + value 1; + description + "The value 'enabled' indicates that the + Action is currently enabled."; + } + enum disabled { + value 2; + description + "The value 'disabled' indicates that the + Action is currently disabled."; + } + enum running { + value 3; + description + "The value 'running' indicates that the + Action is currently running."; + } + enum suppressed { + value 4; + description + "The value 'suppressed' indicates that the + Action is currently suppressed."; + } + } + config false; + mandatory true; + description + "The current state of the Action."; + } + + leaf storage { + uci:option "storage"; + type yang:gauge64; + units "bytes"; + config false; + mandatory true; + description + "The amount of secondary storage (e.g., allocated in a + file system) holding temporary data allocated to the + Schedule in bytes. This object reports the amount of + allocated physical storage and not the storage used + by logical data records."; + } + + leaf invocations { + uci:option "invocations"; + type yang:counter32; + config false; + mandatory true; + + description + "Number of invocations of this Action. This counter + does not include suppressed invocations or invocations + that were prevented due to an overlap with a previous + invocation of this Action."; + } + + leaf suppressions { + uci:option "suppressions"; + type yang:counter32; + config false; + mandatory true; + description + "Number of suppressed executions of this Action."; + } + + leaf overlaps { + uci:option "overlaps"; + type yang:counter32; + config false; + mandatory true; + description + "Number of executions prevented due to overlaps with + a previous invocation of this Action."; + } + + leaf failures { + uci:option "failures"; + type yang:counter32; + config false; + mandatory true; + description + "Number of failed executions of this Action."; + } + + leaf last-invocation { + uci:option "last_invocation"; + type yang:date-and-time; + config false; + mandatory true; + description + "The date and time of the last invocation of + this Action."; + } + + leaf last-completion { + uci:option "last_completion"; + type yang:date-and-time; + config false; + mandatory true; + description + "The date and time of the last completion of + this Action."; + } + + leaf last-status { + uci:option "last_status"; + type lmap:status-code; + config false; + mandatory true; + description + "The status code returned by the last execution of + this Action."; + } + + leaf last-message { + uci:option "last_message"; + type string; + config false; + mandatory true; + description + "The status message produced by the last execution + of this Action."; + } + + leaf last-failed-completion { + uci:option "last_failed_completion"; + type yang:date-and-time; + config false; + mandatory true; + description + "The date and time of the last failed completion + of this Action."; + } + + leaf last-failed-status { + uci:option "last_failed_status"; + type lmap:status-code; + config false; + mandatory true; + description + "The status code returned by the last failed + execution of this Action."; + } + + leaf last-failed-message { + uci:option "last_failed_message"; + type string; + config false; + mandatory true; + description + "The status message produced by the last failed + execution of this Action."; + } + } + } + } + + /* + * Suppression Instructions + */ + + container suppressions { + uci:section "suppressions"; + uci:section-name "suppressions"; + description + "Suppression information to prevent Schedules or + certain Actions from starting."; + + list suppression { + uci:section "suppression"; + uci:leaf-as-name "name"; + key name; + description + "Configuration of a particular Suppression."; + + leaf name { + uci:option "name"; + type lmap:identifier; + description + "The locally unique, administratively assigned name + for this Suppression."; + } + + leaf start { + uci:option "start"; + type event-ref; + description + "The event source controlling the start of the + Suppression period."; + } + + leaf end { + uci:option "end"; + type event-ref; + description + "The event source controlling the end of the + Suppression period. If not present, Suppression + continues indefinitely."; + } + + leaf-list match { + uci:option "match"; + type lmap:glob-pattern; + description + "A set of Suppression match patterns. The Suppression + will apply to all Schedules (and their Actions) that + have a matching value in their suppression-tags + and to all Actions that have a matching value in + their suppression-tags."; + } + + leaf stop-running { + uci:option "stop_running"; + type boolean; + default false; + description + "If 'stop-running' is true, running Schedules and + Actions matching the Suppression will be terminated + when Suppression is activated. If 'stop-running' is + false, running Schedules and Actions will not be + affected if Suppression is activated."; + } + + leaf state { + uci:option "state"; + type enumeration { + enum enabled { + value 1; + description + "The value 'enabled' indicates that the + Suppression is currently enabled."; + } + enum disabled { + value 2; + description + "The value 'disabled' indicates that the + Suppression is currently disabled."; + } + enum active { + value 3; + description + "The value 'active' indicates that the + Suppression is currently active."; + } + } + config false; + mandatory true; + description + "The current state of the Suppression."; + } + } + } + + /* + * Event Instructions + */ + + container events { + uci:section "events"; + uci:section-name "events"; + description + "Configuration of LMAP events. + + Implementations may be forced to delay acting + upon the occurrence of events in the face of local + constraints. An Action triggered by an event + therefore should not rely on the accuracy + provided by the scheduler implementation."; + + list event { + uci:section "event"; + uci:leaf-as-name "name"; + key name; + description + "The list of event sources configured on the + Measurement Agent."; + + leaf name { + uci:option "name"; + type lmap:identifier; + description + "The unique name of an event source."; + } + + leaf random-spread { + uci:option "random_spread"; + type uint32; + units seconds; + description + "This optional leaf adds a random spread to the + computation of the event's trigger time. The + random spread is a uniformly distributed random + number taken from the interval [0:random-spread]."; + } + + leaf cycle-interval { + uci:option "cycle_interval"; + type uint32; + units seconds; + description + "The optional cycle-interval defines the duration + of the time interval in seconds that is used to + calculate cycle numbers. No cycle number is + calculated if the optional cycle-interval does + not exist."; + } + + leaf event-type { + uci:option "event_type"; + type uint32; + description + "Different types of events."; + } + + leaf interval { + uci:option "interval"; + type uint32 { + range "1..max"; + } + units "seconds"; + mandatory true; + description + "The number of seconds between two triggers + generated by this periodic timing object."; + } + + leaf-list month { + uci:option "month"; + type lmap:month-or-all; + min-elements 1; + description + "A set of months at which this calendar timing + will trigger. The wildcard means all months."; + } + + leaf-list day-of-month { + uci:option "day_of_month"; + type lmap:day-of-months-or-all; + min-elements 1; + description + "A set of days of the month at which this + calendar timing will trigger. The wildcard means + all days of a month."; + } + + leaf-list day-of-week { + uci:option "day_of_week"; + type lmap:weekday-or-all; + min-elements 1; + description + "A set of weekdays at which this calendar timing + will trigger. The wildcard means all weekdays."; + } + + leaf-list hour { + uci:option "hour"; + type lmap:hour-or-all; + min-elements 1; + description + "A set of hours at which this calendar timing will + trigger. The wildcard means all hours of a day."; + } + + leaf-list minute { + uci:option "minute"; + type lmap:minute-or-all; + min-elements 1; + description + "A set of minutes at which this calendar timing + will trigger. The wildcard means all minutes of + an hour."; + } + + leaf-list second { + uci:option "second"; + type lmap:second-or-all; + min-elements 1; + description + "A set of seconds at which this calendar timing + will trigger. The wildcard means all seconds of + a minute."; + } + + leaf timezone-offset { + uci:option "timezone_offset"; + type lmap:timezone-offset; + description + "The time zone in which this calendar timing + object will be evaluated. If not present, + the system's local time zone will be used."; + } + + leaf time { + uci:option "time"; + type yang:date-and-time; + mandatory true; + description + "This one-off timing object triggers once at + the configured date and time."; + } + + leaf immediate { + uci:option "immediate"; + type empty; + mandatory true; + description + "This immediate Event object triggers immediately + when it is configured."; + } + + leaf startup { + uci:option "startup"; + type empty; + mandatory true; + description + "This startup Event object triggers whenever the + Measurement Agent (re)starts."; + } + + leaf controller-lost { + uci:option "controller_lost"; + type empty; + mandatory true; + description + "The controller-lost Event object triggers when + the connectivity to the Controller has been lost + for at least 'controller-timeout' seconds."; + } + + leaf controller-connected { + uci:option "controller_connected"; + type empty; + mandatory true; + description + "The controller-connected Event object triggers + when the connectivity to the Controller has been + restored after it was lost for at least + 'controller-timeout' seconds."; + } + uses start-end-grouping; + } + } + } +} diff --git a/yang/restconf-example.yang b/yang/restconf-example.yang index 8003543..a523d5e 100644 --- a/yang/restconf-example.yang +++ b/yang/restconf-example.yang @@ -18,6 +18,17 @@ module restconf-example { } } + grouping instructor-data { + leaf name { + uci:option "name"; + type string; + } + leaf email { + uci:option "email"; + type email; + } + } + uci:package "restconf-example"; container course { uci:section-name "course"; @@ -75,6 +86,57 @@ module restconf-example { uci:option "grade"; type grade; } + + list contact-option { + uci:section "contact_option"; + uci:leaf-as-name "email"; + + key email; + + leaf email { + uci:option "email"; + type string; + } + + leaf example-leaf { + uci:option "example-leaf"; + type string; + } + } + + list option { + uci:section "options"; + uci:leaf-as-name "id"; + + key "id"; + + leaf id { + uci:option "id"; + type string; + } + + leaf name { + uci:option "name"; + type string; + } + + list more-options { + uci:section "more_options"; + uci:leaf-as-name "id"; + + key "id"; + + leaf id { + uci:option "id"; + type string; + } + + leaf value { + uci:option "value"; + type string; + } + } + } } container instructor { diff --git a/yang2json.sh b/yang2json.sh new file mode 100755 index 0000000..e3f7711 --- /dev/null +++ b/yang2json.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +declare -a f_array=("openwrt-uci-extension" "ietf-inet-types" "ietf-yang-types" "ietf-netconf-acm" "ietf-lmap-common" "lmapd" "restconf-example") + +for val in ${f_array[@]}; do + echo "pyang -f yin ./yang/$val.yang -p ./yang -o ./yin/$val.yin" + pyang -f yin ./yang/$val.yang -p ./yang -o ./yin/$val.yin +done + +target=$1 + +echo "python3 ./yin2json/yin2json.py -y ./yin -o ./generated ./yin/$target.yin" +python3 ./yin2json/yin2json.py -y ./yin -o ./generated ./yin/$target.yin diff --git a/yin/ietf-inet-types.yin b/yin/ietf-inet-types.yin new file mode 100644 index 0000000..fc612be --- /dev/null +++ b/yin/ietf-inet-types.yin @@ -0,0 +1,417 @@ + + + + + + IETF NETMOD (NETCONF Data Modeling Language) Working Group + + + WG Web: <http://tools.ietf.org/wg/netmod/> +WG List: <mailto:netmod@ietf.org> +WG Chair: David Kessens + <mailto:david.kessens@nsn.com> +WG Chair: Juergen Schoenwaelder + <mailto:j.schoenwaelder@jacobs-university.de> +Editor: Juergen Schoenwaelder + <mailto:j.schoenwaelder@jacobs-university.de> + + + This module contains a collection of generally useful derived +YANG data types for Internet addresses and related things. +Copyright (c) 2013 IETF Trust and the persons identified as +authors of the code. All rights reserved. +Redistribution and use in source and binary forms, with or +without modification, is permitted pursuant to, and subject +to the license terms contained in, the Simplified BSD License +set forth in Section 4.c of the IETF Trust's Legal Provisions +Relating to IETF Documents +(http://trustee.ietf.org/license-info). +This version of this YANG module is part of RFC 6991; see +the RFC itself for full legal notices. + + + + This revision adds the following new data types: +- ip-address-no-zone +- ipv4-address-no-zone +- ipv6-address-no-zone + + + RFC 6991: Common YANG Data Types + + + + + Initial revision. + + + RFC 6021: Common YANG Data Types + + + + + + + + An unknown or unspecified version of the Internet +protocol. + + + + + + The IPv4 protocol as defined in RFC 791. + + + + + + The IPv6 protocol as defined in RFC 2460. + + + + + This value represents the version of the IP protocol. +In the value set and its semantics, this type is equivalent +to the InetVersion textual convention of the SMIv2. + + + RFC 791: Internet Protocol +RFC 2460: Internet Protocol, Version 6 (IPv6) Specification +RFC 4001: Textual Conventions for Internet Network Addresses + + + + + + + + The dscp type represents a Differentiated Services Code Point +that may be used for marking packets in a traffic stream. +In the value set and its semantics, this type is equivalent +to the Dscp textual convention of the SMIv2. + + + RFC 3289: Management Information Base for the Differentiated + Services Architecture +RFC 2474: Definition of the Differentiated Services Field + (DS Field) in the IPv4 and IPv6 Headers +RFC 2780: IANA Allocation Guidelines For Values In + the Internet Protocol and Related Headers + + + + + + + + The ipv6-flow-label type represents the flow identifier or Flow +Label in an IPv6 packet header that may be used to +discriminate traffic flows. +In the value set and its semantics, this type is equivalent +to the IPv6FlowLabel textual convention of the SMIv2. + + + RFC 3595: Textual Conventions for IPv6 Flow Label +RFC 2460: Internet Protocol, Version 6 (IPv6) Specification + + + + + + + + The port-number type represents a 16-bit port number of an +Internet transport-layer protocol such as UDP, TCP, DCCP, or +SCTP. Port numbers are assigned by IANA. A current list of +all assignments is available from <http://www.iana.org/>. +Note that the port number value zero is reserved by IANA. In +situations where the value zero does not make sense, it can +be excluded by subtyping the port-number type. +In the value set and its semantics, this type is equivalent +to the InetPortNumber textual convention of the SMIv2. + + + RFC 768: User Datagram Protocol +RFC 793: Transmission Control Protocol +RFC 4960: Stream Control Transmission Protocol +RFC 4340: Datagram Congestion Control Protocol (DCCP) +RFC 4001: Textual Conventions for Internet Network Addresses + + + + + + The as-number type represents autonomous system numbers +which identify an Autonomous System (AS). An AS is a set +of routers under a single technical administration, using +an interior gateway protocol and common metrics to route +packets within the AS, and using an exterior gateway +protocol to route packets to other ASes. IANA maintains +the AS number space and has delegated large parts to the +regional registries. +Autonomous system numbers were originally limited to 16 +bits. BGP extensions have enlarged the autonomous system +number space to 32 bits. This type therefore uses an uint32 +base type without a range restriction in order to support +a larger autonomous system number space. +In the value set and its semantics, this type is equivalent +to the InetAutonomousSystemNumber textual convention of +the SMIv2. + + + RFC 1930: Guidelines for creation, selection, and registration + of an Autonomous System (AS) +RFC 4271: A Border Gateway Protocol 4 (BGP-4) +RFC 4001: Textual Conventions for Internet Network Addresses +RFC 6793: BGP Support for Four-Octet Autonomous System (AS) + Number Space + + + + + + + + + The ip-address type represents an IP address and is IP +version neutral. The format of the textual representation +implies the IP version. This type supports scoped addresses +by allowing zone identifiers in the address format. + + + RFC 4007: IPv6 Scoped Address Architecture + + + + + + + + The ipv4-address type represents an IPv4 address in +dotted-quad notation. The IPv4 address may include a zone +index, separated by a % sign. +The zone index is used to disambiguate identical address +values. For link-local addresses, the zone index will +typically be the interface index number or the name of an +interface. If the zone index is not present, the default +zone of the device will be used. +The canonical format for the zone index is the numerical +format + + + + + + + + + The ipv6-address type represents an IPv6 address in full, +mixed, shortened, and shortened-mixed notation. The IPv6 +address may include a zone index, separated by a % sign. +The zone index is used to disambiguate identical address +values. For link-local addresses, the zone index will +typically be the interface index number or the name of an +interface. If the zone index is not present, the default +zone of the device will be used. +The canonical format of IPv6 addresses uses the textual +representation defined in Section 4 of RFC 5952. The +canonical format for the zone index is the numerical +format as described in Section 11.2 of RFC 4007. + + + RFC 4291: IP Version 6 Addressing Architecture +RFC 4007: IPv6 Scoped Address Architecture +RFC 5952: A Recommendation for IPv6 Address Text + Representation + + + + + + + + + The ip-address-no-zone type represents an IP address and is +IP version neutral. The format of the textual representation +implies the IP version. This type does not support scoped +addresses since it does not allow zone identifiers in the +address format. + + + RFC 4007: IPv6 Scoped Address Architecture + + + + + + + + An IPv4 address without a zone index. This type, derived from +ipv4-address, may be used in situations where the zone is +known from the context and hence no zone index is needed. + + + + + + + + An IPv6 address without a zone index. This type, derived from +ipv6-address, may be used in situations where the zone is +known from the context and hence no zone index is needed. + + + RFC 4291: IP Version 6 Addressing Architecture +RFC 4007: IPv6 Scoped Address Architecture +RFC 5952: A Recommendation for IPv6 Address Text + Representation + + + + + + + + + The ip-prefix type represents an IP prefix and is IP +version neutral. The format of the textual representations +implies the IP version. + + + + + + + + The ipv4-prefix type represents an IPv4 address prefix. +The prefix length is given by the number following the +slash character and must be less than or equal to 32. +A prefix length value of n corresponds to an IP address +mask that has n contiguous 1-bits from the most +significant bit (MSB) and all other bits set to 0. +The canonical format of an IPv4 prefix has all bits of +the IPv4 address set to zero that are not part of the +IPv4 prefix. + + + + + + + + + The ipv6-prefix type represents an IPv6 address prefix. +The prefix length is given by the number following the +slash character and must be less than or equal to 128. +A prefix length value of n corresponds to an IP address +mask that has n contiguous 1-bits from the most +significant bit (MSB) and all other bits set to 0. +The IPv6 address should have all bits that do not belong +to the prefix set to zero. +The canonical format of an IPv6 prefix has all bits of +the IPv6 address set to zero that are not part of the +IPv6 prefix. Furthermore, the IPv6 address is represented +as defined in Section 4 of RFC 5952. + + + RFC 5952: A Recommendation for IPv6 Address Text + Representation + + + + + + + + + The domain-name type represents a DNS domain name. The +name SHOULD be fully qualified whenever possible. +Internet domain names are only loosely specified. Section +3.5 of RFC 1034 recommends a syntax (modified in Section +2.1 of RFC 1123). The pattern above is intended to allow +for current practice in domain name use, and some possible +future expansion. It is designed to hold various types of +domain names, including names used for A or AAAA records +(host names) and other records, such as SRV records. Note +that Internet host names have a stricter syntax (described +in RFC 952) than the DNS recommendations in RFCs 1034 and +1123, and that systems that want to store host names in +schema nodes using the domain-name type are recommended to +adhere to this stricter standard to ensure interoperability. +The encoding of DNS names in the DNS protocol is limited +to 255 characters. Since the encoding consists of labels +prefixed by a length bytes and there is a trailing NULL +byte, only 253 characters can appear in the textual dotted +notation. +The description clause of schema nodes using the domain-name +type MUST describe when and how these names are resolved to +IP addresses. Note that the resolution of a domain-name value +may require to query multiple DNS records (e.g., A for IPv4 +and AAAA for IPv6). The order of the resolution process and +which DNS record takes precedence can either be defined +explicitly or may depend on the configuration of the +resolver. +Domain-name values use the US-ASCII encoding. Their canonical +format uses lowercase US-ASCII characters. Internationalized +domain names MUST be A-labels as per RFC 5890. + + + RFC 952: DoD Internet Host Table Specification +RFC 1034: Domain Names - Concepts and Facilities +RFC 1123: Requirements for Internet Hosts -- Application + and Support +RFC 2782: A DNS RR for specifying the location of services + (DNS SRV) +RFC 5890: Internationalized Domain Names in Applications + (IDNA): Definitions and Document Framework + + + + + + + + + The host type represents either an IP address or a DNS +domain name. + + + + + + The uri type represents a Uniform Resource Identifier +(URI) as defined by STD 66. +Objects using the uri type MUST be in US-ASCII encoding, +and MUST be normalized as described by RFC 3986 Sections +6.2.1, 6.2.2.1, and 6.2.2.2. All unnecessary +percent-encoding is removed, and all case-insensitive +characters are set to lowercase except for hexadecimal +digits, which are normalized to uppercase as described in +Section 6.2.2.1. +The purpose of this normalization is to help provide +unique URIs. Note that this normalization is not +sufficient to provide uniqueness. Two URIs that are +textually distinct after this normalization may still be +equivalent. +Objects using the uri type may restrict the schemes that +they permit. For example, 'data:' and 'urn:' schemes +might not be appropriate. +A zero-length URI is not a valid URI. This can be used to +express 'URI absent' where required. +In the value set and its semantics, this type is equivalent +to the Uri SMIv2 textual convention defined in RFC 5017. + + + RFC 3986: Uniform Resource Identifier (URI): Generic Syntax +RFC 3305: Report from the Joint W3C/IETF URI Planning Interest + Group: Uniform Resource Identifiers (URIs), URLs, + and Uniform Resource Names (URNs): Clarifications + and Recommendations +RFC 5017: MIB Textual Conventions for Uniform Resource + Identifiers (URIs) + + + diff --git a/yin/ietf-lmap-common.yin b/yin/ietf-lmap-common.yin new file mode 100644 index 0000000..4d37085 --- /dev/null +++ b/yin/ietf-lmap-common.yin @@ -0,0 +1,424 @@ + + + + + + + + + + + + + IETF Large-Scale Measurement of Broadband Performance +Working Group + + + WG Web: <https://datatracker.ietf.org/wg/lmap> +WG List: <mailto:lmap@ietf.org> + +Editor: Juergen Schoenwaelder + <j.schoenwaelder@jacobs-university.de> + +Editor: Vaibhav Bajpai + <bajpaiv@in.tum.de> + + + This module provides common definitions used by the data +models written for Large-Scale Measurement Platforms (LMAPs). +This module defines typedefs and groupings but no schema +tree elements. + + + + Initial version + + + RFC 8194: A YANG Data Model for LMAP Measurement Agents + + + + + + + + A string value used to name something. + + + + + + + + A tag consists of at least one character. + + + + + + + + A glob style pattern (following POSIX.2 fnmatch() without + special treatment of file paths): + + * matches a sequence of characters + ? matches a single character + [seq] matches any character in seq + [!seq] matches any character not in seq + + A backslash followed by a character matches the following + character. In particular: + + \* matches * + \? matches ? + \\ matches \ + + A sequence seq may be a sequence of characters (e.g., [abc] + or a range of characters (e.g., [a-c]). + + + + + + + + A wildcard for calendar scheduling entries. + + + + + + + + A cycle number represented in the format YYYYMMDD.HHMMSS +where YYYY represents the year, MM the month (1..12), DD +the day of the months (01..31), HH the hour (00..23), MM +the minute (00..59), and SS the second (00..59). The cycle +number is using Coordinated Universal Time (UTC). + + + + + + + + January of the Gregorian calendar. + + + + + + February of the Gregorian calendar. + + + + + + March of the Gregorian calendar. + + + + + + April of the Gregorian calendar. + + + + + + May of the Gregorian calendar. + + + + + + June of the Gregorian calendar. + + + + + + July of the Gregorian calendar. + + + + + + August of the Gregorian calendar. + + + + + + September of the Gregorian calendar. + + + + + + October of the Gregorian calendar. + + + + + + November of the Gregorian calendar. + + + + + + December of the Gregorian calendar. + + + + + A type modeling the month in the Gregorian calendar. + + + + + + + + + A month or a wildcard indicating all twelve months. + + + + + + + + A day of a month of the Gregorian calendar. + + + + + + + + + A day of a month or a wildcard indicating all days +of a month. + + + + + + + + Monday of the Gregorian calendar. + + + + + + Tuesday of the Gregorian calendar. + + + + + + Wednesday of the Gregorian calendar. + + + + + + Thursday of the Gregorian calendar. + + + + + + Friday of the Gregorian calendar. + + + + + + Saturday of the Gregorian calendar. + + + + + + Sunday of the Gregorian calendar. + + + + + A type modeling the weekdays in the Gregorian calendar. +The numbering follows the ISO 8601 scheme. + + + ISO 8601:2004: Data elements and interchange formats -- + Information interchange -- Representation + of dates and times + + + + + + + + + A weekday or a wildcard indicating all seven weekdays. + + + + + + + + An hour of a day. + + + + + + + + + An hour of a day or a wildcard indicating all hours +of a day. + + + + + + + + A minute of an hour. + + + + + + + + + A minute of an hour or a wildcard indicating all +minutes of an hour. + + + + + + + + A second of a minute. + + + + + + + + + A second of a minute or a wildcard indicating all +seconds of a minute. + + + + + + A status code returned by the execution of a Task. Note +that the actual range is implementation dependent, but it +should be portable to use values in the range 0..127 for +regular exit codes. By convention, 0 indicates successful +termination. Negative values may be used to indicate +abnormal termination due to a signal; the absolute value +may identify the signal number in this case. + + + + + + + + A time zone offset as it is used by the date-and-time type +defined in the ietf-yang-types module. The value Z is +equivalent to +00:00. The value -00:00 indicates an +unknown time-offset. + + + RFC 6991: Common YANG Data Types + + + + + This grouping models a list of entries in a registry +that identify functions of a Task. + + + + + + + A list of entries in a registry identifying functions. + + + + + + A URI identifying an entry in a registry. + + + + + + + A set of roles for the identified registry entry. + + + + + + + A list of options of a Task. Each option is a name/value +pair (where the value may be absent). + + + + + + + + A list of options passed to the Task. It is a list of +key/value pairs and may be used to model options. +Options may be used to identify the role of a Task +or to pass a Channel name to a Task. + + + + + + An identifier uniquely identifying an option. This +identifier is required by YANG to uniquely identify +a name/value pair, but it otherwise has no semantic +value + + + + + + + The name of the option. + + + + + + + The value of the option. + + + + + diff --git a/yin/ietf-netconf-acm.yin b/yin/ietf-netconf-acm.yin new file mode 100644 index 0000000..958a6ff --- /dev/null +++ b/yin/ietf-netconf-acm.yin @@ -0,0 +1,495 @@ + + + + + + + + + + + + IETF NETCONF (Network Configuration) Working Group + + + WG Web: <https://datatracker.ietf.org/wg/netconf/> +WG List: <mailto:netconf@ietf.org> + +Author: Andy Bierman + <mailto:andy@yumaworks.com> + +Author: Martin Bjorklund + <mailto:mbj@tail-f.com> + + + Network Configuration Access Control Model. + +Copyright (c) 2012 - 2018 IETF Trust and the persons +identified as authors of the code. All rights reserved. + +Redistribution and use in source and binary forms, with or +without modification, is permitted pursuant to, and subject +to the license terms contained in, the Simplified BSD +License set forth in Section 4.c of the IETF Trust's +Legal Provisions Relating to IETF Documents +(https://trustee.ietf.org/license-info). + +This version of this YANG module is part of RFC 8341; see +the RFC itself for full legal notices. + + + + Added support for YANG 1.1 actions and notifications tied to +data nodes. Clarified how NACM extensions can be used by +other data models. + + + RFC 8341: Network Configuration Access Control Model + + + + + Initial version. + + + RFC 6536: Network Configuration Protocol (NETCONF) + Access Control Model + + + + + Used to indicate that the data model node +represents a sensitive security system parameter. + +If present, the NETCONF server will only allow the designated +'recovery session' to have write access to the node. An +explicit access control rule is required for all other users. + +If the NACM module is used, then it must be enabled (i.e., +/nacm/enable-nacm object equals 'true'), or this extension +is ignored. + +The 'default-deny-write' extension MAY appear within a data +definition statement. It is ignored otherwise. + + + + + Used to indicate that the data model node +controls a very sensitive security system parameter. + +If present, the NETCONF server will only allow the designated +'recovery session' to have read, write, or execute access to +the node. An explicit access control rule is required for all +other users. + +If the NACM module is used, then it must be enabled (i.e., +/nacm/enable-nacm object equals 'true'), or this extension +is ignored. + +The 'default-deny-all' extension MAY appear within a data +definition statement, 'rpc' statement, or 'notification' +statement. It is ignored otherwise. + + + + + + + + General-purpose username string. + + + + + + + + The string containing a single asterisk '*' is used +to conceptually represent all possible values +for the particular leaf using this data type. + + + + + + + Any protocol operation that creates a +new data node. + + + + + Any protocol operation or notification that +returns the value of a data node. + + + + + Any protocol operation that alters an existing +data node. + + + + + Any protocol operation that removes a data node. + + + + + Execution access to the specified protocol operation. + + + + + Access operation. + + + + + + + + + Name of administrative group to which +users can be assigned. + + + + + + + Requested action is permitted. + + + + + Requested action is denied. + + + + + Action taken by the server when a particular +rule matches. + + + + + + Path expression used to represent a special +data node, action, or notification instance-identifier +string. + +A node-instance-identifier value is an +unrestricted YANG instance-identifier expression. +All the same rules as an instance-identifier apply, +except that predicates for keys are optional. If a key +predicate is missing, then the node-instance-identifier +represents all possible server instances for that key. + +This XML Path Language (XPath) expression is evaluated in the +following context: + + o The set of namespace declarations are those in scope on + the leaf element where this type is used. + + o The set of variable bindings contains one variable, + 'USER', which contains the name of the user of the + current session. + + o The function library is the core function library, but + note that due to the syntax restrictions of an + instance-identifier, no functions are allowed. + + o The context node is the root node in the data tree. + +The accessible tree includes actions and notifications tied +to data nodes. + + + + + + + + + Parameters for NETCONF access control model. + + + + + + + Enables or disables all NETCONF access control +enforcement. If 'true', then enforcement +is enabled. If 'false', then enforcement +is disabled. + + + + + + + + Controls whether read access is granted if +no appropriate rule is found for a +particular read request. + + + + + + + + Controls whether create, update, or delete access +is granted if no appropriate rule is found for a +particular write request. + + + + + + + + Controls whether exec access is granted if no appropriate +rule is found for a particular protocol operation request. + + + + + + + + Controls whether the server uses the groups reported by the +NETCONF transport layer when it assigns the user to a set of +NACM groups. If this leaf has the value 'false', any group +names reported by the transport layer are ignored by the +server. + + + + + + + + + Number of times since the server last restarted that a +protocol operation request was denied. + + + + + + + + + Number of times since the server last restarted that a +protocol operation request to alter +a configuration datastore was denied. + + + + + + + + + Number of times since the server last restarted that +a notification was dropped for a subscription because +access to the event type was denied. + + + + + + + NETCONF access control groups. + + + + + + + One NACM group entry. This list will only contain +configured entries, not any entries learned from +any transport protocols. + + + + + + Group name associated with this entry. + + + + + + + Each entry identifies the username of +a member of the group associated with +this entry. + + + + + + + + + + + An ordered collection of access control rules. + + + + + + + + Arbitrary name assigned to the rule-list. + + + + + + + + + + List of administrative groups that will be +assigned the associated access rights +defined by the 'rule' list. + +The string '*' indicates that all groups apply to the +entry. + + + + + + + + + One access control rule. + +Rules are processed in user-defined order until a match is +found. A rule matches if 'module-name', 'rule-type', and +'access-operations' match the request. If a rule +matches, the 'action' leaf determines whether or not +access is granted. + + + + + + + + Arbitrary name assigned to the rule. + + + + + + + + + + + Name of the module associated with this rule. + +This leaf matches if it has the value '*' or if the +object being accessed is defined in the module with the +specified module name. + + + + + + + This choice matches if all leafs present in the rule +match the request. If no leafs are present, the +choice matches all requests. + + + + + + + + + + This leaf matches if it has the value '*' or if + its value equals the requested protocol operation + name. + + + + + + + + + + This leaf matches if it has the value '*' or if its + value equals the requested notification name. + + + + + + + + Data node instance-identifier associated with the + data node, action, or notification controlled by + this rule. + + Configuration data or state data + instance-identifiers start with a top-level + data node. A complete instance-identifier is + required for this type of path value. + + The special value '/' refers to all possible + datastore contents. + + + + + + + + + + + Access operations associated with this rule. + +This leaf matches if it has the value '*' or if the +bit corresponding to the requested operation is set. + + + + + + + + The access control action associated with the +rule. If a rule has been determined to match a +particular request, then this object is used +to determine whether to permit or deny the +request. + + + + + + + A textual description of the access rule. + + + + + + diff --git a/yin/ietf-yang-types.yin b/yin/ietf-yang-types.yin new file mode 100644 index 0000000..15c3691 --- /dev/null +++ b/yin/ietf-yang-types.yin @@ -0,0 +1,480 @@ + + + + + + + IETF NETMOD (NETCONF Data Modeling Language) Working Group + + + WG Web: <http://tools.ietf.org/wg/netmod/> +WG List: <mailto:netmod@ietf.org> + +WG Chair: David Kessens + <mailto:david.kessens@nsn.com> + +WG Chair: Juergen Schoenwaelder + <mailto:j.schoenwaelder@jacobs-university.de> + +Editor: Juergen Schoenwaelder + <mailto:j.schoenwaelder@jacobs-university.de> + + + This module contains a collection of generally useful derived +YANG data types. + +Copyright (c) 2013 IETF Trust and the persons identified as +authors of the code. All rights reserved. + +Redistribution and use in source and binary forms, with or +without modification, is permitted pursuant to, and subject +to the license terms contained in, the Simplified BSD License +set forth in Section 4.c of the IETF Trust's Legal Provisions +Relating to IETF Documents +(http://trustee.ietf.org/license-info). + +This version of this YANG module is part of RFC 6991; see +the RFC itself for full legal notices. + + + + This revision adds the following new data types: +- yang-identifier +- hex-string +- uuid +- dotted-quad + + + RFC 6991: Common YANG Data Types + + + + + Initial revision. + + + RFC 6021: Common YANG Data Types + + + + + + The counter32 type represents a non-negative integer +that monotonically increases until it reaches a +maximum value of 2^32-1 (4294967295 decimal), when it +wraps around and starts increasing again from zero. + +Counters have no defined 'initial' value, and thus, a +single value of a counter has (in general) no information +content. Discontinuities in the monotonically increasing +value normally occur at re-initialization of the +management system, and at other times as specified in the +description of a schema node using this type. If such +other times can occur, for example, the creation of +a schema node of type counter32 at times other than +re-initialization, then a corresponding schema node +should be defined, with an appropriate type, to indicate +the last discontinuity. + +The counter32 type should not be used for configuration +schema nodes. A default statement SHOULD NOT be used in +combination with the type counter32. + +In the value set and its semantics, this type is equivalent +to the Counter32 type of the SMIv2. + + + RFC 2578: Structure of Management Information Version 2 + (SMIv2) + + + + + + + The zero-based-counter32 type represents a counter32 +that has the defined 'initial' value zero. + +A schema node of this type will be set to zero (0) on creation +and will thereafter increase monotonically until it reaches +a maximum value of 2^32-1 (4294967295 decimal), when it +wraps around and starts increasing again from zero. + +Provided that an application discovers a new schema node +of this type within the minimum time to wrap, it can use the +'initial' value as a delta. It is important for a management +station to be aware of this minimum time and the actual time +between polls, and to discard data if the actual time is too +long or there is no defined minimum time. + +In the value set and its semantics, this type is equivalent +to the ZeroBasedCounter32 textual convention of the SMIv2. + + + RFC 4502: Remote Network Monitoring Management Information + Base Version 2 + + + + + + The counter64 type represents a non-negative integer +that monotonically increases until it reaches a +maximum value of 2^64-1 (18446744073709551615 decimal), +when it wraps around and starts increasing again from zero. + +Counters have no defined 'initial' value, and thus, a +single value of a counter has (in general) no information +content. Discontinuities in the monotonically increasing +value normally occur at re-initialization of the +management system, and at other times as specified in the +description of a schema node using this type. If such +other times can occur, for example, the creation of +a schema node of type counter64 at times other than +re-initialization, then a corresponding schema node +should be defined, with an appropriate type, to indicate +the last discontinuity. + +The counter64 type should not be used for configuration +schema nodes. A default statement SHOULD NOT be used in +combination with the type counter64. + +In the value set and its semantics, this type is equivalent +to the Counter64 type of the SMIv2. + + + RFC 2578: Structure of Management Information Version 2 + (SMIv2) + + + + + + + The zero-based-counter64 type represents a counter64 that +has the defined 'initial' value zero. + + + + +A schema node of this type will be set to zero (0) on creation +and will thereafter increase monotonically until it reaches +a maximum value of 2^64-1 (18446744073709551615 decimal), +when it wraps around and starts increasing again from zero. + +Provided that an application discovers a new schema node +of this type within the minimum time to wrap, it can use the +'initial' value as a delta. It is important for a management +station to be aware of this minimum time and the actual time +between polls, and to discard data if the actual time is too +long or there is no defined minimum time. + +In the value set and its semantics, this type is equivalent +to the ZeroBasedCounter64 textual convention of the SMIv2. + + + RFC 2856: Textual Conventions for Additional High Capacity + Data Types + + + + + + The gauge32 type represents a non-negative integer, which +may increase or decrease, but shall never exceed a maximum +value, nor fall below a minimum value. The maximum value +cannot be greater than 2^32-1 (4294967295 decimal), and +the minimum value cannot be smaller than 0. The value of +a gauge32 has its maximum value whenever the information +being modeled is greater than or equal to its maximum +value, and has its minimum value whenever the information +being modeled is smaller than or equal to its minimum value. +If the information being modeled subsequently decreases +below (increases above) the maximum (minimum) value, the +gauge32 also decreases (increases). + +In the value set and its semantics, this type is equivalent +to the Gauge32 type of the SMIv2. + + + RFC 2578: Structure of Management Information Version 2 + (SMIv2) + + + + + + The gauge64 type represents a non-negative integer, which +may increase or decrease, but shall never exceed a maximum +value, nor fall below a minimum value. The maximum value +cannot be greater than 2^64-1 (18446744073709551615), and +the minimum value cannot be smaller than 0. The value of +a gauge64 has its maximum value whenever the information +being modeled is greater than or equal to its maximum +value, and has its minimum value whenever the information +being modeled is smaller than or equal to its minimum value. +If the information being modeled subsequently decreases +below (increases above) the maximum (minimum) value, the +gauge64 also decreases (increases). + +In the value set and its semantics, this type is equivalent +to the CounterBasedGauge64 SMIv2 textual convention defined +in RFC 2856 + + + RFC 2856: Textual Conventions for Additional High Capacity + Data Types + + + + + + + + The object-identifier type represents administratively +assigned names in a registration-hierarchical-name tree. + +Values of this type are denoted as a sequence of numerical +non-negative sub-identifier values. Each sub-identifier +value MUST NOT exceed 2^32-1 (4294967295). Sub-identifiers +are separated by single dots and without any intermediate +whitespace. + +The ASN.1 standard restricts the value space of the first +sub-identifier to 0, 1, or 2. Furthermore, the value space +of the second sub-identifier is restricted to the range +0 to 39 if the first sub-identifier is 0 or 1. Finally, +the ASN.1 standard requires that an object identifier +has always at least two sub-identifiers. The pattern +captures these restrictions. + +Although the number of sub-identifiers is not limited, +module designers should realize that there may be +implementations that stick with the SMIv2 limit of 128 +sub-identifiers. + +This type is a superset of the SMIv2 OBJECT IDENTIFIER type +since it is not restricted to 128 sub-identifiers. Hence, +this type SHOULD NOT be used to represent the SMIv2 OBJECT +IDENTIFIER type; the object-identifier-128 type SHOULD be +used instead. + + + ISO9834-1: Information technology -- Open Systems +Interconnection -- Procedures for the operation of OSI +Registration Authorities: General procedures and top +arcs of the ASN.1 Object Identifier tree + + + + + + + + This type represents object-identifiers restricted to 128 +sub-identifiers. + +In the value set and its semantics, this type is equivalent +to the OBJECT IDENTIFIER type of the SMIv2. + + + RFC 2578: Structure of Management Information Version 2 + (SMIv2) + + + + + + + + + + A YANG identifier string as defined by the 'identifier' +rule in Section 12 of RFC 6020. An identifier must +start with an alphabetic character or an underscore +followed by an arbitrary sequence of alphabetic or +numeric characters, underscores, hyphens, or dots. + +A YANG identifier MUST NOT start with any possible +combination of the lowercase or uppercase character +sequence 'xml'. + + + RFC 6020: YANG - A Data Modeling Language for the Network + Configuration Protocol (NETCONF) + + + + + + + + The date-and-time type is a profile of the ISO 8601 +standard for representation of dates and times using the +Gregorian calendar. The profile is defined by the +date-time production in Section 5.6 of RFC 3339. + +The date-and-time type is compatible with the dateTime XML +schema type with the following notable exceptions: + +(a) The date-and-time type does not allow negative years. + +(b) The date-and-time time-offset -00:00 indicates an unknown + time zone (see RFC 3339) while -00:00 and +00:00 and Z + all represent the same time zone in dateTime. + +(c) The canonical format (see below) of data-and-time values + differs from the canonical format used by the dateTime XML + schema type, which requires all times to be in UTC using + the time-offset 'Z'. + +This type is not equivalent to the DateAndTime textual +convention of the SMIv2 since RFC 3339 uses a different +separator between full-date and full-time and provides +higher resolution of time-secfrac. + +The canonical format for date-and-time values with a known time +zone uses a numeric time zone offset that is calculated using +the device's configured known offset to UTC time. A change of +the device's offset to UTC time will cause date-and-time values +to change accordingly. Such changes might happen periodically +in case a server follows automatically daylight saving time +(DST) time zone offset changes. The canonical format for +date-and-time values with an unknown time zone (usually +referring to the notion of local time) uses the time-offset +-00:00. + + + RFC 3339: Date and Time on the Internet: Timestamps +RFC 2579: Textual Conventions for SMIv2 +XSD-TYPES: XML Schema Part 2: Datatypes Second Edition + + + + + + The timeticks type represents a non-negative integer that +represents the time, modulo 2^32 (4294967296 decimal), in +hundredths of a second between two epochs. When a schema +node is defined that uses this type, the description of +the schema node identifies both of the reference epochs. + +In the value set and its semantics, this type is equivalent +to the TimeTicks type of the SMIv2. + + + RFC 2578: Structure of Management Information Version 2 + (SMIv2) + + + + + + The timestamp type represents the value of an associated +timeticks schema node at which a specific occurrence +happened. The specific occurrence must be defined in the +description of any schema node defined using this type. When +the specific occurrence occurred prior to the last time the +associated timeticks attribute was zero, then the timestamp +value is zero. Note that this requires all timestamp values +to be reset to zero when the value of the associated timeticks +attribute reaches 497+ days and wraps around to zero. + +The associated timeticks schema node must be specified +in the description of any schema node using this type. + +In the value set and its semantics, this type is equivalent +to the TimeStamp textual convention of the SMIv2. + + + RFC 2579: Textual Conventions for SMIv2 + + + + + + + + Represents media- or physical-level addresses represented +as a sequence octets, each octet represented by two hexadecimal +numbers. Octets are separated by colons. The canonical +representation uses lowercase characters. + +In the value set and its semantics, this type is equivalent +to the PhysAddress textual convention of the SMIv2. + + + RFC 2579: Textual Conventions for SMIv2 + + + + + + + + The mac-address type represents an IEEE 802 MAC address. +The canonical representation uses lowercase characters. + +In the value set and its semantics, this type is equivalent +to the MacAddress textual convention of the SMIv2. + + + IEEE 802: IEEE Standard for Local and Metropolitan Area + Networks: Overview and Architecture +RFC 2579: Textual Conventions for SMIv2 + + + + + + This type represents an XPATH 1.0 expression. + +When a schema node is defined that uses this type, the +description of the schema node MUST specify the XPath +context in which the XPath expression is evaluated. + + + XPATH: XML Path Language (XPath) Version 1.0 + + + + + + + + A hexadecimal string with octets represented as hex digits +separated by colons. The canonical representation uses +lowercase characters. + + + + + + + + A Universally Unique IDentifier in the string representation +defined in RFC 4122. The canonical representation uses +lowercase characters. + +The following is an example of a UUID in string representation: +f81d4fae-7dec-11d0-a765-00a0c91e6bf6 + + + + RFC 4122: A Universally Unique IDentifier (UUID) URN + Namespace + + + + + + + + An unsigned 32-bit number expressed in the dotted-quad +notation, i.e., four octets written as decimal numbers +and separated with the '.' (full stop) character. + + + diff --git a/yin/lmapd.yin b/yin/lmapd.yin new file mode 100644 index 0000000..a1b46cb --- /dev/null +++ b/yin/lmapd.yin @@ -0,0 +1,1118 @@ + + + + + + + + + + + + + + + + + + + + + + IETF Large-Scale Measurement of Broadband Performance +Working Group + + + WG Web: <https://datatracker.ietf.org/wg/lmap> +WG List: <mailto:lmap@ietf.org> + +Editor: Juergen Schoenwaelder + <j.schoenwaelder@jacobs-university.de> + +Editor: Vaibhav Bajpai + <bajpaiv@in.tum.de> + + + This module defines a data model for controlling Measurement +Agents that are part of a Large-Scale Measurement Platform +(LMAP). This data model is expected to be implemented by +Measurement Agents. + + + + Initial version + + + RFC 8194: A YANG Data Model for LMAP Measurement Agents + + + + + + + + This type is used by data models that need to reference +a configured event source. + + + + + + + + This type is used by data models that need to reference +a configured Task. + + + + + + + + This type is used by data models that need to reference +a configured Schedule. + + + + + A grouping that provides start and end times for +Event objects. + + + + + + The date and time when the Event object +starts to create triggers. + + + + + + + The date and time when the Event object +stops to create triggers. + +It is generally a good idea to always configure +an end time and to refresh the end time as needed +to ensure that agents that lose connectivity to +their Controller do not continue executing Schedules +forever. + + + + + + This grouping models a list of entries in a registry +that identify functions of a Task. + + + + + + + A list of entries in a registry identifying functions. + + + + + + A URI identifying an entry in a registry. + + + + + + + A set of roles for the identified registry entry. + + + + + + + A list of options of a Task. Each option is a name/value +pair (where the value may be absent). + + + + + + + + A list of options passed to the Task. It is a list of +key/value pairs and may be used to model options. +Options may be used to identify the role of a Task +or to pass a Channel name to a Task. + + + + + + An identifier uniquely identifying an option. This +identifier is required by YANG to uniquely identify +a name/value pair, but it otherwise has no semantic +value + + + + + + + The name of the option. + + + + + + + The value of the option. + + + + + + + + + + Configuration and control of a Measurement Agent. + + + + + + + Agent capabilities including a list of supported Tasks. + + + + + + + + A short description of the software implementing the +Measurement Agent. This should include the version +number of the Measurement Agent software. + + + + + + + + An optional unordered set of tags that provide +additional information about the capabilities of +the Measurement Agent. + + + + + + + A list of Tasks that the Measurement Agent supports. + + + + + + + The list of Tasks supported by the Measurement Agent. + + + + + + The unique name of a Task capability. + + + + + + + + A short description of the software implementing +the Task. This should include the version +number of the Measurement Task software. + + + + + + + The (local) program to invoke in order to execute +the Task. + + + + + + + + + + Configuration of parameters affecting the whole +Measurement Agent. + + + + + + The agent-id identifies a Measurement Agent with +a very low probability of collision. In certain +deployments, the agent-id may be considered +sensitive, and hence this object is optional. + + + + + + + The group-id identifies a group of Measurement +Agents. In certain deployments, the group-id +may be considered less sensitive than the +agent-id. + + + + + + + The measurement point indicating where the + Measurement Agent is located on a path. + + + RFC 7398: A Reference Path and Measurement Points + for Large-Scale Measurement of Broadband + Performance + + + + + + + + An agent-id must exist for this to be set +to true. + + + + + The 'report-agent-id' controls whether the +'agent-id' is reported to Collectors. + + + + + + + + A group-id must exist for this to be set +to true. + + + + + The 'report-group-id' controls whether the +'group-id' is reported to Collectors. + + + + + + + + A measurement-point must exist for this to be +set to true. + + + + + The 'report-measurement-point' controls whether +the 'measurement-point' is reported to Collectors. + + + + + + + + A timer is started after each successful contact +with a Controller. When the timer reaches the +controller-timeout, an event (controller-lost) is +raised indicating that connectivity to the Controller +has been lost. + + + + + + + + + The date and time the Measurement Agent last started. + + + + + + + + Configuration of LMAP Tasks. + + + + + + + The list of Tasks configured on the Measurement +Agent. Note that a configured Task MUST resolve to a +Task listed in the capabilities. Attempts to execute +a configured Task that is not listed in the capabilities +result in a runtime execution error. + + + + + + The unique name of a Task. + + + + + + + + + The (local) program to invoke in order to execute +the Task. If this leaf is not set, then the system +will try to identify a suitable program based on +the registry information present. + + + + + + + + A set of Task-specific tags that are reported +together with the measurement results to a Collector. +A tag can be used, for example, to carry the +Measurement Cycle ID. + + + + + + + + + Configuration of LMAP Schedules. Schedules control +which Tasks are executed by the LMAP implementation. + + + + + + + Configuration of a particular Schedule. + + + + + + The locally unique, administratively assigned name +for this Schedule. + + + + + + + + The event source controlling the start of the +scheduled Actions. + + + + + + + The event source controlling the graceful + forced termination of the scheduled Actions. + + + + + + + + The duration controlling the graceful forced + termination of the scheduled Actions. + + + + + + + + + The Actions of the Schedule are executed +sequentially. + + + + + + The Actions of the Schedule are executed +concurrently. + + + + + + The Actions of the Schedule are executed in a +pipelined mode. Output created by an Action is +passed as input to the subsequent Action. + + + + + + The execution mode of this Schedule determines in +which order the Actions of the Schedule are executed. + + + + + + + A set of Schedule-specific tags that are reported +together with the measurement results to a Collector. + + + + + + + A set of Suppression tags that are used to select +Schedules to be suppressed. + + + + + + + + + The value 'enabled' indicates that the +Schedule is currently enabled. + + + + + + The value 'disabled' indicates that the +Schedule is currently disabled. + + + + + + The value 'running' indicates that the +Schedule is currently running. + + + + + + The value 'suppressed' indicates that the +Schedule is currently suppressed. + + + + + + + The current state of the Schedule. + + + + + + + + + + The amount of secondary storage (e.g., allocated in a +file system) holding temporary data allocated to the +Schedule in bytes. This object reports the amount of +allocated physical storage and not the storage used +by logical data records. + + + + + + + + + Number of invocations of this Schedule. This counter +does not include suppressed invocations or invocations +that were prevented due to an overlap with a previous +invocation of this Schedule. + + + + + + + + + Number of suppressed executions of this Schedule. + + + + + + + + + Number of executions prevented due to overlaps with +a previous invocation of this Schedule. + + + + + + + + + Number of failed executions of this Schedule. A +failed execution is an execution where at least +one Action failed. + + + + + + + + The date and time of the last invocation of +this Schedule. + + + + + + + + An Action describes a Task that is invoked by the +Schedule. Multiple Actions are invoked according to +the execution-mode of the Schedule. + + + + + + The unique identifier for this Action. + + + + + + + + The Task invoked by this Action. + + + + + + + + A set of Schedules receiving the output produced +by this Action. The output is stored temporarily +since the Destination Schedules will in general +not be running when output is passed to them. The +behavior of an Action passing data to its own +Schedule is implementation specific. + +Data passed to a sequential or pipelined Schedule +is received by the Schedule's first Action. Data +passed to a parallel Schedule is received by all +Actions of the Schedule. + + + + + + + A set of Action-specific tags that are reported +together with the measurement results to a +Collector. + + + + + + + A set of Suppression tags that are used to select +Actions to be suppressed. + + + + + + + + + The value 'enabled' indicates that the +Action is currently enabled. + + + + + + The value 'disabled' indicates that the +Action is currently disabled. + + + + + + The value 'running' indicates that the +Action is currently running. + + + + + + The value 'suppressed' indicates that the +Action is currently suppressed. + + + + + + + The current state of the Action. + + + + + + + + + + The amount of secondary storage (e.g., allocated in a +file system) holding temporary data allocated to the +Schedule in bytes. This object reports the amount of +allocated physical storage and not the storage used +by logical data records. + + + + + + + + + Number of invocations of this Action. This counter +does not include suppressed invocations or invocations +that were prevented due to an overlap with a previous +invocation of this Action. + + + + + + + + + Number of suppressed executions of this Action. + + + + + + + + + Number of executions prevented due to overlaps with +a previous invocation of this Action. + + + + + + + + + Number of failed executions of this Action. + + + + + + + + + The date and time of the last invocation of +this Action. + + + + + + + + + The date and time of the last completion of +this Action. + + + + + + + + + The status code returned by the last execution of +this Action. + + + + + + + + + The status message produced by the last execution +of this Action. + + + + + + + + + The date and time of the last failed completion +of this Action. + + + + + + + + + The status code returned by the last failed +execution of this Action. + + + + + + + + + The status message produced by the last failed +execution of this Action. + + + + + + + + + + Suppression information to prevent Schedules or +certain Actions from starting. + + + + + + + Configuration of a particular Suppression. + + + + + + The locally unique, administratively assigned name +for this Suppression. + + + + + + + The event source controlling the start of the +Suppression period. + + + + + + + The event source controlling the end of the +Suppression period. If not present, Suppression +continues indefinitely. + + + + + + + A set of Suppression match patterns. The Suppression +will apply to all Schedules (and their Actions) that +have a matching value in their suppression-tags +and to all Actions that have a matching value in +their suppression-tags. + + + + + + + + If 'stop-running' is true, running Schedules and +Actions matching the Suppression will be terminated +when Suppression is activated. If 'stop-running' is +false, running Schedules and Actions will not be +affected if Suppression is activated. + + + + + + + + + The value 'enabled' indicates that the +Suppression is currently enabled. + + + + + + The value 'disabled' indicates that the +Suppression is currently disabled. + + + + + + The value 'active' indicates that the +Suppression is currently active. + + + + + + + The current state of the Suppression. + + + + + + + + + Configuration of LMAP events. + +Implementations may be forced to delay acting +upon the occurrence of events in the face of local +constraints. An Action triggered by an event +therefore should not rely on the accuracy +provided by the scheduler implementation. + + + + + + + The list of event sources configured on the +Measurement Agent. + + + + + + The unique name of an event source. + + + + + + + + This optional leaf adds a random spread to the +computation of the event's trigger time. The +random spread is a uniformly distributed random +number taken from the interval [0:random-spread]. + + + + + + + + The optional cycle-interval defines the duration +of the time interval in seconds that is used to +calculate cycle numbers. No cycle number is +calculated if the optional cycle-interval does +not exist. + + + + + + + Different types of events. + + + + + + + + + + + The number of seconds between two triggers + generated by this periodic timing object. + + + + + + + + A set of months at which this calendar timing + will trigger. The wildcard means all months. + + + + + + + + A set of days of the month at which this + calendar timing will trigger. The wildcard means + all days of a month. + + + + + + + + A set of weekdays at which this calendar timing + will trigger. The wildcard means all weekdays. + + + + + + + + A set of hours at which this calendar timing will + trigger. The wildcard means all hours of a day. + + + + + + + + A set of minutes at which this calendar timing + will trigger. The wildcard means all minutes of + an hour. + + + + + + + + A set of seconds at which this calendar timing + will trigger. The wildcard means all seconds of + a minute. + + + + + + + The time zone in which this calendar timing + object will be evaluated. If not present, + the system's local time zone will be used. + + + + + + + + This one-off timing object triggers once at + the configured date and time. + + + + + + + + This immediate Event object triggers immediately + when it is configured. + + + + + + + + This startup Event object triggers whenever the + Measurement Agent (re)starts. + + + + + + + + The controller-lost Event object triggers when + the connectivity to the Controller has been lost + for at least 'controller-timeout' seconds. + + + + + + + + The controller-connected Event object triggers + when the connectivity to the Controller has been + restored after it was lost for at least + 'controller-timeout' seconds. + + + + + + + diff --git a/yin/openwrt-network.yin b/yin/openwrt-network.yin new file mode 100644 index 0000000..9ba0f34 --- /dev/null +++ b/yin/openwrt-network.yin @@ -0,0 +1,662 @@ + + + + + + + + + + + + + + + Malte Granderath <m.granderath@jacobs-university.de> + + + + initial revision + + + + + + + + + + + + + + + + IPv6 prefix for device + + + + + + + + + + + + + Physical interface name + + + + + + + Type of interface + + + + + + + Enable spanning tree protocol + + + + + + + Enable creating empty bridge + + + + + + + Enable multicast_snooping + + + + + + + Enable mutlicast_queries + + + + + + + Override the MAC address of the interface + + + + + + + Override the default MTU of the interface + + + + + + + Bring up interface at boot + + + + + + + Enable or disable IPv6 + + + + + + + Specifies whether ip address, route, and optionally gateway are assigned to the interface +regardless of the link being active ('1') or only after the link has become active ('0'); + + + + + + + Enable or disable the interface + + + + + + + IPv4 routing table for this interface + + + + + + + IPv6 routing table for this interface + + + + + + + The protocol of the interface + + + + + + + Alias IP address + + + + + + + Alias Netmask + + + + + + + Default gateway + + + + + + + Broadcast address (autogenerated if not setup) + + + + + + + IPv6 address + + + + + + + IPv6 default gateway + + + + + + + list of dns servers + + + + + + + + + Selects the interface to attach to for stacked protocols + + + + + + + + + + + + + Specifies the fwmark + + + + + + + Specifies the incoming logical interface name + + + + + + + Specifies the outgoing logical interface name + + + + + + + Specifies the source subnet to match + + + + + + + Specifies the destination subnet to match + + + + + + + Specifies the TOS value to match in the IP headers + + + + + + + Inverts the meaning of match options + + + + + + + Declares the priority of the rule + + + + + + + The rule lookup target + + + + + + + The rule target is another rule with priority + + + + + + + + + + + + + + + Specifies the fwmark + + + + + + + Specifies the incoming logical interface name + + + + + + + Specifies the outgoing logical interface name + + + + + + + Specifies the source subnet to match + + + + + + + Specifies the destination subnet to match + + + + + + + Specifies the TOS value to match in the IP headers + + + + + + + Inverts the meaning of match options + + + + + + + Declares the priority of the rule + + + + + + + The rule lookup target + + + + + + + The rule target is another rule with priority + + + + + + + + + + + + + + + + + Name of rule + + + + + + + + Specifies the interface name this route belongs to + + + + + + + The target network address + + + + + + + The route netmask + + + + + + + The network gateway + + + + + + + Specifies the route metric to use + + + + + + + Specifies a MTU for this route + + + + + + + Specifies the table id to use for route + + + + + + + The preferred source address when sending to destinations + + + + + + + Enable gateway on link, even if gateway does not match any interface prefix + + + + + + + + + + + + + + + Name of rule + + + + + + + + Specifies the interface name this route belongs to + + + + + + + The target network address + + + + + + + The network gateway + + + + + + + Specifies the route metric to use + + + + + + + Specifies a MTU for this route + + + + + + + Specifies the table id to use for route + + + + + + + The preferred source address when sending to destinations + + + + + + + Enable gateway on link, even if gateway does not match any interface prefix + + + + + + + + + + + + + + + + + The name of the switch to configure + + + + + + + + + + + + + + + Mirror received packets from the mirror_source_port to the mirror_monitor_port + + + + + + + Mirror transmitted packets from the mirror_source_port to the mirror_monitor_port + + + + + + + Switch port to which the packets are mirrored + + + + + + + Switch port from which packets are mirrored + + + + + + + Adjust the address resolution table's aging time + + + + + + + + + + + + + + + + + + + The device to configure + + + + + + + The VLAN table index to configure + + + + + + + The VLAN tag number to use + + + + + + + List of port indices that should be associated with VLAN + + + + + + + + + + + The device to configure + + + + + + + The port index to configure + + + + + + + The port PVID + + + + + + + Enable power-saving features + + + + + + + + + + + + + diff --git a/yin/openwrt-system.yin b/yin/openwrt-system.yin new file mode 100644 index 0000000..4634ff3 --- /dev/null +++ b/yin/openwrt-system.yin @@ -0,0 +1,211 @@ + + + + + + + + + + + + Malte Granderath <m.granderath@jacobs-university.de> + + + + initial revision + + + + + + + + + + + The hostname of the system + + + + + + + Size of the kernel message buffer. + + + + + + + + + + Number between 1-8. The maximum log level for kernel messages to be logged to the +console. Only messages with a level lower than this will be printed to the console. +Higher level messages have lower log level number. Highest level messages are ones with +log level 0. If you want more verbose messages in console put conloglevel to 8 +if you want less messages lower conloglevel to 4 or even less. + + + + + + + + The minimum level for cron messages to be logged to syslog. 0 will print all debug messages, +8 will log command executions, and 9 or higher will only log error messages. + + + + + + + + The maximum log level for kernel messages to be logged to the console. Only messages with a level +lower than this will be printed to the console. Identical to conloglevel and will override it. + + + + + + + + Size of the log buffer of the “new” procd based system log, that is output by the logread command + + + + + + + File to write log messages to (type file). The default is to not write a log in a file. The most +often used location for a system log file is /var/log/messages. + + + + + + Hostname to send to remote syslog. If none is provided, the actual hostname is send. + + + + + + + IP address of a syslog server to which the log messages should be sent in addition to the local destination. + + + + + + + Port number of the remote syslog server + + + + + + + Adds a prefix to all log messages send over network + + + + + + + + + + Sets the protocol to use for the connection + + + + + + + + Enables remote logging. + + + + + + + + Size of the file or circular memory buffer in KiB. + + + + + + + + Use \0 instead of \n as trailer when using TCP. + + + + + + + + + Either circular or file. + + + + + + + + Path of the seed. Enables saving a new seed on each boot. + + + + + + + The time zone that date and time should be rendered in by default. + + + + + + + Only useful when using glibc and zoneinfo! + + + + + + + + + + + + + enable the ntp client + + + + + + + + + enable the timeserver + + + + + + + list of ntp servers + + + + diff --git a/yin/openwrt-uci-extension.yin b/yin/openwrt-uci-extension.yin new file mode 100644 index 0000000..06ec4cb --- /dev/null +++ b/yin/openwrt-uci-extension.yin @@ -0,0 +1,30 @@ + + + + + + Malte Granderath <m.granderath@jacobs-university.de> + + + + initial revision + + + + + + + + + + + + + + + + + + diff --git a/yin/restconf-example.yin b/yin/restconf-example.yin new file mode 100644 index 0000000..e92a55b --- /dev/null +++ b/yin/restconf-example.yin @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + name of the course + + + + + + + list of names of instructors + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/yin2json/yin2json.py b/yin2json/yin2json.py index 3424a55..9555437 100644 --- a/yin2json/yin2json.py +++ b/yin2json/yin2json.py @@ -23,7 +23,14 @@ "uint64": "UINT_64", "binary": "BINARY", "boolean": "BOOLEAN", - "decimal64": "DECIMAL_64" + "decimal64": "DECIMAL_64", + "enumeration": "ENUMERATION", + "union": "UNION", + "bits": "BITS", + "yang:xpath1.0": "STRING", + "counter32": "INT_32", + "leafref": "LEAF_REF", + "empty": "EMPTY" } @@ -55,7 +62,26 @@ def add_type(self, module_name, content): def get_types(self): return self.types - +class Grouping: + def __init__(self): + self.tree = {} + self.current_size = 0 + + def generate_name(self): + return "grouping{}".format(self.current_size) + + def add_grouping(self, name, value={}): + if name in self.tree: + print("Duplicate grouping: {}\nPlease check YANG model".format(name)) + return + self.tree[name] = value + self.current_size += 1 + + def find(self, name): + if name in self.tree: + return self.tree[name]["map"] + return None + def convert_yin_to_json(data): val = xmltodict.parse(data) return json.loads(json.dumps(val)) @@ -109,7 +135,7 @@ def extract_type_statements(generated, key, value, imported): "pattern": "^" + value["pattern"]["@value"] + "$" } if range_allowed(type_name) and "range" in value: - range_split = value["range"]["@value"].split("..", 1) + range_split = get_range(value["range"]["@value"].split("..", 1), type_name) type_name = { "leaf-type": type_name, "from": range_split[0], @@ -117,6 +143,51 @@ def extract_type_statements(generated, key, value, imported): } generated["leaf-type"] = type_name +def get_range(range_split, type_name): + if len(range_split) == 0: + return [0, 0] + try: + val1 = int(range_split[0]) + except ValueError: + val1 = get_min_or_max(range_split[0], type_name) + try: + val2 = int(range_split[1]) + except ValueError: + val2 = get_min_or_max(range_split[1], type_name) + return [val1, val2] + +def get_min_or_max(x, t): + if x == "max": + if t == "int8": + return (2**7)-1 + elif t == "int16": + return (2**15)-1 + elif t == "int32": + return (2**31)-1 + elif t == "int64": + return (2**63)-1 + elif t == "uint8": + return (2**8)-1 + elif t == "uint16": + return (2**16)-1 + elif t == "uint32": + return (2**32)-1 + else: + return (2**64)-1 + elif x == "min": + if t == "int8": + return -(2**7) + elif t == "int16": + return -(2**15) + elif t == "int32": + return -(2**31) + elif t == "int64": + return -(2**63) + else: + return 0 + else: + return 0 + def handle_typedef(typedefs): if isinstance(typedefs, dict): @@ -127,9 +198,15 @@ def handle_typedef(typedefs): "leaf-type": typedefs["type"]["@name"] } if converted["leaf-type"] == "string" and "pattern" in typedefs["type"]: - converted["pattern"] = "^" + typedefs["type"]["pattern"]["@value"] + "$" + if isinstance(typedefs["type"]["pattern"], list): + regex = "" + for val in typedefs["type"]["pattern"]: + regex += "({})|".format(val["@value"]) + converted["pattern"] = "^({})$".format(regex[:len(regex)-1]) + else: + converted["pattern"] = "^" + typedefs["type"]["pattern"]["@value"] + "$" if range_allowed(converted["leaf-type"]) and "range" in typedefs["type"]: - range_split = typedefs["type"]["range"]["@value"].split("..", 1) + range_split = get_range(typedefs["type"]["range"]["@value"].split("..", 1), converted["leaf-type"]) converted["from"] = range_split[0] converted["to"] = range_split[1] types[typedefs["@name"]] = converted @@ -138,20 +215,50 @@ def handle_typedef(typedefs): handle_typedef(item) -def process_node(generated, key, value, imported): +def process_node(generated, key, value, imported, groupings): if isinstance(value, dict): inner_key = value["@name"] if "mandatory" in value and value["mandatory"]["@value"] == "true": if not ("mandatory" in generated): generated["mandatory"] = [] generated["mandatory"].append(inner_key) - generated["map"][inner_key] = convert(value, imported, key) + generated["map"][inner_key] = convert(value, imported, groupings, key) elif isinstance(value, list): for inner_value in value: - process_node(generated, key, inner_value, imported) + process_node(generated, key, inner_value, imported, groupings) - -def convert(level, imported, object_type=None): +def handle_grouping(value, imported, groupings): + if isinstance(value, dict): + grouping_name = "" + if "@name" in value: + grouping_name = value["@name"] + else: + grouping_name = groupings.generate_name() + groupings.add_grouping(grouping_name, convert(value, imported, groupings, "grouping")) + elif isinstance(value, list): + for val in value: + handle_grouping(val, imported, groupings) + +def extract_uses(generated, value, imported, groupings): + if isinstance(value, list): + for val in value: + extract_uses(generated, val, imported, groupings) + return + if "@name" not in value: + print("Invalid use of 'uses': {}".format(value)) + return + name = value["@name"] + grouping = groupings.find(name) + if grouping == None: + print("Could not find {} in groupings".format(name)) + return + for key, val in grouping.items(): + if key in generated["map"].keys(): + print("A node with name '{}' already exists".format(key)) + continue + generated["map"][key] = val + +def convert(level, imported, groupings, object_type=None): generated = {} changed_level = level if len(changed_level) == 1 and "module" in changed_level: @@ -166,6 +273,8 @@ def convert(level, imported, object_type=None): generated["map"] = {} for key, value in changed_level.items(): extract_uci_statements(generated, key, value, imported) + if key == "grouping": + handle_grouping(value, imported, groupings) if key == "type": extract_type_statements(generated, key, value, imported) if key == "key": @@ -177,7 +286,9 @@ def convert(level, imported, object_type=None): to_be_split = value["@value"] generated["unique"] = to_be_split.split() if key in ["container", "leaf", "leaf-list", "list"]: - process_node(generated, key, value, imported) + process_node(generated, key, value, imported, groupings) + if key == "uses": + extract_uses(generated, value, imported, groupings) return generated @@ -207,7 +318,7 @@ def process_imported_types(args, imported): else: converted["pattern"].append("^" + item["type"]["pattern"]["@value"] + "$") if range_allowed(converted["leaf-type"]) and "range" in item["type"]: - range_split = item["type"]["range"]["@value"].split("..", 1) + range_split = get_range(item["type"]["range"]["@value"].split("..", 1), converted["leaf-type"]) converted["from"] = range_split[0] converted["to"] = range_split[1] types[val["type_name"]] = converted @@ -228,8 +339,9 @@ def main(): with open(file) as yin: data = yin.read() js = convert_yin_to_json(data) + groupings = Grouping() imported = Imported() - js = convert(js, imported) + js = convert(js, imported, groupings) modules.append((os.path.basename(file).split('.')[0], js)) process_imported_types(args, imported)