Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ jobs:
uses: actions/checkout@v5

- name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@v4
with:
category: "/language:${{matrix.language}}"
4 changes: 2 additions & 2 deletions .github/workflows/e2e-suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ jobs:

- name: Upload Test Report as Artifact
if: always()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: test-report-file
if-no-files-found: ignore
Expand Down Expand Up @@ -243,7 +243,7 @@ jobs:
submodules: 'recursive'

- name: Download test report
uses: actions/download-artifact@v5
uses: actions/download-artifact@v6
with:
name: test-report-file

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish-wiki.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: Andrew-Chen-Wang/github-wiki-action@2c80c13ee98aa43683bd77973ef4916e2eedf817 # pin@v5.0.1
- uses: Andrew-Chen-Wang/github-wiki-action@6448478bd55f1f3f752c93af8ac03207eccc3213 # pin@v5.0.3
2 changes: 1 addition & 1 deletion .github/workflows/remote-release-trigger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ jobs:
commit_sha: ${{ steps.calculate_head_sha.outputs.commit_sha }}

- name: Release
uses: softprops/action-gh-release@6cbd405e2c4e67a21c47fa9e383d020e4e28b836 # pin@v2.3.3
uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # pin@v2.4.1
with:
target_commitish: 'main'
token: ${{ steps.generate_token.outputs.token }}
Expand Down
7 changes: 5 additions & 2 deletions linodecli/plugins/get-kubeconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

from linodecli.exit_codes import ExitCodes
from linodecli.help_formatter import SortingHelpFormatter
from linodecli.plugins import inherit_plugin_args

PLUGIN_BASE = "linode-cli get-kubeconfig"

