Closed medometo closed 3 years ago
So, I have done some more research and I think the issue is related to how the isinstance(value, str)
function checks for type string in Python 2 vs Python 3.
I tried two solutions to solve this.
Solution 1) Do a check of Python version in which I split the below code section:
527 elif var_type == "choice":
528 if not isinstance(value, str):
529 self._raise_value_error(var_name, "is not a string")
530 choices = self._get_required_field(var_schema, "choices")
531 upper_choices = [x.upper() for x in choices]
532 if value.upper() in upper_choices:
533 return True
534 else:
535 self._raise_value_error(var_name, "is not a valid choice")
and replace it with the following code in which I use isinstance(value, str)
in Python 3 and use isinstance(value, unicode)
in Python 2:
527 elif var_type == "choice" and sys.version_info == (3,):
528 if not isinstance(value, str):
529 self._raise_value_error(var_name, "is not a string")
530 choices = self._get_required_field(var_schema, "choices")
531 upper_choices = [x.upper() for x in choices]
532 if value.upper() in upper_choices:
533 return True
534 else:
535 self._raise_value_error(var_name, "is not a valid choice")
536 elif var_type == "choice" and sys.version_info < (3,):
537 if not isinstance(value, unicode):
538 self._raise_value_error(var_name, "is not a string")
539 choices = self._get_required_field(var_schema, "choices")
540 upper_choices = [x.upper() for x in choices]
541 if value.upper() in upper_choices:
542 return True
543 else:
544 self._raise_value_error(var_name, "is not a valid choice")
Solution 2) Follow the recommendation mentioned here, and use the six library to be both Python 2 and Python 3 compatible using one piece of code.
And this is by: a) Importing the six library:
import six
b) Rreplacing the following code (using isinstance(value, str)
):
527 elif var_type == "choice":
528 if not isinstance(value, str):
529 self._raise_value_error(var_name, "is not a string")
530 choices = self._get_required_field(var_schema, "choices")
531 upper_choices = [x.upper() for x in choices]
532 if value.upper() in upper_choices:
533 return True
534 else:
535 self._raise_value_error(var_name, "is not a valid choice")
with the following code; using isinstance(value, six.string_types)
528 elif var_type == "choice":
529 if not isinstance(value, six.string_types):
530 self._raise_value_error(var_name, "is not a string")
531 choices = self._get_required_field(var_schema, "choices")
532 upper_choices = [x.upper() for x in choices]
533 if value.upper() in upper_choices:
534 return True
535 else:
536 self._raise_value_error(var_name, "is not a valid choice")
Both solutions were tested successfully with the following templates that include different "string" choice var_type (of course while keeping the type of the variable as "choice" in the yml template file, i.e., no workaround as previously mentioned in the original comment reporting the issue):
@mpiecuch-nuage Please have a look...
Thank you for going far above and beyond with your debugging and analysis. I am using your solution with the six library and retrofitting it for the regular string case as well since it is a better solution. The fix has been merged in the following PR and will be released in MetroAE Config v1.1.
https://github.com/nuagenetworks/nuage-metroae-config/pull/43
First of all, I'm very sorry I opened this issue in the nuage-metroae project instead of nuage-metroae-config. I will close it over there and keep it here only.
I have noticed in two occasions that a template variable of type "choice" which is actually a string causes an error when the value of the variable is set in the Excel file/template.
The two occasions that I have tested are:
1) When creating a Policy Group using an Excel template and select the "Policy group type" from the drop-down list (for example setting it to "SOFTWARE"), will cause an error when validating or creating the Policy Group.
_A workaround is to modify the "policy_group_type" variable type in
standard-templates/templates/policy_group.yml
to "string" instead of "choice":_Now the validation/creation succeeds:
2) Similarly, when creating an L3 Domain using an Excel template and select the "Underlay enabled" attribute from the drop-down list (for example setting it to "ENABLED"), will cause an error when validating or creating the L3 Domain. Similar error is given like in the case of policy group type.
If we set the "underlay_enabled" variable in
standard-templates/templates/l3_domain.yml
to "string" instead of "choice", the validation/creation succeeds.I know the above workarounds are just a "desperate man's" workaround and are unlikely to be the solution.
While looking at the code in
source/nuage-metroae-config/nuage_metroae_config/template.py
, I suspect that the issue is related to the part checking that var of type "choice" is a string in Python 3 usingisinstance(value, str)
. I'm not a programmer, so I can be totally wrong.