Skip to content

Commit

Permalink
[Core] aaz: Feature Atomic Azure Command support argument validation (
Browse files Browse the repository at this point in the history
#23126)

* add argument formats

* add test for AAZStrArgFormat

* Use OrderedDict for _fields of AAZObjectType

* test and fix base argument formats

* fix bug with None value

* add test for AAZResourceLocationArgFormat

* add test for AAZResourceIdArgFormat

* add test for AAZSubscriptionIdArgFormat

* fix style issues

* fix test issues

* move test into resource module

* fix style issue
  • Loading branch information
kairu-ms authored Jul 7, 2022
1 parent 99731af commit 6347220
Show file tree
Hide file tree
Showing 12 changed files with 1,761 additions and 39 deletions.
2 changes: 2 additions & 0 deletions src/azure-cli-core/azure/cli/core/aaz/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
from ._arg import has_value, AAZArgumentsSchema, AAZArgEnum, AAZStrArg, AAZIntArg, AAZObjectArg, AAZDictArg, \
AAZFloatArg, AAZBaseArg, AAZBoolArg, AAZListArg, AAZResourceGroupNameArg, AAZResourceLocationArg, \
AAZResourceIdArg, AAZSubscriptionIdArg
from ._arg_fmt import AAZStrArgFormat, AAZIntArgFormat, AAZFloatArgFormat, AAZBoolArgFormat, AAZObjectArgFormat, \
AAZDictArgFormat, AAZListArgFormat, AAZResourceLocationArgFormat, AAZResourceIdArgFormat, AAZSubscriptionIdArgFormat
from ._base import AAZValuePatch, AAZUndefined
from ._command import AAZCommand, AAZCommandGroup, register_command, register_command_group, load_aaz_command_table
from ._field_type import AAZIntType, AAZFloatType, AAZStrType, AAZBoolType, AAZDictType, AAZListType, AAZObjectType
Expand Down
44 changes: 29 additions & 15 deletions src/azure-cli-core/azure/cli/core/aaz/_arg.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,19 @@
from ._field_type import AAZObjectType, AAZStrType, AAZIntType, AAZBoolType, AAZFloatType, AAZListType, AAZDictType, \
AAZSimpleType
from ._field_value import AAZObject
from ._arg_fmt import AAZObjectArgFormat, AAZListArgFormat, AAZDictArgFormat, AAZSubscriptionIdArgFormat, \
AAZResourceLocationArgFormat, AAZResourceIdArgFormat

# pylint: disable=redefined-builtin, protected-access


class AAZArgumentsSchema(AAZObjectType):
""" Arguments' schema should be defined as fields of it """

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._fmt = AAZObjectArgFormat()

def __call__(self, data=None):
return AAZObject(
schema=self,
Expand Down Expand Up @@ -64,7 +70,7 @@ class AAZBaseArg(AAZBaseType): # pylint: disable=too-many-instance-attributes
"""Base argument"""

def __init__(self, options=None, required=False, help=None, arg_group=None, is_preview=False, is_experimental=False,
id_part=None, default=AAZUndefined, blank=AAZUndefined, nullable=False):
id_part=None, default=AAZUndefined, blank=AAZUndefined, nullable=False, fmt=None):
"""
:param options: argument optional names.
Expand All @@ -78,6 +84,7 @@ def __init__(self, options=None, required=False, help=None, arg_group=None, is_p
:param default: when the argument flag is not appeared, the default value will be used.
:param blank: when the argument flag is used without value data, the blank value will be used.
:param nullable: argument can accept `None` as value
:param fmt: argument format
"""
super().__init__(options=options, nullable=nullable)
self._help = {} # the key in self._help can be 'name', 'short-summary', 'long-summary', 'populator-commands'
Expand All @@ -96,6 +103,7 @@ def __init__(self, options=None, required=False, help=None, arg_group=None, is_p
self._id_part = id_part
self._default = default
self._blank = blank
self._fmt = fmt

def to_cmd_arg(self, name):
""" convert AAZArg to CLICommandArgument """
Expand Down Expand Up @@ -133,10 +141,9 @@ def _type_in_help(self):
class AAZSimpleTypeArg(AAZBaseArg, AAZSimpleType):
"""Argument accept simple value"""

def __init__(self, enum=None, enum_case_sensitive=False, fmt=None, **kwargs):
def __init__(self, enum=None, enum_case_sensitive=False, **kwargs):
super().__init__(**kwargs)
self.enum = AAZArgEnum(enum, case_sensitive=enum_case_sensitive) if enum else None
self._fmt = fmt

def to_cmd_arg(self, name):
arg = super().to_cmd_arg(name)
Expand Down Expand Up @@ -213,8 +220,8 @@ def to_cmd_arg(self, name):
class AAZObjectArg(AAZCompoundTypeArg, AAZObjectType):

def __init__(self, fmt=None, **kwargs):
super().__init__(**kwargs)
self._fmt = fmt
fmt = fmt or AAZObjectArgFormat()
super().__init__(fmt=fmt, **kwargs)

def to_cmd_arg(self, name):
arg = super().to_cmd_arg(name)
Expand All @@ -238,8 +245,8 @@ def _type_in_help(self):
class AAZDictArg(AAZCompoundTypeArg, AAZDictType):

def __init__(self, fmt=None, **kwargs):
super().__init__(**kwargs)
self._fmt = fmt
fmt = fmt or AAZDictArgFormat()
super().__init__(fmt=fmt, **kwargs)

def to_cmd_arg(self, name):
arg = super().to_cmd_arg(name)
Expand All @@ -263,8 +270,8 @@ def _type_in_help(self):
class AAZListArg(AAZCompoundTypeArg, AAZListType):

def __init__(self, fmt=None, singular_options=None, **kwargs):
super().__init__(**kwargs)
self._fmt = fmt
fmt = fmt or AAZListArgFormat()
super().__init__(fmt=fmt, **kwargs)
self.singular_options = singular_options

def to_cmd_arg(self, name):
Expand Down Expand Up @@ -324,11 +331,13 @@ def __init__(
self, options=('--location', '-l'),
help="Location. Values from: `az account list-locations`. "
"You can configure the default location using `az configure --defaults location=<location>`.",
fmt=None,
**kwargs):
super(AAZResourceLocationArg, self).__init__(
fmt = fmt or AAZResourceLocationArgFormat()
super().__init__(
options=options,
help=help,
fmt=None, # TODO: add ResourceLocation Format, which can transform value with space
fmt=fmt,
**kwargs
)

Expand All @@ -348,25 +357,30 @@ def to_cmd_arg(self, name):

class AAZResourceIdArg(AAZStrArg):
"""ResourceId Argument"""
# TODO: Resource Id arg can support both name and id. And can construct id from name by ResourceId Format

def __init__(self, fmt=None, **kwargs):
fmt = fmt or AAZResourceIdArgFormat()
super().__init__(fmt=fmt, **kwargs)


class AAZSubscriptionIdArg(AAZStrArg):

def __init__(
self, help="Name or ID of subscription.",
self, help="Name or ID of subscription. You can configure the default subscription "
"using `az account set -s NAME_OR_ID`",
fmt=None,
**kwargs):
fmt = fmt or AAZSubscriptionIdArgFormat()
super().__init__(
help=help,
fmt=None, # TODO: add format, which can transform name to subscription id
fmt=fmt,
**kwargs
)

def to_cmd_arg(self, name):
from azure.cli.core._completers import get_subscription_id_list
arg = super().to_cmd_arg(name)
arg.completer = get_subscription_id_list

return arg


Expand Down
Loading

0 comments on commit 6347220

Please sign in to comment.