From 5873dc8139fb5431bf8bc5ee9278817564d5b982 Mon Sep 17 00:00:00 2001 From: Graeme Campbell Date: Mon, 30 Sep 2024 14:11:11 +1300 Subject: [PATCH] Add support for common yang-library code between restconf and netconf This changes moves the yang-library code to the apteryx-xml repo, so that both netconf and restconf can use it as shared library code. --- Makefile.am | 14 +- internal.h | 1 - models/ietf-datastores.yang | 117 -------- models/ietf-yang-library.yang | 544 ---------------------------------- rest.c | 3 +- yang-library.c | 120 -------- 6 files changed, 5 insertions(+), 794 deletions(-) delete mode 100644 models/ietf-datastores.yang delete mode 100644 models/ietf-yang-library.yang diff --git a/Makefile.am b/Makefile.am index 5273ed2..8cf3659 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,25 +3,19 @@ apteryx_rest_SOURCES = main.c fcgi.c rest.c yang-library.c rpc.c api_html.c logg apteryx_rest_CFLAGS = @LIBFCGI_CFLAGS@ @APTERYX_XML_CFLAGS@ @JANSSON_CFLAGS@ @LIBXML2_CFLAGS@ @LUA_CFLAGS@ @APTERYX_CFLAGS@ @GLIB_CFLAGS@ apteryx_rest_LDADD = @LIBFCGI_LIBS@ @APTERYX_XML_LIBS@ @JANSSON_LIBS@ @LIBXML2_LIBS@ @LUA_LIBS@ @APTERYX_LIBS@ @GLIB_LIBS@ -EXTRA_DIST = models/ietf-yang-library.yang models/ietf-restconf-monitoring.yang -BUILT_SOURCES = models/ietf-yang-library.h models/ietf-restconf-monitoring.h models/ietf-yang-library.xml models/ietf-restconf-monitoring.xml api_html.c +EXTRA_DIST = models/ietf-restconf-monitoring.yang +BUILT_SOURCES = models/ietf-restconf-monitoring.h models/ietf-restconf-monitoring.xml api_html.c CLEANFILES = $(BUILT_SOURCES) -include_HEADERS = models/ietf-yang-library.h models/ietf-restconf-monitoring.h +include_HEADERS = models/ietf-restconf-monitoring.h schemadir = $(destdir)/etc/apteryx/schema -schema_DATA = models/ietf-yang-library.xml models/ietf-restconf-monitoring.xml +schema_DATA = models/ietf-restconf-monitoring.xml api_html.c: api.html Makefile @echo '__asm__(".align 8; .global api_html; api_html: .incbin \"api.html\"; .byte 0;");' > api_html.c -models/ietf-yang-library.h: models/ietf-yang-library.yang - $(PYANG) -p . -f cpaths -o $@ $< - models/ietf-restconf-monitoring.h: models/ietf-restconf-monitoring.yang $(PYANG) -p . -f cpaths -o $@ $< -models/ietf-yang-library.xml: models/ietf-yang-library.yang - $(PYANG) -p . -f apteryx-xml $< > $@ - models/ietf-restconf-monitoring.xml: models/ietf-restconf-monitoring.yang $(PYANG) -p . -f apteryx-xml $< > $@ diff --git a/internal.h b/internal.h index 7d7ae0b..631c427 100644 --- a/internal.h +++ b/internal.h @@ -116,7 +116,6 @@ void rest_api (req_handle handle, int flags, const char *rpath, const char *path const char *remote_addr, const char *remote_user, const char *data, int length); void rest_shutdown (void); -void yang_library_create (sch_instance *schema); void restconf_monitoring_create (sch_instance *schema); /* RPC */ diff --git a/models/ietf-datastores.yang b/models/ietf-datastores.yang deleted file mode 100644 index 9e875ab..0000000 --- a/models/ietf-datastores.yang +++ /dev/null @@ -1,117 +0,0 @@ -module ietf-datastores { - yang-version 1.1; - namespace "urn:ietf:params:xml:ns:yang:ietf-datastores"; - prefix ds; - - organization - "IETF Network Modeling (NETMOD) Working Group"; - - contact - "WG Web: - - WG List: - - Author: Martin Bjorklund - - - Author: Juergen Schoenwaelder - - - Author: Phil Shafer - - - Author: Kent Watsen - - - Author: Rob Wilton - "; - - description - "This YANG module defines a set of identities for identifying - datastores. - - Copyright (c) 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 8342 - (https://www.rfc-editor.org/info/rfc8342); see the RFC itself - for full legal notices."; - - revision 2018-02-14 { - description - "Initial revision."; - reference - "RFC 8342: Network Management Datastore Architecture (NMDA)"; - } - - /* - * Identities - */ - - identity datastore { - description - "Abstract base identity for datastore identities."; - } - - identity conventional { - base datastore; - description - "Abstract base identity for conventional configuration - datastores."; - } - - identity running { - base conventional; - description - "The running configuration datastore."; - } - - identity candidate { - base conventional; - description - "The candidate configuration datastore."; - } - - identity startup { - base conventional; - description - "The startup configuration datastore."; - } - - identity intended { - base conventional; - description - "The intended configuration datastore."; - } - - identity dynamic { - base datastore; - description - "Abstract base identity for dynamic configuration datastores."; - } - - identity operational { - base datastore; - description - "The operational state datastore."; - } - - /* - * Type definitions - */ - - typedef datastore-ref { - type identityref { - base datastore; - } - description - "A datastore identity reference."; - } -} diff --git a/models/ietf-yang-library.yang b/models/ietf-yang-library.yang deleted file mode 100644 index dac53a1..0000000 --- a/models/ietf-yang-library.yang +++ /dev/null @@ -1,544 +0,0 @@ -module ietf-yang-library { - yang-version 1.1; - namespace "urn:ietf:params:xml:ns:yang:ietf-yang-library"; - prefix yanglib; - - import ietf-yang-types { - prefix yang; - reference - "RFC 6991: Common YANG Data Types"; - } - import ietf-inet-types { - prefix inet; - reference - "RFC 6991: Common YANG Data Types"; - } - import ietf-datastores { - prefix ds; - reference - "RFC 8342: Network Management Datastore Architecture - (NMDA)"; - } - - organization - "IETF NETCONF (Network Configuration) Working Group"; - contact - "WG Web: - WG List: - - Author: Andy Bierman - - - Author: Martin Bjorklund - - - Author: Juergen Schoenwaelder - - - Author: Kent Watsen - - - Author: Robert Wilton - "; - description - "This module provides information about the YANG modules, - datastores, and datastore schemas used by a network - management server. - The key words 'MUST', 'MUST NOT', 'REQUIRED', 'SHALL', 'SHALL - NOT', 'SHOULD', 'SHOULD NOT', 'RECOMMENDED', 'NOT RECOMMENDED', - 'MAY', and 'OPTIONAL' in this document are to be interpreted as - described in BCP 14 (RFC 2119) (RFC 8174) when, and only when, - they appear in all capitals, as shown here. - - Copyright (c) 2019 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 8525; see - the RFC itself for full legal notices."; - - revision 2019-01-04 { - description - "Added support for multiple datastores according to the - Network Management Datastore Architecture (NMDA)."; - reference - "RFC 8525: YANG Library"; - } - revision 2016-04-09 { - description - "Initial revision."; - reference - "RFC 7895: YANG Module Library"; - } - - /* - * Typedefs - */ - - typedef revision-identifier { - type string { - pattern '\d{4}-\d{2}-\d{2}'; - } - description - "Represents a specific date in YYYY-MM-DD format."; - } - - /* - * Groupings - */ - grouping module-identification-leafs { - description - "Parameters for identifying YANG modules and submodules."; - leaf name { - type yang:yang-identifier; - mandatory true; - description - "The YANG module or submodule name."; - } - leaf revision { - type revision-identifier; - description - "The YANG module or submodule revision date. If no revision - statement is present in the YANG module or submodule, this - leaf is not instantiated."; - } - } - - grouping location-leaf-list { - description - "Common leaf-list parameter for the locations of modules and - submodules."; - leaf-list location { - type inet:uri; - description - "Contains a URL that represents the YANG schema - resource for this module or submodule. - - This leaf will only be present if there is a URL - available for retrieval of the schema for this entry."; - } - } - - grouping module-implementation-parameters { - description - "Parameters for describing the implementation of a module."; - leaf-list feature { - type yang:yang-identifier; - description - "List of all YANG feature names from this module that are - supported by the server, regardless whether they are defined - in the module or any included submodule."; - } - leaf-list deviation { - type leafref { - path "../../module/name"; - } - - description - "List of all YANG deviation modules used by this server to - modify the conformance of the module associated with this - entry. Note that the same module can be used for deviations - for multiple modules, so the same entry MAY appear within - multiple 'module' entries. - - This reference MUST NOT (directly or indirectly) - refer to the module being deviated. - - Robust clients may want to make sure that they handle a - situation where a module deviates itself (directly or - indirectly) gracefully."; - } - } - - grouping module-set-parameters { - description - "A set of parameters that describe a module set."; - leaf name { - type string; - description - "An arbitrary name of the module set."; - } - list module { - key "name"; - description - "An entry in this list represents a module implemented by the - server, as per Section 5.6.5 of RFC 7950, with a particular - set of supported features and deviations."; - reference - "RFC 7950: The YANG 1.1 Data Modeling Language"; - uses module-identification-leafs; - leaf namespace { - type inet:uri; - mandatory true; - description - "The XML namespace identifier for this module."; - } - uses location-leaf-list; - list submodule { - key "name"; - description - "Each entry represents one submodule within the - parent module."; - uses module-identification-leafs; - uses location-leaf-list; - } - uses module-implementation-parameters; - } - list import-only-module { - key "name revision"; - description - "An entry in this list indicates that the server imports - reusable definitions from the specified revision of the - module but does not implement any protocol-accessible - objects from this revision. - - Multiple entries for the same module name MAY exist. This - can occur if multiple modules import the same module but - specify different revision dates in the import statements."; - leaf name { - type yang:yang-identifier; - description - "The YANG module name."; - } - leaf revision { - type union { - type revision-identifier; - type string { - length "0"; - } - } - description - "The YANG module revision date. - A zero-length string is used if no revision statement - is present in the YANG module."; - } - leaf namespace { - type inet:uri; - mandatory true; - description - "The XML namespace identifier for this module."; - } - uses location-leaf-list; - list submodule { - key "name"; - description - "Each entry represents one submodule within the - parent module."; - uses module-identification-leafs; - uses location-leaf-list; - } - } - } - - grouping yang-library-parameters { - description - "The YANG library data structure is represented as a grouping - so it can be reused in configuration or another monitoring - data structure."; - list module-set { - key "name"; - description - "A set of modules that may be used by one or more schemas. - - A module set does not have to be referentially complete, - i.e., it may define modules that contain import statements - for other modules not included in the module set."; - uses module-set-parameters; - } - list schema { - key "name"; - description - "A datastore schema that may be used by one or more - datastores. - - The schema must be valid and referentially complete, i.e., - it must contain modules to satisfy all used import - statements for all modules specified in the schema."; - leaf name { - type string; - description - "An arbitrary name of the schema."; - } - leaf-list module-set { - type leafref { - path "../../module-set/name"; - } - description - "A set of module-sets that are included in this schema. - If a non-import-only module appears in multiple module - sets, then the module revision and the associated features - and deviations must be identical."; - } - } - list datastore { - key "name"; - description - "A datastore supported by this server. - - Each datastore indicates which schema it supports. - - The server MUST instantiate one entry in this list per - specific datastore it supports. - Each datastore entry with the same datastore schema SHOULD - reference the same schema."; - leaf name { - type ds:datastore-ref; - description - "The identity of the datastore."; - } - leaf schema { - type leafref { - path "../../schema/name"; - } - mandatory true; - description - "A reference to the schema supported by this datastore. - All non-import-only modules of the schema are implemented - with their associated features and deviations."; - } - } - } - - /* - * Top-level container - */ - - container yang-library { - config false; - description - "Container holding the entire YANG library of this server."; - uses yang-library-parameters; - leaf content-id { - type string; - mandatory true; - description - "A server-generated identifier of the contents of the - '/yang-library' tree. The server MUST change the value of - this leaf if the information represented by the - '/yang-library' tree, except '/yang-library/content-id', has - changed."; - } - } - - /* - * Notifications - */ - - notification yang-library-update { - description - "Generated when any YANG library information on the - server has changed."; - leaf content-id { - type leafref { - path "/yanglib:yang-library/yanglib:content-id"; - } - mandatory true; - description - "Contains the YANG library content identifier for the updated - YANG library at the time the notification is generated."; - } - } - - /* - * Legacy groupings - */ - - grouping module-list { - status deprecated; - description - "The module data structure is represented as a grouping - so it can be reused in configuration or another monitoring - data structure."; - - grouping common-leafs { - status deprecated; - description - "Common parameters for YANG modules and submodules."; - leaf name { - type yang:yang-identifier; - status deprecated; - description - "The YANG module or submodule name."; - } - leaf revision { - type union { - type revision-identifier; - type string { - length "0"; - } - } - status deprecated; - description - "The YANG module or submodule revision date. - A zero-length string is used if no revision statement - is present in the YANG module or submodule."; - } - } - - grouping schema-leaf { - status deprecated; - description - "Common schema leaf parameter for modules and submodules."; - leaf schema { - type inet:uri; - description - "Contains a URL that represents the YANG schema - resource for this module or submodule. - - This leaf will only be present if there is a URL - available for retrieval of the schema for this entry."; - } - } - list module { - key "name revision"; - status deprecated; - description - "Each entry represents one revision of one module - currently supported by the server."; - uses common-leafs { - status deprecated; - } - uses schema-leaf { - status deprecated; - } - leaf namespace { - type inet:uri; - mandatory true; - status deprecated; - description - "The XML namespace identifier for this module."; - } - leaf-list feature { - type yang:yang-identifier; - status deprecated; - description - "List of YANG feature names from this module that are - supported by the server, regardless of whether they are - defined in the module or any included submodule."; - } - list deviation { - key "name revision"; - status deprecated; - - description - "List of YANG deviation module names and revisions - used by this server to modify the conformance of - the module associated with this entry. Note that - the same module can be used for deviations for - multiple modules, so the same entry MAY appear - within multiple 'module' entries. - - The deviation module MUST be present in the 'module' - list, with the same name and revision values. - The 'conformance-type' value will be 'implement' for - the deviation module."; - uses common-leafs { - status deprecated; - } - } - leaf conformance-type { - type enumeration { - enum implement { - description - "Indicates that the server implements one or more - protocol-accessible objects defined in the YANG module - identified in this entry. This includes deviation - statements defined in the module. - - For YANG version 1.1 modules, there is at most one - 'module' entry with conformance type 'implement' for a - particular module name, since YANG 1.1 requires that - at most one revision of a module is implemented. - - For YANG version 1 modules, there SHOULD NOT be more - than one 'module' entry for a particular module - name."; - } - enum import { - description - "Indicates that the server imports reusable definitions - from the specified revision of the module but does - not implement any protocol-accessible objects from - this revision. - - Multiple 'module' entries for the same module name MAY - exist. This can occur if multiple modules import the - same module but specify different revision dates in - the import statements."; - } - } - mandatory true; - status deprecated; - description - "Indicates the type of conformance the server is claiming - for the YANG module identified by this entry."; - } - list submodule { - key "name revision"; - status deprecated; - description - "Each entry represents one submodule within the - parent module."; - uses common-leafs { - status deprecated; - } - uses schema-leaf { - status deprecated; - } - } - } - } - - /* - * Legacy operational state data nodes - */ - - container modules-state { - config false; - status deprecated; - description - "Contains YANG module monitoring information."; - leaf module-set-id { - type string; - mandatory true; - status deprecated; - description - "Contains a server-specific identifier representing - the current set of modules and submodules. The - server MUST change the value of this leaf if the - information represented by the 'module' list instances - has changed."; - } - uses module-list { - status deprecated; - } - } - - /* - * Legacy notifications - */ - - notification yang-library-change { - status deprecated; - description - "Generated when the set of modules and submodules supported - by the server has changed."; - leaf module-set-id { - type leafref { - path "/yanglib:modules-state/yanglib:module-set-id"; - } - mandatory true; - status deprecated; - description - "Contains the module-set-id value representing the - set of modules and submodules supported at the server - at the time the notification is generated."; - } - } -} diff --git a/rest.c b/rest.c index f501ff8..613958c 100644 --- a/rest.c +++ b/rest.c @@ -1968,13 +1968,12 @@ rest_init (const char *path) g_boottime += (monotime.tv_sec - monotime_raw.tv_sec); /* Load Data Models */ - g_schema = sch_load (path); + g_schema = sch_load_model_list_yang_library (path); if (!g_schema) { return false; } - yang_library_create (g_schema); restconf_monitoring_create (g_schema); /* Register with the YANG condition parser */ diff --git a/yang-library.c b/yang-library.c index e117ba9..7bffde0 100644 --- a/yang-library.c +++ b/yang-library.c @@ -17,15 +17,8 @@ * along with this program. If not, see . */ #include "internal.h" -#include "models/ietf-yang-library.h" #include "models/ietf-restconf-monitoring.h" -/* Name for the set of modules */ -#define MODULES_STR "modules" -#define SCHEMA_STR "schema" -#define DATASTORE_STR "datastore" -#define COMMON_STR "common" - /* List of supported capabilities. This is hard-coded for now, if we add a * capability in the code, we need to update this table. Null terminate it * for ease of traversal. @@ -89,119 +82,6 @@ add_leaf_strdup (GNode *root, const char *node_name, const char *value) return NULL; } -/** - * Add an entry to the apteryx database for each model known to resconf - * - * @param root - The node the leaf will be added to - */ -static void -schema_set_model_information (sch_instance *schema, GNode *root) -{ - GNode *gnode; - sch_loaded_model *loaded; - GList *list; - GList *loaded_models = sch_get_loaded_models (schema); - - for (list = g_list_first (loaded_models); list; list = g_list_next (list)) - { - loaded = list->data; - - if (loaded->model && strlen (loaded->model)) - { - gnode = add_leaf_strdup (root, YANG_LIBRARY_MODULE_SET_MODULE_PATH, - loaded->model); - - add_leaf_strdup (gnode, MODULES_STATE_MODULE_NAME, loaded->model); - if (loaded->version) - { - add_leaf_strdup (gnode, MODULES_STATE_MODULE_REVISION, - loaded->version); - } - if (loaded->ns_href) - { - add_leaf_strdup (gnode, MODULES_STATE_MODULE_NAMESPACE, loaded->ns_href); - } - if (loaded->features) - { - gchar **split; - int count; - int i; - - split = g_strsplit (loaded->features, ",", 0); - count = g_strv_length (split); - for (i = 0; i < count; i++) - { - char *feature_path; - feature_path = - g_strdup_printf ("%s/%s", YANG_LIBRARY_MODULE_SET_MODULE_FEATURE, split[i]); - add_leaf_strdup (gnode, feature_path, split[i]); - g_free (feature_path); - } - g_strfreev (split); - } - if (loaded->deviations) - { - gchar **split; - int count; - int i; - - split = g_strsplit (loaded->deviations, ",", 0); - count = g_strv_length (split); - for (i = 0; i < count; i++) - { - char *deviation_path; - deviation_path = - g_strdup_printf ("%s/%s", YANG_LIBRARY_MODULE_SET_MODULE_DEVIATION, split[i]); - add_leaf_strdup (gnode, deviation_path, split[i]); - g_free (deviation_path); - } - g_strfreev (split); - } - } - } -} - -/** - * Given a schema create the Apteryx data for the ietf-yang-library model required - * by restconf. - * - * @param g_schema - The root schema xml node - */ -void -yang_library_create (sch_instance *schema) -{ - GNode *root; - GNode *modules; - GNode *datastore; - GNode *tmp; - GNode *sch_tmp; - time_t now = time (NULL); - char set_id[24]; - - root = APTERYX_NODE (NULL, g_strdup (YANG_LIBRARY_PATH)); - modules = add_leaf_strdup (root, YANG_LIBRARY_SCHEMA_MODULE_SET, COMMON_STR); - add_leaf_strdup (modules, YANG_LIBRARY_MODULE_SET_NAME, COMMON_STR); - schema_set_model_information (schema, modules); - - tmp = add_leaf_strdup (root, SCHEMA_STR, SCHEMA_STR); - add_leaf_strdup (tmp, YANG_LIBRARY_SCHEMA_NAME, COMMON_STR); - sch_tmp = add_leaf_strdup (tmp, YANG_LIBRARY_SCHEMA_MODULE_SET, COMMON_STR); - add_leaf_strdup (sch_tmp, COMMON_STR, COMMON_STR); - - - datastore = add_leaf_strdup (root, DATASTORE_STR, DATASTORE_STR); - add_leaf_strdup (datastore, YANG_LIBRARY_DATASTORE_NAME, "ietf-datastores:running"); - add_leaf_strdup (datastore, YANG_LIBRARY_DATASTORE_SCHEMA, COMMON_STR); - - apteryx_set_tree (root); - apteryx_free_tree (root); - - /* Each time this routine is run the content-id will be set to a unique id based - * on the clock */ - snprintf (set_id, sizeof (set_id), "%" PRIx64 "", now); - apteryx_set (YANG_LIBRARY_CONTENT_ID, set_id); -} - /** * Create the Apteryx data for the ietf-restconf-monitoring model required by restconf. *