From b6ccfd3362a506ccc2cc5b62e9781b60213e02be Mon Sep 17 00:00:00 2001 From: pmajali Date: Wed, 9 Jul 2025 23:35:08 +0530 Subject: [PATCH 1/4] updating MonitorService class (#568) * updating services endpoint * resolving lint errors --- linode_api4/groups/monitor.py | 18 ++++++-------- linode_api4/objects/monitor.py | 11 +++++---- test/fixtures/monitor_services_dbaas.json | 24 +++++++++++-------- .../models/monitor/test_monitor.py | 8 +++---- test/unit/objects/monitor_test.py | 8 +++---- 5 files changed, 35 insertions(+), 34 deletions(-) diff --git a/linode_api4/groups/monitor.py b/linode_api4/groups/monitor.py index 908b4e819..14b5617c4 100644 --- a/linode_api4/groups/monitor.py +++ b/linode_api4/groups/monitor.py @@ -62,32 +62,28 @@ def dashboards( ) def services( - self, *filters, service_type: Optional[str] = None - ) -> list[MonitorService]: + self, + *filters, + ) -> PaginatedList: """ Lists services supported by ACLP. supported_services = client.monitor.services() - service_details = client.monitor.services(service_type="dbaas") + service_details = client.monitor.load(MonitorService, "dbaas") .. note:: This endpoint is in beta. This will only function if base_url is set to `https://api.linode.com/v4beta`. API Documentation: https://techdocs.akamai.com/linode-api/reference/get-monitor-services API Documentation: https://techdocs.akamai.com/linode-api/reference/get-monitor-services-for-service-type - :param service_type: The service type to get details for. - :type service_type: Optional[str] :param filters: Any number of filters to apply to this query. See :doc:`Filtering Collections` for more details on filtering. - :returns: Lists monitor services by a given service_type + :returns: Lists monitor services :rtype: PaginatedList of the Services """ - endpoint = ( - f"/monitor/services/{service_type}" - if service_type - else "/monitor/services" - ) + endpoint = "/monitor/services" + return self.client._get_and_filter( MonitorService, *filters, diff --git a/linode_api4/objects/monitor.py b/linode_api4/objects/monitor.py index f518e641d..ae3936ee7 100644 --- a/linode_api4/objects/monitor.py +++ b/linode_api4/objects/monitor.py @@ -157,16 +157,19 @@ class MonitorDashboard(Base): } -@dataclass -class MonitorService(JSONObject): +class MonitorService(Base): """ Represents a single service type. API Documentation: https://techdocs.akamai.com/linode-api/reference/get-monitor-services """ - service_type: ServiceType = "" - label: str = "" + api_endpoint = "/monitor/services/{service_type}" + id_attribute = "service_type" + properties = { + "service_type": Property(ServiceType), + "label": Property(), + } @dataclass diff --git a/test/fixtures/monitor_services_dbaas.json b/test/fixtures/monitor_services_dbaas.json index 7a568866c..211833847 100644 --- a/test/fixtures/monitor_services_dbaas.json +++ b/test/fixtures/monitor_services_dbaas.json @@ -1,11 +1,15 @@ { - "data": [ - { - "label": "Databases", - "service_type": "dbaas" - } - ], - "page": 1, - "pages": 1, - "results": 1 - } \ No newline at end of file + "service_type": "dbaas", + "label": "Databases", + "alert": { + "polling_interval_seconds": [ + 300 + ], + "evaluation_period_seconds": [ + 300 + ], + "scope": [ + "entity" + ] + } +} \ No newline at end of file diff --git a/test/integration/models/monitor/test_monitor.py b/test/integration/models/monitor/test_monitor.py index 5fb9626b3..7c9249f42 100644 --- a/test/integration/models/monitor/test_monitor.py +++ b/test/integration/models/monitor/test_monitor.py @@ -44,11 +44,9 @@ def test_get_supported_services(test_linode_client): get_supported_service = supported_services[0].service_type # Get details for a particular service - service_details = client.monitor.services( - service_type=get_supported_service - ) - assert isinstance(service_details[0], MonitorService) - assert service_details[0].service_type == get_supported_service + service_details = client.load(MonitorService, get_supported_service) + assert isinstance(service_details, MonitorService) + assert service_details.service_type == get_supported_service # Get Metric definition details for that particular service metric_definitions = client.monitor.metric_definitions( diff --git a/test/unit/objects/monitor_test.py b/test/unit/objects/monitor_test.py index 385eaf462..a010514c2 100644 --- a/test/unit/objects/monitor_test.py +++ b/test/unit/objects/monitor_test.py @@ -1,7 +1,7 @@ import datetime from test.unit.base import ClientBaseCase -from linode_api4.objects import MonitorDashboard +from linode_api4.objects import MonitorDashboard, MonitorService class MonitorTest(ClientBaseCase): @@ -85,9 +85,9 @@ def test_get_all_dashboards(self): self.assertEqual(dashboards[0].widgets[0].y_label, "cpu_usage") def test_specific_service_details(self): - data = self.client.monitor.services(service_type="dbaas") - self.assertEqual(data[0].label, "Databases") - self.assertEqual(data[0].service_type, "dbaas") + data = self.client.load(MonitorService, "dbaas") + self.assertEqual(data.label, "Databases") + self.assertEqual(data.service_type, "dbaas") def test_metric_definitions(self): From 818feb8d6ca440cf26d7c8a87d1e2bddcbaccf54 Mon Sep 17 00:00:00 2001 From: Youjung Kim <126618609+ykim-akamai@users.noreply.github.com> Date: Tue, 15 Jul 2025 07:03:55 -0700 Subject: [PATCH 2/4] Add basic model filter integration test coverage (#563) --- Makefile | 2 +- test/integration/filters/fixtures.py | 39 +++++++++ .../integration/filters/model_filters_test.py | 84 +++++++++++++++++++ 3 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 test/integration/filters/fixtures.py create mode 100644 test/integration/filters/model_filters_test.py diff --git a/Makefile b/Makefile index 4bfb1c348..ce7ef77d0 100644 --- a/Makefile +++ b/Makefile @@ -58,7 +58,7 @@ lint: build # TEST_CASE: Optional, specify a test case (e.g. 'test_image_replication') # TEST_ARGS: Optional, additional arguments for pytest (e.g. '-v' for verbose mode) -TEST_COMMAND = $(if $(TEST_SUITE),$(if $(filter $(TEST_SUITE),linode_client login_client),$(TEST_SUITE),models/$(TEST_SUITE))) +TEST_COMMAND = $(if $(TEST_SUITE),$(if $(filter $(TEST_SUITE),linode_client login_client filters),$(TEST_SUITE),models/$(TEST_SUITE))) .PHONY: test-int test-int: diff --git a/test/integration/filters/fixtures.py b/test/integration/filters/fixtures.py new file mode 100644 index 000000000..344303eee --- /dev/null +++ b/test/integration/filters/fixtures.py @@ -0,0 +1,39 @@ +from test.integration.conftest import get_region +from test.integration.helpers import get_test_label + +import pytest + + +@pytest.fixture(scope="package") +def domain_instance(test_linode_client): + client = test_linode_client + + domain_addr = get_test_label(5) + "-example.com" + soa_email = "dx-test-email@linode.com" + + domain = client.domain_create(domain=domain_addr, soa_email=soa_email) + + yield domain + + domain.delete() + + +@pytest.fixture(scope="package") +def lke_cluster_instance(test_linode_client): + node_type = test_linode_client.linode.types()[1] # g6-standard-1 + version = test_linode_client.lke.versions()[0] + + region = get_region( + test_linode_client, {"Kubernetes", "LA Disk Encryption"} + ) + + node_pools = test_linode_client.lke.node_pool(node_type, 3) + label = get_test_label() + "_cluster" + + cluster = test_linode_client.lke.cluster_create( + region, label, node_pools, version + ) + + yield cluster + + cluster.delete() diff --git a/test/integration/filters/model_filters_test.py b/test/integration/filters/model_filters_test.py new file mode 100644 index 000000000..22bb8299e --- /dev/null +++ b/test/integration/filters/model_filters_test.py @@ -0,0 +1,84 @@ +from test.integration.filters.fixtures import ( # noqa: F401 + domain_instance, + lke_cluster_instance, +) + +from linode_api4.objects import ( + DatabaseEngine, + DatabaseType, + Domain, + Firewall, + Image, + LKECluster, + Type, +) + + +def test_database_type_model_filter(test_linode_client): + client = test_linode_client + + db_disk = client.database.types()[0].disk + + filtered_db_type = client.database.types(DatabaseType.disk == db_disk) + + assert db_disk == filtered_db_type[0].disk + + +def test_database_engine_model_filter(test_linode_client): + client = test_linode_client + + engine = "mysql" + + filtered_db_engine = client.database.engines( + DatabaseEngine.engine == engine + ) + + assert len(client.database.engines()) > len(filtered_db_engine) + + +def test_domain_model_filter(test_linode_client, domain_instance): + client = test_linode_client + + filtered_domain = client.domains(Domain.domain == domain_instance.domain) + + assert domain_instance.id == filtered_domain[0].id + + +def test_image_model_filter(test_linode_client): + client = test_linode_client + + filtered_images = client.images(Image.label.contains("Debian")) + + assert len(client.images()) > len(filtered_images) + + +def test_linode_type_model_filter(test_linode_client): + client = test_linode_client + + filtered_types = client.linode.types(Type.label.contains("Linode")) + + assert len(filtered_types) > 0 + assert "Linode" in filtered_types[0].label + + +def test_lke_cluster_model_filter(test_linode_client, lke_cluster_instance): + client = test_linode_client + + filtered_cluster = client.lke.clusters( + LKECluster.label.contains(lke_cluster_instance.label) + ) + + assert filtered_cluster[0].id == lke_cluster_instance.id + + +def test_networking_firewall_model_filter( + test_linode_client, e2e_test_firewall +): + client = test_linode_client + + filtered_firewall = client.networking.firewalls( + Firewall.label.contains(e2e_test_firewall.label) + ) + + assert len(filtered_firewall) > 0 + assert e2e_test_firewall.label in filtered_firewall[0].label From e35ffe81a546fb18b29068843648522882f41ac3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Jul 2025 10:54:10 -0400 Subject: [PATCH 3/4] build(deps): bump slackapi/slack-github-action from 2.1.0 to 2.1.1 (#570) Bumps [slackapi/slack-github-action](https://github.com/slackapi/slack-github-action) from 2.1.0 to 2.1.1. - [Release notes](https://github.com/slackapi/slack-github-action/releases) - [Commits](https://github.com/slackapi/slack-github-action/compare/v2.1.0...v2.1.1) --- updated-dependencies: - dependency-name: slackapi/slack-github-action dependency-version: 2.1.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/e2e-test.yml | 4 ++-- .github/workflows/nightly-smoke-tests.yml | 2 +- .github/workflows/release-notify-slack.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/e2e-test.yml b/.github/workflows/e2e-test.yml index d08999645..1c4ec8540 100644 --- a/.github/workflows/e2e-test.yml +++ b/.github/workflows/e2e-test.yml @@ -232,7 +232,7 @@ jobs: steps: - name: Notify Slack id: main_message - uses: slackapi/slack-github-action@v2.1.0 + uses: slackapi/slack-github-action@v2.1.1 with: method: chat.postMessage token: ${{ secrets.SLACK_BOT_TOKEN }} @@ -264,7 +264,7 @@ jobs: - name: Test summary thread if: success() - uses: slackapi/slack-github-action@v2.1.0 + uses: slackapi/slack-github-action@v2.1.1 with: method: chat.postMessage token: ${{ secrets.SLACK_BOT_TOKEN }} diff --git a/.github/workflows/nightly-smoke-tests.yml b/.github/workflows/nightly-smoke-tests.yml index 3f6083a98..dc41e1600 100644 --- a/.github/workflows/nightly-smoke-tests.yml +++ b/.github/workflows/nightly-smoke-tests.yml @@ -45,7 +45,7 @@ jobs: - name: Notify Slack if: always() && github.repository == 'linode/linode_api4-python' - uses: slackapi/slack-github-action@v2.1.0 + uses: slackapi/slack-github-action@v2.1.1 with: method: chat.postMessage token: ${{ secrets.SLACK_BOT_TOKEN }} diff --git a/.github/workflows/release-notify-slack.yml b/.github/workflows/release-notify-slack.yml index f2739e988..4b01f094b 100644 --- a/.github/workflows/release-notify-slack.yml +++ b/.github/workflows/release-notify-slack.yml @@ -11,7 +11,7 @@ jobs: steps: - name: Notify Slack - Main Message id: main_message - uses: slackapi/slack-github-action@v2.1.0 + uses: slackapi/slack-github-action@v2.1.1 with: method: chat.postMessage token: ${{ secrets.SLACK_BOT_TOKEN }} From de7cde17026e8b333eafb15e00215825d8f7e74e Mon Sep 17 00:00:00 2001 From: Ye Chen <127243817+yec-akamai@users.noreply.github.com> Date: Tue, 22 Jul 2025 11:20:54 -0400 Subject: [PATCH 4/4] Fix timeout integration test cases (#575) --- test/integration/models/account/test_account.py | 4 ++-- test/integration/models/linode/test_linode.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/integration/models/account/test_account.py b/test/integration/models/account/test_account.py index decad434f..72cd97cda 100644 --- a/test/integration/models/account/test_account.py +++ b/test/integration/models/account/test_account.py @@ -1,7 +1,7 @@ import time from datetime import datetime from test.integration.conftest import get_region -from test.integration.helpers import get_test_label +from test.integration.helpers import get_test_label, retry_sending_request import pytest @@ -37,7 +37,7 @@ def test_get_account(test_linode_client): def test_get_login(test_linode_client): client = test_linode_client - login = client.load(Login(client, "", {}), "") + login = retry_sending_request(3, client.load, Login(client, "", {}), "") updated_time = int(time.mktime(getattr(login, "_last_updated").timetuple())) diff --git a/test/integration/models/linode/test_linode.py b/test/integration/models/linode/test_linode.py index ade4ca5ed..97965f2b9 100644 --- a/test/integration/models/linode/test_linode.py +++ b/test/integration/models/linode/test_linode.py @@ -252,7 +252,7 @@ def test_linode_rebuild(test_linode_client): disk_encryption=InstanceDiskEncryptionType.disabled, ) - wait_for_condition(10, 100, get_status, linode, "rebuilding") + wait_for_condition(10, 300, get_status, linode, "rebuilding") assert linode.status == "rebuilding" assert linode.image.id == "linode/debian12"