linode-cli 5.56.2__tar.gz → 5.56.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {linode_cli-5.56.2/linode_cli.egg-info → linode_cli-5.56.3}/PKG-INFO +1 -1
- {linode_cli-5.56.2 → linode_cli-5.56.3/linode_cli.egg-info}/PKG-INFO +1 -1
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/baked/request.py +25 -13
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/baked/response.py +25 -3
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/configuration/config.py +16 -34
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/configuration/helpers.py +1 -3
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/version.py +1 -1
- {linode_cli-5.56.2 → linode_cli-5.56.3}/LICENSE +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/MANIFEST.in +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/README.md +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linode_cli.egg-info/SOURCES.txt +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linode_cli.egg-info/dependency_links.txt +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linode_cli.egg-info/entry_points.txt +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linode_cli.egg-info/requires.txt +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linode_cli.egg-info/top_level.txt +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/__init__.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/__main__.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/api_request.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/arg_helpers.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/baked/__init__.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/baked/operation.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/baked/parsing.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/baked/util.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/cli.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/completion.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/configuration/__init__.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/configuration/auth.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/data-3 +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/exit_codes.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/help_pages.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/helpers.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/oauth-landing-page.html +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/output/__init__.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/output/helpers.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/output/output_handler.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/overrides.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/plugins/__init__.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/plugins/firewall-editor.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/plugins/get-kubeconfig.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/plugins/image-upload.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/plugins/metadata.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/plugins/obj/__init__.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/plugins/obj/buckets.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/plugins/obj/config.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/plugins/obj/helpers.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/plugins/obj/list.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/plugins/obj/objects.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/plugins/obj/website.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/plugins/plugins.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/plugins/region-table.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/linodecli/plugins/ssh.py +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/pyproject.toml +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/setup.cfg +0 -0
- {linode_cli-5.56.2 → linode_cli-5.56.3}/setup.py +0 -0
|
@@ -2,9 +2,13 @@
|
|
|
2
2
|
Request details for a CLI Operation
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
from typing import List, Optional
|
|
6
|
+
|
|
7
|
+
from openapi3.paths import MediaType
|
|
5
8
|
from openapi3.schemas import Schema
|
|
6
9
|
|
|
7
10
|
from linodecli.baked.parsing import simplify_description
|
|
11
|
+
from linodecli.baked.response import OpenAPIResponse
|
|
8
12
|
from linodecli.baked.util import _aggregate_schema_properties
|
|
9
13
|
|
|
10
14
|
|
|
@@ -13,16 +17,16 @@ class OpenAPIRequestArg:
|
|
|
13
17
|
A single argument to a request as defined by a Schema in the OpenAPI spec
|
|
14
18
|
"""
|
|
15
19
|
|
|
16
|
-
def __init__(
|
|
20
|
+
def __init__( # pylint: disable=too-many-arguments
|
|
17
21
|
self,
|
|
18
|
-
name,
|
|
19
|
-
schema,
|
|
20
|
-
required,
|
|
21
|
-
prefix=None,
|
|
22
|
-
is_parent=False,
|
|
23
|
-
parent=None,
|
|
24
|
-
depth=0,
|
|
25
|
-
)
|
|
22
|
+
name: str,
|
|
23
|
+
schema: Schema,
|
|
24
|
+
required: bool,
|
|
25
|
+
prefix: Optional[str] = None,
|
|
26
|
+
is_parent: bool = False,
|
|
27
|
+
parent: Optional[str] = None,
|
|
28
|
+
depth: int = 0,
|
|
29
|
+
) -> None:
|
|
26
30
|
"""
|
|
27
31
|
Parses a single Schema node into a argument the CLI can use when making
|
|
28
32
|
requests.
|
|
@@ -120,9 +124,14 @@ class OpenAPIRequestArg:
|
|
|
120
124
|
)
|
|
121
125
|
|
|
122
126
|
|
|
123
|
-
def _parse_request_model(
|
|
127
|
+
def _parse_request_model(
|
|
128
|
+
schema: Schema,
|
|
129
|
+
prefix: Optional[str] = None,
|
|
130
|
+
parent: Optional[str] = None,
|
|
131
|
+
depth: int = 0,
|
|
132
|
+
) -> List[OpenAPIRequestArg]:
|
|
124
133
|
"""
|
|
125
|
-
Parses
|
|
134
|
+
Parses an OpenAPI schema into a list of OpenAPIRequest objects
|
|
126
135
|
:param schema: The schema to parse as a request model
|
|
127
136
|
:type schema: openapi3.Schema
|
|
128
137
|
:param prefix: The prefix to add to all keys in this schema, as a json path
|
|
@@ -143,6 +152,7 @@ def _parse_request_model(schema, prefix=None, parent=None, depth=0):
|
|
|
143
152
|
return args
|
|
144
153
|
|
|
145
154
|
for k, v in properties.items():
|
|
155
|
+
# Handle nested objects which aren't read-only and have properties
|
|
146
156
|
if (
|
|
147
157
|
v.type == "object"
|
|
148
158
|
and not v.readOnly
|
|
@@ -159,6 +169,8 @@ def _parse_request_model(schema, prefix=None, parent=None, depth=0):
|
|
|
159
169
|
# parent arguments.
|
|
160
170
|
depth=depth,
|
|
161
171
|
)
|
|
172
|
+
|
|
173
|
+
# Handle arrays of objects that not marked as JSON
|
|
162
174
|
elif (
|
|
163
175
|
v.type == "array"
|
|
164
176
|
and v.items
|
|
@@ -209,7 +221,7 @@ class OpenAPIRequest:
|
|
|
209
221
|
on the MediaType object of a requestBody portion of an OpenAPI Operation
|
|
210
222
|
"""
|
|
211
223
|
|
|
212
|
-
def __init__(self, request):
|
|
224
|
+
def __init__(self, request: MediaType) -> None:
|
|
213
225
|
"""
|
|
214
226
|
:param request: The request's MediaType object in the OpenAPI spec,
|
|
215
227
|
corresponding to the application/json data the endpoint
|
|
@@ -256,7 +268,7 @@ class OpenAPIFilteringRequest:
|
|
|
256
268
|
endpoints where filters are accepted.
|
|
257
269
|
"""
|
|
258
270
|
|
|
259
|
-
def __init__(self, response_model):
|
|
271
|
+
def __init__(self, response_model: OpenAPIResponse) -> None:
|
|
260
272
|
"""
|
|
261
273
|
:param response_model: The parsed response model whose properties may be
|
|
262
274
|
filterable.
|
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
Converting the processed OpenAPI Responses into something the CLI can work with
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
5
7
|
from openapi3.paths import MediaType
|
|
8
|
+
from openapi3.schemas import Schema
|
|
6
9
|
|
|
7
10
|
from linodecli.baked.util import _aggregate_schema_properties
|
|
8
11
|
|
|
@@ -30,7 +33,13 @@ class OpenAPIResponseAttr:
|
|
|
30
33
|
from it.
|
|
31
34
|
"""
|
|
32
35
|
|
|
33
|
-
def __init__(
|
|
36
|
+
def __init__(
|
|
37
|
+
self,
|
|
38
|
+
name: str,
|
|
39
|
+
schema: Schema,
|
|
40
|
+
prefix: Optional[str] = None,
|
|
41
|
+
nested_list_depth: int = 0,
|
|
42
|
+
) -> None:
|
|
34
43
|
"""
|
|
35
44
|
:param name: The key that held this schema in the properties list, representing
|
|
36
45
|
its name in a response.
|
|
@@ -84,10 +93,13 @@ class OpenAPIResponseAttr:
|
|
|
84
93
|
self.item_type = schema.items.type
|
|
85
94
|
|
|
86
95
|
@property
|
|
87
|
-
def path(self):
|
|
96
|
+
def path(self) -> str:
|
|
88
97
|
"""
|
|
89
98
|
This is a helper for filterable fields to return the json path to this
|
|
90
99
|
element in a response.
|
|
100
|
+
|
|
101
|
+
:returns: The json path to the element in a response.
|
|
102
|
+
:rtype: str
|
|
91
103
|
"""
|
|
92
104
|
return self.name
|
|
93
105
|
|
|
@@ -129,6 +141,7 @@ class OpenAPIResponseAttr:
|
|
|
129
141
|
value = str(value)
|
|
130
142
|
color = self.color_map.get(value) or self.color_map["default_"]
|
|
131
143
|
value = f"[{color}]{value}[/]"
|
|
144
|
+
# Convert None value to an empty string for better display
|
|
132
145
|
if value is None:
|
|
133
146
|
# Prints the word None if you don't change it
|
|
134
147
|
value = ""
|
|
@@ -194,12 +207,14 @@ def _parse_response_model(schema, prefix=None, nested_list_depth=0):
|
|
|
194
207
|
elif v.type == "object":
|
|
195
208
|
attrs += _parse_response_model(v, prefix=pref)
|
|
196
209
|
elif v.type == "array" and v.items.type == "object":
|
|
210
|
+
# Parse arrays for objects recursively and increase the nesting depth
|
|
197
211
|
attrs += _parse_response_model(
|
|
198
212
|
v.items,
|
|
199
213
|
prefix=pref,
|
|
200
214
|
nested_list_depth=nested_list_depth + 1,
|
|
201
215
|
)
|
|
202
216
|
else:
|
|
217
|
+
# Handle any other simple types
|
|
203
218
|
attrs.append(
|
|
204
219
|
OpenAPIResponseAttr(
|
|
205
220
|
k, v, prefix=prefix, nested_list_depth=nested_list_depth
|
|
@@ -215,7 +230,7 @@ class OpenAPIResponse:
|
|
|
215
230
|
responses section of an OpenAPI Operation
|
|
216
231
|
"""
|
|
217
232
|
|
|
218
|
-
def __init__(self, response: MediaType):
|
|
233
|
+
def __init__(self, response: MediaType) -> None:
|
|
219
234
|
"""
|
|
220
235
|
:param response: The response's MediaType object in the OpenAPI spec,
|
|
221
236
|
corresponding to the application/json response type
|
|
@@ -287,15 +302,22 @@ class OpenAPIResponse:
|
|
|
287
302
|
|
|
288
303
|
nested_lists = [c.strip() for c in self.nested_list.split(",")]
|
|
289
304
|
result = []
|
|
305
|
+
|
|
290
306
|
for nested_list in nested_lists:
|
|
291
307
|
path_parts = nested_list.split(".")
|
|
308
|
+
|
|
292
309
|
if not isinstance(json, list):
|
|
293
310
|
json = [json]
|
|
311
|
+
|
|
294
312
|
for cur in json:
|
|
313
|
+
# Get the nested list using the path
|
|
295
314
|
nlist_path = cur
|
|
296
315
|
for p in path_parts:
|
|
297
316
|
nlist_path = nlist_path.get(p)
|
|
298
317
|
nlist = nlist_path
|
|
318
|
+
|
|
319
|
+
# For each item in the nested list,
|
|
320
|
+
# combine the parent properties with the nested item
|
|
299
321
|
for item in nlist:
|
|
300
322
|
cobj = {k: v for k, v in cur.items() if k != path_parts[0]}
|
|
301
323
|
cobj["_split"] = path_parts[-1]
|
|
@@ -82,10 +82,7 @@ class CLIConfig:
|
|
|
82
82
|
:returns: The `default-user` username or an empty string.
|
|
83
83
|
:rtype: str
|
|
84
84
|
"""
|
|
85
|
-
|
|
86
|
-
return self.config.get("DEFAULT", "default-user")
|
|
87
|
-
|
|
88
|
-
return ""
|
|
85
|
+
return self.config.get("DEFAULT", "default-user", fallback="")
|
|
89
86
|
|
|
90
87
|
def set_user(self, username: str):
|
|
91
88
|
"""
|
|
@@ -153,15 +150,11 @@ class CLIConfig:
|
|
|
153
150
|
:rtype: str
|
|
154
151
|
"""
|
|
155
152
|
if self.used_env_token:
|
|
156
|
-
return os.
|
|
153
|
+
return os.getenv(ENV_TOKEN_NAME, None)
|
|
157
154
|
|
|
158
|
-
|
|
159
|
-
self.username or self.default_username(), "token"
|
|
160
|
-
)
|
|
161
|
-
return self.config.get(
|
|
162
|
-
self.username or self.default_username(), "token"
|
|
163
|
-
)
|
|
164
|
-
return ""
|
|
155
|
+
return self.config.get(
|
|
156
|
+
self.username or self.default_username(), "token", fallback=""
|
|
157
|
+
)
|
|
165
158
|
|
|
166
159
|
def get_value(self, key: str) -> Optional[Any]:
|
|
167
160
|
"""
|
|
@@ -180,12 +173,9 @@ class CLIConfig:
|
|
|
180
173
|
current user.
|
|
181
174
|
:rtype: any
|
|
182
175
|
"""
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
return None
|
|
187
|
-
|
|
188
|
-
return self.config.get(username, key)
|
|
176
|
+
return self.config.get(
|
|
177
|
+
self.username or self.default_username(), key, fallback=None
|
|
178
|
+
)
|
|
189
179
|
|
|
190
180
|
def get_bool(self, key: str) -> bool:
|
|
191
181
|
"""
|
|
@@ -204,12 +194,10 @@ class CLIConfig:
|
|
|
204
194
|
current user.
|
|
205
195
|
:rtype: any
|
|
206
196
|
"""
|
|
207
|
-
username = self.username or self.default_username()
|
|
208
|
-
|
|
209
|
-
if not self.config.has_option(username, key):
|
|
210
|
-
return False
|
|
211
197
|
|
|
212
|
-
return self.config.getboolean(
|
|
198
|
+
return self.config.getboolean(
|
|
199
|
+
self.username or self.default_username(), key, fallback=False
|
|
200
|
+
)
|
|
213
201
|
|
|
214
202
|
# plugin methods - these are intended for plugins to utilize to store their
|
|
215
203
|
# own persistent config information
|
|
@@ -255,13 +243,10 @@ class CLIConfig:
|
|
|
255
243
|
"No running plugin to retrieve configuration for!"
|
|
256
244
|
)
|
|
257
245
|
|
|
258
|
-
username = self.username or self.default_username()
|
|
246
|
+
username = self.username or self.default_username() or "DEFAULT"
|
|
259
247
|
full_key = f"plugin-{self.running_plugin}-{key}"
|
|
260
248
|
|
|
261
|
-
|
|
262
|
-
return None
|
|
263
|
-
|
|
264
|
-
return self.config.get(username, full_key)
|
|
249
|
+
return self.config.get(username, full_key, fallback=None)
|
|
265
250
|
|
|
266
251
|
# TODO: this is more of an argparsing function than it is a config function
|
|
267
252
|
# might be better to move this to argparsing during refactor and just have
|
|
@@ -308,11 +293,8 @@ class CLIConfig:
|
|
|
308
293
|
# these don't get included in the updated namespace
|
|
309
294
|
if key.startswith("plugin-"):
|
|
310
295
|
continue
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
value = self.config.get(username, key)
|
|
314
|
-
else:
|
|
315
|
-
value = ns_dict[key]
|
|
296
|
+
|
|
297
|
+
value = self.config.get(username, key, fallback=ns_dict.get(key))
|
|
316
298
|
|
|
317
299
|
if not value:
|
|
318
300
|
continue
|
|
@@ -553,7 +535,7 @@ class CLIConfig:
|
|
|
553
535
|
|
|
554
536
|
if len(users) == 0:
|
|
555
537
|
# config is new or _really_ old
|
|
556
|
-
token = self.config.get("DEFAULT", "token")
|
|
538
|
+
token = self.config.get("DEFAULT", "token", fallback=None)
|
|
557
539
|
|
|
558
540
|
if token is not None:
|
|
559
541
|
# there's a token in the config - configure that user
|
|
@@ -299,6 +299,4 @@ def _config_get_with_default(
|
|
|
299
299
|
:returns: The value pulled from the config or the default value.
|
|
300
300
|
:rtype: Any
|
|
301
301
|
"""
|
|
302
|
-
return (
|
|
303
|
-
config.get(user, field) if config.has_option(user, field) else default
|
|
304
|
-
)
|
|
302
|
+
return config.get(user, field, fallback=default)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|