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-id <name>\n"
147+ " Name of extension instance in format:\n"
148+ " <prefix>:<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,8 @@ 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-id" , required_argument , NULL , 'k' },
178+ {"ext" , no_argument , NULL , 'i' },
169179 {NULL , 0 , NULL , 0 }
170180 };
171181
@@ -255,6 +265,15 @@ cmd_data_opt(struct yl_opt *yo, const char *cmdline, char ***posv, int *posc)
255265 return 1 ;
256266 }
257267 break ;
268+ case 'k' : /* --ext-id */
269+ if (parse_ext_string (optarg , yo )) {
270+ YLMSG_E ("Invalid name of extension instance." );
271+ return 1 ;
272+ }
273+ break ;
274+ case 'i' : /* --ext */
275+ yo -> data_ext = 1 ;
276+ break ;
258277
259278 case 'h' : /* --help */
260279 cmd_data_help ();
@@ -346,6 +365,23 @@ cmd_data_dep(struct yl_opt *yo, int posc)
346365 }
347366 }
348367
368+ if (yo -> data_ext && !yo -> prefix ) {
369+ if (yo -> interactive ) {
370+ YLMSG_E ("When using '-i' the '-k' parameter need to be also set." );
371+ } else {
372+ YLMSG_E ("When using '-t ext' the '-k' parameter need to be also set." );
373+ }
374+ return 1 ;
375+ }
376+ if (!yo -> data_ext && yo -> prefix ) {
377+ if (yo -> interactive ) {
378+ YLMSG_E ("When using '-k' parameter the '-i' need to be also set." );
379+ } else {
380+ YLMSG_E ("When using '-k' parameter the '-t ext' need to be also set." );
381+ }
382+ return 1 ;
383+ }
384+
349385 return 0 ;
350386}
351387
@@ -417,6 +453,34 @@ evaluate_xpath(const struct lyd_node *tree, const char *xpath)
417453 return 0 ;
418454}
419455
456+ int
457+ parse_ext_string (char * extension_name , struct yl_opt * yo )
458+ {
459+ char * token = strtok (extension_name , ":" );
460+
461+ if (token ) {
462+ yo -> prefix = strdup (token );
463+ token = strtok (NULL , ":" );
464+ } else {
465+ return -1 ;
466+ }
467+
468+ if (token ) {
469+ yo -> name = strdup (token );
470+ token = strtok (NULL , ":" );
471+ } else {
472+ return -1 ;
473+ }
474+
475+ if (token ) {
476+ yo -> argument = strdup (token );
477+ } else {
478+ return -1 ;
479+ }
480+
481+ return 0 ;
482+ }
483+
420484/**
421485 * @brief Checking that a parent data node exists in the datastore for the nested-notification and action.
422486 *
@@ -675,11 +739,53 @@ process_data(struct ly_ctx *ctx, enum lyd_type type, uint8_t merge, LYD_FORMAT o
675739int
676740cmd_data_process (struct ly_ctx * ctx , struct yl_opt * yo )
677741{
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 ;
742+ if (yo -> data_ext ) {
743+ struct lyd_node * tree = NULL ;
744+ struct cmdline_file * input_f = NULL ;
745+ struct lys_module * module = NULL ;
746+ uint32_t idx = 0 ;
747+
748+ while ((module = ly_ctx_get_module_iter (ctx , & idx ))) {
749+ if (!strcmp (module -> prefix , yo -> prefix )) {
750+ break ;
751+ }
752+ }
753+
754+ if (!module ) {
755+ YLMSG_E ("Cannot find the \"%s\" prefix in yang modules." , yo -> prefix );
756+ return 1 ;
757+ }
758+
759+ /* get the extension from module that user is looking for */
760+ for (size_t i = 0 ; i < LY_ARRAY_COUNT (module -> compiled -> exts ); ++ i ) {
761+ if (!strcmp (module -> compiled -> exts [i ].def -> name , yo -> name ) &&
762+ !strcmp (module -> compiled -> exts [i ].argument , yo -> argument )) {
763+ yo -> ext = & module -> compiled -> exts [i ];
764+ break ;
765+ }
766+ }
767+
768+ if (!yo -> ext ) {
769+ YLMSG_E ("Extension '%s:%s:%s' not found in module '%s'." , yo -> prefix , yo -> name , yo -> argument , module -> name );
770+ return 1 ;
771+ }
772+
773+ input_f = (struct cmdline_file * )yo -> data_inputs .objs [0 ];
774+
775+ if (lyd_parse_ext_data (yo -> ext , NULL , input_f -> in , input_f -> format , 0 , 0 , & tree )) {
776+ YLMSG_E ("Parsing of extension data failed." )
777+ }
778+
779+ lyd_free_all (tree );
780+ yo -> data_ext = 0 ;
781+
782+ } else {
783+ /* parse, validate and print data */
784+ if (process_data (ctx , yo -> data_type , yo -> data_merge , yo -> data_out_format , yo -> out , yo -> data_parse_options ,
785+ yo -> data_validate_options , yo -> data_print_options , & yo -> data_operational , & yo -> reply_rpc ,
786+ & yo -> data_inputs , & yo -> data_xpath )) {
787+ return 1 ;
788+ }
683789 }
684790
685791 return 0 ;
0 commit comments