Skip to content

Commit 8abff4e

Browse files
Merge pull request #804 from linode/dev
Release v5.61.0
2 parents a50ce24 + 9ebee7f commit 8abff4e

File tree

13 files changed

+271
-73
lines changed

13 files changed

+271
-73
lines changed

.github/workflows/e2e-suite.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ jobs:
294294
steps:
295295
- name: Notify Slack
296296
id: main_message
297-
uses: slackapi/slack-github-action@v2.1.0
297+
uses: slackapi/slack-github-action@v2
298298
with:
299299
method: chat.postMessage
300300
token: ${{ secrets.SLACK_BOT_TOKEN }}
@@ -326,7 +326,7 @@ jobs:
326326
327327
- name: Test summary thread
328328
if: success()
329-
uses: slackapi/slack-github-action@v2.1.0
329+
uses: slackapi/slack-github-action@v2
330330
with:
331331
method: chat.postMessage
332332
token: ${{ secrets.SLACK_BOT_TOKEN }}

.github/workflows/nightly-smoke-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ jobs:
4646

4747
- name: Notify Slack
4848
if: always() && github.repository == 'linode/linode-cli' # Run even if integration tests fail and only on main repository
49-
uses: slackapi/slack-github-action@v2.1.0
49+
uses: slackapi/slack-github-action@v2
5050
with:
5151
method: chat.postMessage
5252
token: ${{ secrets.SLACK_BOT_TOKEN }}

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
steps:
1212
- name: Notify Slack - Main Message
1313
id: main_message
14-
uses: slackapi/slack-github-action@v2.1.0
14+
uses: slackapi/slack-github-action@v2
1515
with:
1616
method: chat.postMessage
1717
token: ${{ secrets.SLACK_BOT_TOKEN }}

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ test-unit:
6464
@mkdir -p /tmp/linode/.config
6565
@orig_xdg_config_home=$${XDG_CONFIG_HOME:-}; \
6666
export LINODE_CLI_TEST_MODE=1 XDG_CONFIG_HOME=/tmp/linode/.config; \
67-
pytest -v tests/unit; \
67+
pytest -vv tests/unit; \
6868
exit_code=$$?; \
6969
export XDG_CONFIG_HOME=$$orig_xdg_config_home; \
7070
exit $$exit_code

