-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Missing container in list support in YANG Model #16704 #18091
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
f5d17c7
bc3f6ec
8d3c0f3
77a1bbc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -378,10 +378,17 @@ def _createLeafDict(self, model, table): | |
| #choices, this is tricky, since leafs are under cases in tree. | ||
| choices = model.get('choice') | ||
| if choices: | ||
| for choice in choices: | ||
| cases = choice['case'] | ||
| # If single choice exists in container/list | ||
| if isinstance(choices, dict): | ||
| cases = choices['case'] | ||
| for case in cases: | ||
| self._fillLeafDict(case.get('leaf'), leafDict) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The 2 lines are duplicated, you may consider reusing. #Closed
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are right, but throughout the code every time, there are separation between single element (dict) and multiple (list), they are handled separately.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no easy way to reuse. |
||
| # If multiple choices exist in container/list | ||
| else: | ||
| for choice in choices: | ||
| cases = choice['case'] | ||
| for case in cases: | ||
| self._fillLeafDict(case.get('leaf'), leafDict) | ||
|
|
||
| # leaf-lists | ||
| self._fillLeafDict(model.get('leaf-list'), leafDict, True) | ||
|
|
@@ -535,6 +542,29 @@ def _xlateType1MapList(self, model, yang, config, table, exceptionList): | |
| continue | ||
| return | ||
|
|
||
| """ | ||
| Process container inside a List. | ||
| This function will call xlateContainer based on Container(s) present | ||
| in outer List. | ||
| """ | ||
| def _xlateContainerInList(self, model, yang, configC, table): | ||
| ccontainer = model | ||
| ccName = ccontainer['@name'] | ||
| if ccName not in configC: | ||
| # Inner container doesn't exist in config | ||
| return | ||
|
|
||
| if len(configC[ccName]) == 0: | ||
VladimirKuk marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| # Empty container - return | ||
| return | ||
|
|
||
| self.sysLog(msg="xlateProcessListOfContainer: {}".format(ccName)) | ||
| self.elementPath.append(ccName) | ||
| self._xlateContainer(ccontainer, yang, configC[ccName], table) | ||
| self.elementPath.pop() | ||
|
|
||
| return | ||
|
|
||
| """ | ||
| Xlate a list | ||
| This function will xlate from a dict in config DB to a Yang JSON list | ||
|
|
@@ -553,6 +583,9 @@ def _xlateList(self, model, yang, config, table, exceptionList): | |
| self._xlateType1MapList(model, yang, config, table, exceptionList) | ||
| return | ||
|
|
||
| # For handling of container(s) in list | ||
| ccontainer = model.get('container') | ||
|
|
||
| #create a dict to map each key under primary key with a dict yang model. | ||
| #This is done to improve performance of mapping from values of TABLEs in | ||
| #config DB to leaf in YANG LIST. | ||
|
|
@@ -572,6 +605,19 @@ def _xlateList(self, model, yang, config, table, exceptionList): | |
| keyDict = self._extractKey(pkey, listKeys) | ||
| # fill rest of the values in keyDict | ||
| for vKey in config[pkey]: | ||
| if ccontainer and vKey == ccontainer['@name']: | ||
| self.sysLog(syslog.LOG_DEBUG, "xlateList Handle container {} in list {}".\ | ||
| format(vKey, table)) | ||
| yangContainer = dict() | ||
| if isinstance(ccontainer, dict) and bool(config): | ||
| self._xlateContainerInList(ccontainer, yangContainer, config[pkey], table) | ||
| # If multi-list exists in container, | ||
| elif ccontainer and isinstance(ccontainer, list) and bool(config): | ||
| for modelContainer in ccontainer: | ||
| self._xlateContainerInList(modelContainer, yangContainer, config[pkey], table) | ||
| if len(yangContainer): | ||
| keyDict[vKey] = yangContainer | ||
| continue | ||
| self.elementPath.append(vKey) | ||
| self.sysLog(syslog.LOG_DEBUG, "xlateList vkey {}".format(vKey)) | ||
| try: | ||
|
|
@@ -876,6 +922,9 @@ def _revXlateList(self, model, yang, config, table): | |
| self._revXlateType1MapList(model, yang, config, table) | ||
| return | ||
|
|
||
| # For handling of container(s) in list | ||
| ccontainer = model.get('container') | ||
|
|
||
| # get keys from YANG model list itself | ||
| listKeys = model['key']['@value'] | ||
| # create a dict to map each key under primary key with a dict yang model. | ||
|
|
@@ -894,6 +943,17 @@ def _revXlateList(self, model, yang, config, table): | |
| # fill rest of the entries | ||
| for key in entry: | ||
| if key not in pkeydict: | ||
| if ccontainer and key == ccontainer['@name']: | ||
VladimirKuk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| self.sysLog(syslog.LOG_DEBUG, "revXlateList handle container {} in list {}".format(pkey, table)) | ||
| # IF container has only one inner container | ||
| if isinstance(ccontainer, dict): | ||
| self._revXlateContainerInContainer(ccontainer, entry, config[pkey], table) | ||
| # IF container has many inner container | ||
| elif isinstance(ccontainer, list): | ||
| for modelContainer in ccontainer: | ||
| self._revXlateContainerInContainer(modelContainer, entry, config[pkey], table) | ||
| continue | ||
|
|
||
| self.elementPath.append(key) | ||
| config[pkey][key] = self._revFindYangTypedValue(key, \ | ||
| entry[key], leafDict) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,105 @@ | ||
| module test-yang-structure { | ||
|
|
||
| namespace "http://github.com/sonic-net/test"; | ||
| prefix yangstructtest; | ||
|
|
||
| yang-version 1.1; | ||
|
|
||
| import ietf-yang-types { | ||
| prefix yang; | ||
| } | ||
|
|
||
| import ietf-inet-types { | ||
| prefix inet; | ||
| } | ||
|
|
||
| import test-head { | ||
| prefix head; | ||
| revision-date 2019-07-01; | ||
| } | ||
|
|
||
| revision 2021-10-30 { | ||
| description "First Revision"; | ||
| } | ||
|
|
||
| container test-yang-container { | ||
|
|
||
| container YANG_STRUCT_TEST { | ||
|
|
||
| description "sample test container"; | ||
|
|
||
| list YANG_LIST_TEST_LIST { | ||
|
|
||
| key "name"; | ||
|
|
||
| leaf name { | ||
| type string; | ||
| } | ||
|
|
||
| leaf-list leaf-list-test { | ||
| description "Test leaf-list statement"; | ||
| type inet:ipv6-address; | ||
| } | ||
|
|
||
| container container-in-list-test { | ||
| leaf leaf-1 { | ||
| description "test leaf in container"; | ||
| type string { | ||
| pattern "false|true"; | ||
| } | ||
| } | ||
|
|
||
| leaf leaf-2 { | ||
| description "test leaf in container"; | ||
| type string; | ||
| } | ||
|
|
||
| choice multi-choice-in-container-test-1 { | ||
| case mc-case-test-1 { | ||
| leaf mc-case-leaf-1 { | ||
| description "test leaf in multi choice"; | ||
| type uint32; | ||
| } | ||
| } | ||
|
|
||
| case mc-case-test-2 { | ||
| leaf mc-case-leaf-2 { | ||
| description "test leaf in multi choice"; | ||
| type uint8; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| choice multi-choice-in-container-test-2 { | ||
| case mc-case-test-3 { | ||
| leaf mc-case-leaf-3 { | ||
| description "test leaf in multi choice"; | ||
| type uint16; | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| choice single-choice-in-list-test { | ||
| case case-test-1 { | ||
| leaf case-leaf-1 { | ||
| description "test leaf in single choice"; | ||
| type uint32; | ||
| } | ||
| } | ||
|
|
||
| case case-test-2 { | ||
| leaf case-leaf-2 { | ||
| description "test leaf in single choice"; | ||
| type uint16; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| /* end of YANG_LIST_TEST_LIST */ | ||
| } | ||
| /* end of container YANG_STRUCT_TEST */ | ||
| } | ||
| /* end of container test-yang-container */ | ||
| } | ||
| /* end of module test-yang-structure */ |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible that 'case' is not in choices dict? will it throw? #Closed
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My understanding that this should be validated by libyang. Since the choice is already checked, at least one case must be present otherwise yang file won't be valid.