Expand All @@ -23,8 +24,10 @@ def call(args, context):
"""
The entrypoint for this plugin
"""
parser = argparse.ArgumentParser(
PLUGIN_BASE, add_help=True, formatter_class=SortingHelpFormatter
parser = inherit_plugin_args(
argparse.ArgumentParser(
PLUGIN_BASE, add_help=True, formatter_class=SortingHelpFormatter
)
)

group = parser.add_mutually_exclusive_group()
Expand Down
2 changes: 2 additions & 0 deletions tests/integration/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,8 @@ def create_vpc_w_subnet():
vpc_label,
"--region",
region,
# "--ipv6.range", TODO: Uncomment after VPC Dual Stack is ready to ship
# "auto",
"--subnets.ipv4",
"10.0.0.0/24",
"--subnets.label",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ def test_mysql_engine_config_view():
binlog_retention = mysql_config[0]["binlog_retention_period"]
assert binlog_retention["type"] == "integer"
assert binlog_retention["minimum"] == 600
assert binlog_retention["maximum"] == 604800
assert binlog_retention["maximum"] == 9007199254740991
assert binlog_retention["requires_restart"] is False

mysql_settings = mysql_config[0]["mysql"]
Expand Down
9 changes: 9 additions & 0 deletions tests/integration/helpers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import json
import random
import re
import subprocess
import time
from string import ascii_lowercase
Expand Down Expand Up @@ -27,6 +28,8 @@
"domains",
"events",
"image",
"images",
"image-sharegroups",
"image-upload",
"firewalls",
"kernels",
Expand Down Expand Up @@ -204,3 +207,9 @@ def get_random_region_with_caps(
matching_region_ids = [region["id"] for region in matching_regions]

return random.choice(matching_region_ids) if matching_region_ids else None


def assert_help_actions_list(expected_actions, help_output):
output_actions = re.findall(r"│\s(\S+(?:,\s)?\S+)\s*│", help_output)
for expected_action in expected_actions:
assert expected_action in output_actions
38 changes: 38 additions & 0 deletions tests/integration/monitor/test_alerts.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,35 @@
from tests.integration.helpers import (
BASE_CMDS,
assert_headers_in_lines,
assert_help_actions_list,
delete_target_id,
exec_test_command,
get_random_text,
retry_exec_test_command_with_delay,
)


def test_help_alerts():
output = exec_test_command(
BASE_CMDS["alerts"]
+ [
"--help",
"--text",
"--delimiter=,",
]
)

actions = [
"channels-list",
"definition-create",
"definition-delete",
"definition-update",
"definition-view",
"definitions-list-all",
]
assert_help_actions_list(actions, output)


def test_channels_list():
res = exec_test_command(
BASE_CMDS["alerts"] + ["channels-list", "--text", "--delimiter=,"]
Expand Down Expand Up @@ -77,6 +99,22 @@ def test_alerts_definition_create(get_channel_id, get_service_type):
)


def test_list_alert_definitions_for_service_type(get_service_type):
service_type = get_service_type
output = exec_test_command(
BASE_CMDS["alerts"]
+ [
"service-definitions-list",
service_type,
"--text",
"--delimiter=,",
]
)

headers = ["class", "created", "label", "severity", "service_type"]
assert_headers_in_lines(headers, output.splitlines())


def test_alerts_list():
res = exec_test_command(
BASE_CMDS["alerts"]
Expand Down
32 changes: 26 additions & 6 deletions tests/integration/monitor/test_metrics.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import pytest

from linodecli.exit_codes import ExitCodes
from tests.integration.helpers import (
BASE_CMDS,
assert_headers_in_lines,
exec_failing_test_command,
exec_test_command,
)

Expand Down Expand Up @@ -62,12 +64,12 @@ def test_service_list():


def test_service_view(get_service_type):
dashboard_id = get_service_type
service_type = get_service_type
res = exec_test_command(
BASE_CMDS["monitor"]
+ [
"service-view",
dashboard_id,
service_type,
"--text",
"--delimiter=,",
]
Expand All @@ -79,12 +81,12 @@ def test_service_view(get_service_type):


def test_dashboard_service_type_list(get_service_type):
dashboard_id = get_service_type
service_type = get_service_type
res = exec_test_command(
BASE_CMDS["monitor"]
+ [
"dashboards-list",
dashboard_id,
service_type,
"--text",
"--delimiter=,",
]
Expand All @@ -96,12 +98,12 @@ def test_dashboard_service_type_list(get_service_type):


def test_metrics_list(get_service_type):
dashboard_id = get_service_type
service_type = get_service_type
res = exec_test_command(
BASE_CMDS["monitor"]
+ [
"metrics-list",
dashboard_id,
service_type,
"--text",
"--delimiter=,",
]
Expand All @@ -117,3 +119,21 @@ def test_metrics_list(get_service_type):
"scrape_interval",
]
assert_headers_in_lines(headers, lines)


def test_try_create_token_with_not_existing_entity(get_service_type):
service_type = get_service_type
output = exec_failing_test_command(
BASE_CMDS["monitor"]
+ [
"token-get",
service_type,
"--entity_ids",
"99999999999",
"--text",
"--delimiter=,",
],
expected_code=ExitCodes.REQUEST_FAILED,
)
assert "Request failed: 403" in output
assert "The following entity_ids are not valid - [99999999999]" in output
141 changes: 141 additions & 0 deletions tests/integration/sharegroups/fixtures.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import pytest
from pytest import MonkeyPatch

from tests.integration.helpers import (
BASE_CMDS,
exec_test_command,
get_random_text,
)


@pytest.fixture
def get_region():
regions = exec_test_command(
BASE_CMDS["regions"]
+ [
"list",
"--text",
"--no-headers",
"--delimiter",
",",
"--format",
"id",
]
).splitlines()
first_id = regions[0]
yield first_id


def wait_for_image_status(id, expected_status, timeout=180, interval=5):
import time

current_status = exec_test_command(
BASE_CMDS["images"]
+ [
"view",
id,
"--text",
"--no-headers",
"--delimiter",
",",
"--format",
"status",
]
).splitlines()
timer = 0
while current_status[0] != expected_status and timer < timeout:
time.sleep(interval)
timer += interval
current_status = exec_test_command(
BASE_CMDS["images"]
+ [
"view",
id,
"--text",
"--no-headers",
"--delimiter",
",",
"--format",
"status",
]
).splitlines()
if timer >= timeout:
raise TimeoutError(
f"Created image did not reach status '{expected_status}' within {timeout} seconds."
)


@pytest.fixture(scope="function")
def create_image_id(get_region):
linode_id = exec_test_command(
BASE_CMDS["linodes"]
+ [
"create",
"--image",
"linode/alpine3.22",
"--region",
get_region,
"--type",
"g6-nanode-1",
"--root_pass",
"aComplex@Password",
"--text",
"--no-headers",
"--delimiter",
",",
"--format",
"id",
]
)
disks = exec_test_command(
BASE_CMDS["linodes"]
+ [
"disks-list",
linode_id,
"--text",
"--no-headers",
"--delimiter",
",",
"--format",
"id",
]
).splitlines()
image_id = exec_test_command(
BASE_CMDS["images"]
+ [
"create",
"--label",
"linode-cli-test-image-sharing-image",
"--disk_id",
disks[0],
"--text",
"--no-headers",
"--delimiter",
",",
"--format",
"id",
]
)
wait_for_image_status(image_id, "available")
yield linode_id, image_id


@pytest.fixture(scope="function")
def create_share_group(monkeypatch: MonkeyPatch):
monkeypatch.setenv("LINODE_CLI_API_VERSION", "v4beta")
label = get_random_text(8) + "_sharegroup_cli_test"
share_group = exec_test_command(
BASE_CMDS["image-sharegroups"]
+ [
"create",
"--label",
label,
"--text",
"--no-headers",
"--delimiter",
",",
"--format",
"id,uuid",
]
).split(",")
yield share_group[0], share_group[1]
Loading
Loading