linodecli/baked/request.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ def __init__( # pylint: disable=too-many-arguments
4848
:type parent: Optional[str]
4949
:param depth: The depth of this argument, or how many parent arguments this argument has.
5050
:type depth: int
51+
:param option_variants: A mapping of options, defined using oneOf in the to spec,
52+
to a variant of this argument.
5153
"""
5254
#: The name of this argument, mostly used for display and docs
5355
self.name = name
@@ -147,6 +149,7 @@ def _parse_request_model(
147149
:returns: The flattened request model, as a list
148150
:rtype: list[OpenAPIRequestArg]
149151
"""
152+
150153
args = []
151154

152155
properties, required = _aggregate_schema_properties(schema)

linodecli/baked/util.py

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,28 +24,39 @@ def _aggregate_schema_properties(
2424
properties = {}
2525
required = defaultdict(lambda: 0)
2626

27-
def _handle_schema(_schema: Schema):
28-
if _schema.properties is None:
27+
def __inner(
28+
path: List[str],
29+
entry: Schema,
30+
):
31+
if isinstance(entry, dict):
32+
# TODO: Figure out why this happens (openapi3 package bug?)
33+
# pylint: disable=protected-access
34+
entry = Schema(path, entry, schema._root)
35+
36+
if entry.properties is None:
37+
# If there aren't any properties, this might be a
38+
# composite schema
39+
for composition_field in ["oneOf", "allOf", "anyOf"]:
40+
for i, nested_entry in enumerate(
41+
getattr(entry, composition_field) or []
42+
):
43+
__inner(
44+
schema.path + [composition_field, str(i)],
45+
nested_entry,
46+
)
47+
2948
return
3049

50+
# This is a valid option
51+
properties.update(entry.properties)
52+
3153
nonlocal schema_count
3254
schema_count += 1
3355

34-
properties.update(dict(_schema.properties))
35-
36-
# Aggregate required keys and their number of usages.
37-
if _schema.required is not None:
38-
for key in _schema.required:
39-
required[key] += 1
40-
41-
_handle_schema(schema)
42-
43-
one_of = schema.oneOf or []
44-
any_of = schema.anyOf or []
56+
for key in entry.required or []:
57+
required[key] += 1
4558

46-
for entry in one_of + any_of:
47-
# pylint: disable=protected-access
48-
_handle_schema(Schema(schema.path, entry, schema._root))
59+
__inner(schema.path, schema)
4960

5061
return (
5162
properties,

linodecli/help_pages.py

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -298,50 +298,58 @@ def _help_group_arguments(
298298
"""
299299
Returns help page groupings for a list of POST/PUT arguments.
300300
"""
301+
args = [arg for arg in args if not arg.read_only]
301302
args_sorted = sorted(args, key=lambda a: a.path)
302303

303-
groups_tmp = defaultdict(list)
304+
paths = {tuple(arg.path.split(".")) for arg in args_sorted}
305+
path_to_args = defaultdict(list)
304306

305-
# Initial grouping by root parent
306307
for arg in args_sorted:
307-
if arg.read_only:
308-
continue
308+
arg_path = tuple(arg.path.split("."))
309+
310+
if not arg.is_parent:
311+
# Parent arguments are grouped in with their children
312+
arg_path = arg_path[:-1]
313+
314+
# Find first common parent
315+
while len(arg_path) > 1 and arg_path not in paths:
316+
arg_path = arg_path[:-1]
309317

310-
groups_tmp[arg.path.split(".", 1)[0]].append(arg)
318+
path_to_args[arg_path].append(arg)
311319

312320
group_required = []
313321
groups = []
314322
ungrouped = []
315323

316-
for group in groups_tmp.values():
317-
# If the group has more than one element,
318-
# leave it as is in the result
319-
if len(group) > 1:
324+
for k, group in sorted(
325+
path_to_args.items(), key=lambda a: (len(a[0]), a[0], len(a[1]))
326+
):
327+
if len(k) > 0 and len(group) > 1:
328+
# This is a named subgroup
320329
groups.append(
321330
# Args should be ordered by least depth -> required -> path
322331
sorted(group, key=lambda v: (v.depth, not v.required, v.path)),
323332
)
324333
continue
325334

326-
target_arg = group[0]
327-
328335
# If the group's argument is required,
329-
# add it to the required group
330-
if target_arg.required:
331-
group_required.append(target_arg)
332-
continue
336+
# add it to the top-level required group
337+
for arg in group:
338+
if arg.required:
339+
group_required.append(arg)
340+
continue
333341

334-
# Add ungrouped arguments (single value groups) to the
335-
# "ungrouped" group.
336-
ungrouped.append(target_arg)
342+
# Add ungrouped arguments (single value groups) to the
343+
# "ungrouped" group.
344+
ungrouped.append(arg)
337345

338346
result = []
339347

340348
if len(group_required) > 0:
341-
result.append(group_required)
349+
result.append(sorted(group_required, key=lambda v: v.path))
342350

343351
if len(ungrouped) > 0:
344-
result.append(ungrouped)
352+
result.append(sorted(ungrouped, key=lambda v: v.path))
345353

346354
result += groups
347355

tests/integration/linodes/fixtures.py

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,60 @@ def linode_with_vpc_interface_as_json(linode_cloud_firewall):
311311
delete_target_id(target="vpcs", id=vpc_id)
312312

313313

314+
@pytest.fixture
315+
def linode_with_vpc_interface_as_args(linode_cloud_firewall):
316+
"""
317+
NOTE: This is fixture exists to accommodate a regression test.
318+
For new tests, use linode_with_vpc_interface_as_json.
319+
"""
320+
321+
vpc_json = create_vpc_w_subnet()
322+
323+
vpc_region = vpc_json["region"]
324+
vpc_id = str(vpc_json["id"])
325+
subnet_id = str(vpc_json["subnets"][0]["id"])
326+
327+
linode_json = json.loads(
328+
exec_test_command(
329+
BASE_CMDS["linodes"]
330+
+ [
331+
"create",
332+
"--type",
333+
"g6-nanode-1",
334+
"--region",
335+
vpc_region,
336+
"--image",
337+
DEFAULT_TEST_IMAGE,
338+
"--root_pass",
339+
DEFAULT_RANDOM_PASS,
340+
"--firewall_id",
341+
linode_cloud_firewall,
342+
"--interfaces.purpose",
343+
"vpc",
344+
"--interfaces.primary",
345+
"true",
346+
"--interfaces.subnet_id",
347+
subnet_id,
348+
"--interfaces.ipv4.nat_1_1",
349+
"any",
350+
"--interfaces.ipv4.vpc",
351+
"10.0.0.5",
352+
"--interfaces.ip_ranges",
353+
json.dumps(["10.0.0.6/32"]),
354+
"--interfaces.purpose",
355+
"public",
356+
"--json",
357+
"--suppress-warnings",
358+
]
359+
)
360+
)[0]
361+
362+
yield linode_json, vpc_json
363+
364+
delete_target_id(target="linodes", id=str(linode_json["id"]))
365+
delete_target_id(target="vpcs", id=vpc_id)
366+
367+
314368
# Interfaces new
315369
@pytest.fixture(scope="module")
316370
def linode_interface_public(linode_cloud_firewall):
@@ -321,13 +375,9 @@ def linode_interface_public(linode_cloud_firewall):
321375
interfaces='[{"public": {"ipv4": {"addresses": [{"primary": true}]}}, "default_route": {"ipv4": true, "ipv6": true }, "firewall_id":'
322376
+ linode_cloud_firewall
323377
+ "}]",
378+
booted=False,
324379
)
325380

326-
wait_until(linode_id=linode_id, timeout=300, status="running")
327-
328-
# TODO: add support of creating a offline linode in `create_linode` then remove this workaround
329-
exec_test_command(BASE_CMDS["linodes"] + ["shutdown", linode_id])
330-
331381
wait_until(linode_id=linode_id, timeout=60, status="offline")
332382

333383
yield linode_id

tests/integration/linodes/helpers.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ def create_linode(
6262
disk_encryption=False,
6363
interface_generation: str = None,
6464
interfaces: str = None,
65+
booted: bool = True,
6566
):
6667
# Base command
6768
command = BASE_CMDS["linodes"] + [
@@ -78,6 +79,8 @@ def create_linode(
7879
firewall_id,
7980
"--disk_encryption",
8081
"enabled" if disk_encryption else "disabled",
82+
"--booted",
83+
str(booted).lower(),
8184
]
8285

8386
if interface_generation:

tests/integration/linodes/test_interfaces.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
exec_test_command,
77
)
88
from tests.integration.linodes.fixtures import ( # noqa: F401
9+
linode_with_vpc_interface_as_args,
910
linode_with_vpc_interface_as_json,
1011
)
1112

@@ -40,5 +41,9 @@ def assert_interface_configuration(
4041
assert public_interface["purpose"] == "public"
4142

4243

44+
def test_with_vpc_interface_as_args(linode_with_vpc_interface_as_args):
45+
assert_interface_configuration(*linode_with_vpc_interface_as_args)
46+
47+
4348
def test_with_vpc_interface_as_json(linode_with_vpc_interface_as_json):
4449
assert_interface_configuration(*linode_with_vpc_interface_as_json)

0 commit comments

Comments
 (0)