33 * @author Michal Vasko <[email protected] > 44 * @author Radek Krejci <[email protected] > 55 * @author Adam Piecek <[email protected] > 6+ * @author Juraj Budai <[email protected] > 67 * @brief 'data' command of the libyang's yanglint tool.
78 *
89 * Copyright (c) 2015-2023 CESNET, z.s.p.o.
@@ -68,7 +69,9 @@ cmd_data_help_type(void)
6869 " element without <eventTime>).\n"
6970 " nc-notif - Similar to 'notif' but expect and check also the NETCONF\n"
7071 " envelope <notification> with element <eventTime> and its\n"
71- " sibling as the actual notification.\n" );
72+ " sibling as the actual notification.\n"
73+ " ext - Validates extension data based on loaded YANG modules.\n"
74+ " Need to be used with -k parameter.\n" );
7275}
7376
7477static void
@@ -139,7 +142,12 @@ cmd_data_help(void)
139142 " existence is also checked in these operational data.\n"
140143 " -R FILE, --reply-rpc=FILE\n"
141144 " Provide source RPC for parsing of the 'nc-reply' TYPE. The FILE\n"
142- " is supposed to contain the source 'nc-rpc' operation of the reply.\n" );
145+ " is supposed to contain the source 'nc-rpc' operation of the reply.\n"
146+ " -k, --ext-inst <name>\n"
147+ " Name of extension instance in format:\n"
148+ " <module-name>:<extension-name>:<argument>\n"
149+ " -i --ext\n"
150+ " Validates extension data based on loaded YANG modules\n" );
143151 cmd_data_help_format ();
144152 cmd_data_help_in_format ();
145153 printf (" -o OUTFILE, --output=OUTFILE\n"
@@ -166,6 +174,7 @@ cmd_data_opt(struct yl_opt *yo, const char *cmdline, char ***posv, int *posc)
166174 {"not-strict" , no_argument , NULL , 'n' },
167175 {"type" , required_argument , NULL , 't' },
168176 {"xpath" , required_argument , NULL , 'x' },
177+ {"ext-inst" , required_argument , NULL , 'k' },
169178 {NULL , 0 , NULL , 0 }
170179 };
171180
@@ -255,6 +264,12 @@ cmd_data_opt(struct yl_opt *yo, const char *cmdline, char ***posv, int *posc)
255264 return 1 ;
256265 }
257266 break ;
267+ case 'k' : /* --ext-id */
268+ if (parse_ext_string (optarg , yo )) {
269+ YLMSG_E ("Invalid name of extension instance." );
270+ return 1 ;
271+ }
272+ break ;
258273
259274 case 'h' : /* --help */
260275 cmd_data_help ();
@@ -346,6 +361,23 @@ cmd_data_dep(struct yl_opt *yo, int posc)
346361 }
347362 }
348363
364+ if (yo -> data_ext && !yo -> mod_name ) {
365+ if (yo -> interactive ) {
366+ YLMSG_E ("When using '-i' the '-k' parameter need to be also set." );
367+ } else {
368+ YLMSG_E ("When using '-t ext' the '-k' parameter need to be also set." );
369+ }
370+ return 1 ;
371+ }
372+ if (!yo -> data_ext && yo -> mod_name ) {
373+ if (yo -> interactive ) {
374+ YLMSG_E ("When using '-k' parameter the '-i' need to be also set." );
375+ } else {
376+ YLMSG_E ("When using '-k' parameter the '-t ext' need to be also set." );
377+ }
378+ return 1 ;
379+ }
380+
349381 return 0 ;
350382}
351383
@@ -417,6 +449,35 @@ evaluate_xpath(const struct lyd_node *tree, const char *xpath)
417449 return 0 ;
418450}
419451
452+ int
453+ parse_ext_string (const char * extension_instance , struct yl_opt * yo )
454+ {
455+ const char * start = extension_instance ;
456+ char * end ;
457+
458+ end = strchr (start , ':' );
459+ if (!end ) {
460+ return -1 ;
461+ }
462+ yo -> mod_name = strndup (start , end - start );
463+ start = end + 1 ;
464+
465+ end = strchr (start , ':' );
466+ if (!end ) {
467+ return -1 ;
468+ }
469+ yo -> name = strndup (start , end - start );
470+ start = end + 1 ;
471+
472+ if (* start == '\0' ) {
473+ return -1 ;
474+ }
475+
476+ yo -> argument = strdup (start );
477+
478+ return 0 ;
479+ }
480+
420481/**
421482 * @brief Checking that a parent data node exists in the datastore for the nested-notification and action.
422483 *
@@ -672,14 +733,72 @@ process_data(struct ly_ctx *ctx, enum lyd_type type, uint8_t merge, LYD_FORMAT o
672733 return ret ;
673734}
674735
736+ /**
737+ * @brief Iterate trough modules to find extension instance
738+ *
739+ * @param[in] ctx libyang context with schema.
740+ * @param[in] yo context for yanglint.
741+ *
742+ * @return 0 on success.
743+ */
744+ static int
745+ find_extension (struct ly_ctx * ctx , struct yl_opt * yo )
746+ {
747+ struct lys_module * module ;
748+ uint32_t idx = 0 ;
749+ LY_ARRAY_COUNT_TYPE i ;
750+
751+ while ((module = ly_ctx_get_module_iter (ctx , & idx ))) {
752+ if (!strcmp (module -> name , yo -> mod_name )) {
753+ break ;
754+ }
755+ }
756+
757+ if (!module ) {
758+ YLMSG_E ("Cannot find the \"%s\" name in yang modules." , yo -> name );
759+ return 1 ;
760+ }
761+
762+ /* get the extension from module that user is looking for */
763+ LY_ARRAY_FOR (module -> compiled -> exts , i ) {
764+ if (!strcmp (module -> compiled -> exts [i ].def -> name , yo -> name ) &&
765+ !strcmp (module -> compiled -> exts [i ].argument , yo -> argument )) {
766+ yo -> ext = & module -> compiled -> exts [i ];
767+ return 0 ;
768+ }
769+ }
770+ return 1 ;
771+ }
772+
675773int
676774cmd_data_process (struct ly_ctx * ctx , struct yl_opt * yo )
677775{
678- /* parse, validate and print data */
679- if (process_data (ctx , yo -> data_type , yo -> data_merge , yo -> data_out_format , yo -> out , yo -> data_parse_options ,
680- yo -> data_validate_options , yo -> data_print_options , & yo -> data_operational , & yo -> reply_rpc ,
681- & yo -> data_inputs , & yo -> data_xpath )) {
682- return 1 ;
776+ if (yo -> data_ext ) {
777+ struct lyd_node * tree ;
778+ struct cmdline_file * input_f ;
779+
780+ if (find_extension (ctx , yo )) {
781+ YLMSG_E ("Extension '%s:%s:%s' not found in module." , yo -> mod_name , yo -> name , yo -> argument );
782+ return 1 ;
783+ }
784+
785+ input_f = (struct cmdline_file * )yo -> data_inputs .objs [0 ];
786+
787+ if (lyd_parse_ext_data (yo -> ext , NULL , input_f -> in , input_f -> format , 0 , 0 , & tree )) {
788+ YLMSG_E ("Parsing of extension data failed." )
789+ return 1 ;
790+ }
791+
792+ lyd_free_all (tree );
793+ yo -> data_ext = 0 ;
794+
795+ } else {
796+ /* parse, validate and print data */
797+ if (process_data (ctx , yo -> data_type , yo -> data_merge , yo -> data_out_format , yo -> out , yo -> data_parse_options ,
798+ yo -> data_validate_options , yo -> data_print_options , & yo -> data_operational , & yo -> reply_rpc ,
799+ & yo -> data_inputs , & yo -> data_xpath )) {
800+ return 1 ;
801+ }
683802 }
684803
685804 return 0 ;
0 commit comments