@@ -9,7 +9,13 @@ class OpenAPIRequestArg:
99 """
1010
1111 def __init__ (
12- self , name , schema , required , prefix = None , list_parent = None
12+ self ,
13+ name ,
14+ schema ,
15+ required ,
16+ prefix = None ,
17+ is_parent = False ,
18+ parent = None ,
1319 ): # pylint: disable=too-many-arguments
1420 """
1521 Parses a single Schema node into a argument the CLI can use when making
@@ -23,6 +29,10 @@ def __init__(
2329 :param prefix: The prefix for this arg's path, used in the actual argument
2430 to the CLI to ensure unique arg names
2531 :type prefix: str
32+ :param is_parent: Whether this argument is a parent to child fields.
33+ :type is_parent: bool
34+ :param parent: If applicable, the path to the parent list for this argument.
35+ :type parent: Optional[str]
2636 """
2737 #: The name of this argument, mostly used for display and docs
2838 self .name = name
@@ -50,6 +60,11 @@ def __init__(
5060 schema .extensions .get ("linode-cli-format" ) or schema .format or None
5161 )
5262
63+ # If this is a deeply nested array we should treat it as JSON.
64+ # This allows users to specify fields like --interfaces.ip_ranges.
65+ if is_parent or (schema .type == "array" and parent is not None ):
66+ self .format = "json"
67+
5368 #: The type accepted for this argument. This will ultimately determine what
5469 #: we accept in the ArgumentParser
5570 self .datatype = (
@@ -59,13 +74,16 @@ def __init__(
5974 #: The type of item accepted in this list; if None, this is not a list
6075 self .item_type = None
6176
62- #: Whether the argument is a field in a nested list.
63- self .list_item = list_parent is not None
77+ #: Whether the argument is a parent to child fields.
78+ self .is_parent = is_parent
79+
80+ #: Whether the argument is a nested field.
81+ self .is_child = parent is not None
6482
6583 #: The name of the list this argument falls under.
6684 #: This allows nested dictionaries to be specified in lists of objects.
6785 #: e.g. --interfaces.ipv4.nat_1_1
68- self .list_parent = list_parent
86+ self .parent = parent
6987
7088 #: The path of the path element in the schema.
7189 self .prefix = prefix
@@ -85,7 +103,7 @@ def __init__(
85103 )
86104
87105
88- def _parse_request_model (schema , prefix = None , list_parent = None ):
106+ def _parse_request_model (schema , prefix = None , parent = None ):
89107 """
90108 Parses a schema into a list of OpenAPIRequest objects
91109 :param schema: The schema to parse as a request model
@@ -107,8 +125,11 @@ def _parse_request_model(schema, prefix=None, list_parent=None):
107125 if v .type == "object" and not v .readOnly and v .properties :
108126 # nested objects receive a prefix and are otherwise parsed normally
109127 pref = prefix + "." + k if prefix else k
128+
110129 args += _parse_request_model (
111- v , prefix = pref , list_parent = list_parent
130+ v ,
131+ prefix = pref ,
132+ parent = parent ,
112133 )
113134 elif (
114135 v .type == "array"
@@ -119,9 +140,20 @@ def _parse_request_model(schema, prefix=None, list_parent=None):
119140 # handle lists of objects as a special case, where each property
120141 # of the object in the list is its own argument
121142 pref = prefix + "." + k if prefix else k
122- args += _parse_request_model (
123- v .items , prefix = pref , list_parent = pref
143+
144+ # Support specifying this list as JSON
145+ args .append (
146+ OpenAPIRequestArg (
147+ k ,
148+ v .items ,
149+ False ,
150+ prefix = prefix ,
151+ is_parent = True ,
152+ parent = parent ,
153+ )
124154 )
155+
156+ args += _parse_request_model (v .items , prefix = pref , parent = pref )
125157 else :
126158 # required fields are defined in the schema above the property, so
127159 # we have to check here if required fields are defined/if this key
@@ -131,7 +163,7 @@ def _parse_request_model(schema, prefix=None, list_parent=None):
131163 required = k in schema .required
132164 args .append (
133165 OpenAPIRequestArg (
134- k , v , required , prefix = prefix , list_parent = list_parent
166+ k , v , required , prefix = prefix , parent = parent
135167 )
136168 )
137169
0 commit comments