From 0c32726f3ac35dcd4a2dc8fb70e03e9ce0066fe4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Aug 2025 02:30:24 -0400 Subject: [PATCH 1/6] build(deps): bump actions/checkout from 4 to 5 (#579) Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- .github/workflows/codeql.yml | 2 +- .github/workflows/dependency-review.yml | 2 +- .github/workflows/e2e-test-pr.yml | 4 ++-- .github/workflows/e2e-test.yml | 8 ++++---- .github/workflows/labeler.yml | 2 +- .github/workflows/nightly-smoke-tests.yml | 2 +- .github/workflows/publish-pypi.yaml | 2 +- .github/workflows/release-cross-repo-test.yml | 4 ++-- 9 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1fd2ad747..d9863f1fd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: checkout repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: setup python 3 uses: actions/setup-python@v5 @@ -33,7 +33,7 @@ jobs: matrix: python-version: ['3.9', '3.10', '3.11', '3.12', '3.13'] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 7168ea488..527950d61 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -23,7 +23,7 @@ jobs: build-mode: none steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Initialize CodeQL uses: github/codeql-action/init@v3 diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index f2b7117d8..e31dcc975 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: 'Checkout repository' - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: 'Dependency Review' uses: actions/dependency-review-action@v4 with: diff --git a/.github/workflows/e2e-test-pr.yml b/.github/workflows/e2e-test-pr.yml index 31e695aca..2f26c393b 100644 --- a/.github/workflows/e2e-test-pr.yml +++ b/.github/workflows/e2e-test-pr.yml @@ -48,7 +48,7 @@ jobs: # Check out merge commit - name: Checkout PR - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: ref: ${{ inputs.sha }} fetch-depth: 0 @@ -150,7 +150,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 0 submodules: 'recursive' diff --git a/.github/workflows/e2e-test.yml b/.github/workflows/e2e-test.yml index 1c4ec8540..3c9c531fd 100644 --- a/.github/workflows/e2e-test.yml +++ b/.github/workflows/e2e-test.yml @@ -57,7 +57,7 @@ jobs: steps: - name: Clone Repository with SHA if: ${{ inputs.sha != '' }} - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 0 submodules: 'recursive' @@ -65,7 +65,7 @@ jobs: - name: Clone Repository without SHA if: ${{ inputs.sha == '' }} - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 0 submodules: 'recursive' @@ -111,7 +111,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 0 submodules: 'recursive' @@ -178,7 +178,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 0 submodules: 'recursive' diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 30bcb1956..7a3ee5f37 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -18,7 +18,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Run Labeler uses: crazy-max/ghaction-github-labeler@24d110aa46a59976b8a7f35518cb7f14f434c916 diff --git a/.github/workflows/nightly-smoke-tests.yml b/.github/workflows/nightly-smoke-tests.yml index dc41e1600..2d7f9543a 100644 --- a/.github/workflows/nightly-smoke-tests.yml +++ b/.github/workflows/nightly-smoke-tests.yml @@ -19,7 +19,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: ref: dev diff --git a/.github/workflows/publish-pypi.yaml b/.github/workflows/publish-pypi.yaml index 027ac5298..a921010ca 100644 --- a/.github/workflows/publish-pypi.yaml +++ b/.github/workflows/publish-pypi.yaml @@ -12,7 +12,7 @@ jobs: environment: pypi-release steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Setup Python uses: actions/setup-python@v5 diff --git a/.github/workflows/release-cross-repo-test.yml b/.github/workflows/release-cross-repo-test.yml index 052eaffb4..e6ca88cd3 100644 --- a/.github/workflows/release-cross-repo-test.yml +++ b/.github/workflows/release-cross-repo-test.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout linode_api4 repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 0 submodules: 'recursive' @@ -30,7 +30,7 @@ jobs: python-version: '3.10' - name: Checkout ansible repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: linode/ansible_linode path: .ansible/collections/ansible_collections/linode/cloud From f2055c68e703de1f124c2f80cfce8ea2fc897c8c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Aug 2025 02:31:32 -0400 Subject: [PATCH 2/6] build(deps): bump actions/download-artifact from 4 to 5 (#580) Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4 to 5. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/e2e-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e-test.yml b/.github/workflows/e2e-test.yml index 3c9c531fd..7a94a1e24 100644 --- a/.github/workflows/e2e-test.yml +++ b/.github/workflows/e2e-test.yml @@ -184,7 +184,7 @@ jobs: submodules: 'recursive' - name: Download test report - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v5 with: name: test-report-file From 78ae6187d38d648bf661ad3ccfed2d4acc205a7f Mon Sep 17 00:00:00 2001 From: rammanoj Date: Fri, 22 Aug 2025 14:13:56 -0400 Subject: [PATCH 3/6] Add label to nodepool (#588) * add label to nodepool * remove redundant prints --------- Co-authored-by: rpotla --- linode_api4/objects/lke.py | 12 +++++------- test/fixtures/lke_clusters_18881_pools_456.json | 1 + test/fixtures/lke_clusters_18882_pools_789.json | 1 + test/unit/objects/lke_test.py | 5 +++++ 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/linode_api4/objects/lke.py b/linode_api4/objects/lke.py index 7086b1113..792aed988 100644 --- a/linode_api4/objects/lke.py +++ b/linode_api4/objects/lke.py @@ -187,6 +187,7 @@ class LKENodePool(DerivedBase): properties = { "id": Property(identifier=True), "cluster_id": Property(identifier=True), + "label": Property(mutable=True), "type": Property(slug_relationship=Type), "disks": Property(), "disk_encryption": Property(), @@ -419,6 +420,7 @@ def node_pool_create( Union[str, KubeVersion, TieredKubeVersion] ] = None, update_strategy: Optional[str] = None, + label: str = None, **kwargs, ): """ @@ -444,23 +446,19 @@ def node_pool_create( for possible values. :returns: The new Node Pool + :param label: The name of the node pool. + :type label: str :rtype: LKENodePool """ params = { "type": node_type, + "label": label, "count": node_count, "labels": labels, "taints": taints, "k8s_version": k8s_version, "update_strategy": update_strategy, } - - if labels is not None: - params["labels"] = labels - - if taints is not None: - params["taints"] = taints - params.update(kwargs) result = self._client.post( diff --git a/test/fixtures/lke_clusters_18881_pools_456.json b/test/fixtures/lke_clusters_18881_pools_456.json index f904b9c95..9aa5fb0f0 100644 --- a/test/fixtures/lke_clusters_18881_pools_456.json +++ b/test/fixtures/lke_clusters_18881_pools_456.json @@ -34,6 +34,7 @@ "foo": "bar", "bar": "foo" }, + "label": "example-node-pool", "type": "g6-standard-4", "disk_encryption": "enabled" } \ No newline at end of file diff --git a/test/fixtures/lke_clusters_18882_pools_789.json b/test/fixtures/lke_clusters_18882_pools_789.json index a7bbc4749..d3c17eedb 100644 --- a/test/fixtures/lke_clusters_18882_pools_789.json +++ b/test/fixtures/lke_clusters_18882_pools_789.json @@ -1,6 +1,7 @@ { "id": 789, "type": "g6-standard-2", + "label": "enterprise-node-pool", "count": 3, "nodes": [], "disks": [], diff --git a/test/unit/objects/lke_test.py b/test/unit/objects/lke_test.py index a0ad63288..cb9589cfb 100644 --- a/test/unit/objects/lke_test.py +++ b/test/unit/objects/lke_test.py @@ -51,6 +51,7 @@ def test_get_pool(self): assert pool.id == 456 assert pool.cluster_id == 18881 assert pool.type.id == "g6-standard-4" + assert pool.label == "example-node-pool" assert pool.disk_encryption == InstanceDiskEncryptionType.enabled assert pool.disks is not None @@ -162,6 +163,7 @@ def test_load_node_pool(self): self.assertEqual(pool.id, 456) self.assertEqual(pool.cluster_id, 18881) self.assertEqual(pool.type.id, "g6-standard-4") + self.assertEqual(pool.label, "example-node-pool") self.assertIsNotNone(pool.disks) self.assertIsNotNone(pool.nodes) self.assertIsNotNone(pool.autoscaler) @@ -251,6 +253,7 @@ def test_lke_node_pool_update(self): pool.tags = ["foobar"] pool.count = 5 + pool.label = "testing-label" pool.autoscaler = { "enabled": True, "min": 2, @@ -274,6 +277,7 @@ def test_lke_node_pool_update(self): "min": 2, "max": 10, }, + "label": "testing-label", "labels": { "updated-key": "updated-value", }, @@ -546,6 +550,7 @@ def test_cluster_enterprise(self): pool = LKENodePool(self.client, 789, 18882) assert pool.k8s_version == "1.31.1+lke1" assert pool.update_strategy == "rolling_update" + assert pool.label == "enterprise-node-pool" def test_lke_tiered_version(self): version = TieredKubeVersion(self.client, "1.32", "standard") From 0c1f2b855f204619d679c0828c77cfc5cc427e6b Mon Sep 17 00:00:00 2001 From: Erik Zilber Date: Fri, 5 Sep 2025 16:13:04 -0400 Subject: [PATCH 4/6] Updated incorrect documentation link for maintenance policies (#590) --- linode_api4/groups/maintenance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linode_api4/groups/maintenance.py b/linode_api4/groups/maintenance.py index f41780dfb..7d56cec6e 100644 --- a/linode_api4/groups/maintenance.py +++ b/linode_api4/groups/maintenance.py @@ -14,7 +14,7 @@ def maintenance_policies(self): Returns a collection of MaintenancePolicy objects representing available maintenance policies that can be applied to Linodes - API Documentation: https://techdocs.akamai.com/linode-api/reference/get-policies + API Documentation: https://techdocs.akamai.com/linode-api/reference/get-maintenance-policies :returns: A list of Maintenance Policies that can be applied to Linodes :rtype: List of MaintenancePolicy objects as MappedObjects From 8b85487e49da429b5063888b7f9c29a82a4ededb Mon Sep 17 00:00:00 2001 From: Lena Garber <114949949+lgarber-akamai@users.noreply.github.com> Date: Mon, 8 Sep 2025 09:54:36 -0400 Subject: [PATCH 5/6] Resolve various integration test failures (#591) * Various test fixes to unblock upcoming release * Use dynamic label for VLAN test * oops * LA Disk Encryption -> Disk Encryption --- test/integration/filters/fixtures.py | 4 +- test/integration/models/image/test_image.py | 40 ++++++++++++++----- test/integration/models/linode/test_linode.py | 4 +- test/integration/models/lke/test_lke.py | 10 ++--- .../models/networking/test_networking.py | 2 +- .../models/nodebalancer/test_nodebalancer.py | 13 ++++-- 6 files changed, 47 insertions(+), 26 deletions(-) diff --git a/test/integration/filters/fixtures.py b/test/integration/filters/fixtures.py index 344303eee..31b7edcbf 100644 --- a/test/integration/filters/fixtures.py +++ b/test/integration/filters/fixtures.py @@ -23,9 +23,7 @@ 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"} - ) + region = get_region(test_linode_client, {"Kubernetes", "Disk Encryption"}) node_pools = test_linode_client.lke.node_pool(node_type, 3) label = get_test_label() + "_cluster" diff --git a/test/integration/models/image/test_image.py b/test/integration/models/image/test_image.py index 9124ddf97..58da0a56f 100644 --- a/test/integration/models/image/test_image.py +++ b/test/integration/models/image/test_image.py @@ -1,22 +1,46 @@ from io import BytesIO -from test.integration.conftest import get_region, get_regions +from test.integration.conftest import get_regions from test.integration.helpers import get_test_label import polling import pytest +from linode_api4 import LinodeClient from linode_api4.objects import Image +DISALLOWED_IMAGE_REGIONS = { + "gb-lon", + "au-mel", + "sg-sin-2", + "jp-tyo-3", +} + + +def get_image_upload_regions(client: LinodeClient): + """ + This is necessary because the API does not currently expose + a capability for regions that allow custom image uploads. + + In the future, we should remove this if the API exposes a custom images capability or + if all Object Storage regions support custom images. + """ + + return [ + region + for region in get_regions( + client, + capabilities={"Linodes", "Object Storage"}, + site_type="core", + ) + if region.id not in DISALLOWED_IMAGE_REGIONS + ] + @pytest.fixture(scope="session") def image_upload_url(test_linode_client): label = get_test_label() + "_image" - region = get_region( - test_linode_client, - capabilities={"Linodes", "Object Storage"}, - site_type="core", - ) + region = get_image_upload_regions(test_linode_client)[0] test_linode_client.image_create_upload( label, region.id, "integration test image upload" @@ -38,9 +62,7 @@ def test_uploaded_image(test_linode_client): label = get_test_label() + "_image" - regions = get_regions( - test_linode_client, capabilities={"Object Storage"}, site_type="core" - ) + regions = get_image_upload_regions(test_linode_client) image = test_linode_client.image_upload( label, diff --git a/test/integration/models/linode/test_linode.py b/test/integration/models/linode/test_linode.py index 52d948d26..e13903e4f 100644 --- a/test/integration/models/linode/test_linode.py +++ b/test/integration/models/linode/test_linode.py @@ -180,7 +180,7 @@ def create_linode_for_long_running_tests(test_linode_client, e2e_test_firewall): def linode_with_disk_encryption(test_linode_client, request): client = test_linode_client - target_region = get_region(client, {"LA Disk Encryption"}) + target_region = get_region(client, {"Disk Encryption"}) label = get_test_label(length=8) disk_encryption = request.param @@ -235,7 +235,7 @@ def test_linode_transfer(test_linode_client, linode_with_volume_firewall): def test_linode_rebuild(test_linode_client): client = test_linode_client - region = get_region(client, {"LA Disk Encryption"}) + region = get_region(client, {"Disk Encryption"}) label = get_test_label() + "_rebuild" diff --git a/test/integration/models/lke/test_lke.py b/test/integration/models/lke/test_lke.py index 3486485d6..241117442 100644 --- a/test/integration/models/lke/test_lke.py +++ b/test/integration/models/lke/test_lke.py @@ -32,9 +32,7 @@ def lke_cluster(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"} - ) + region = get_region(test_linode_client, {"Kubernetes", "Disk Encryption"}) node_pools = test_linode_client.lke.node_pool(node_type, 3) label = get_test_label() + "_cluster" @@ -117,9 +115,7 @@ def lke_cluster_with_labels_and_taints(test_linode_client): def lke_cluster_with_apl(test_linode_client): version = test_linode_client.lke.versions()[0] - region = get_region( - test_linode_client, {"Kubernetes", "LA Disk Encryption"} - ) + region = get_region(test_linode_client, {"Kubernetes", "Disk Encryption"}) # NOTE: g6-dedicated-4 is the minimum APL-compatible Linode type node_pools = test_linode_client.lke.node_pool("g6-dedicated-4", 3) @@ -149,7 +145,7 @@ def lke_cluster_enterprise(test_linode_client): )[0] region = get_region( - test_linode_client, {"Kubernetes Enterprise", "LA Disk Encryption"} + test_linode_client, {"Kubernetes Enterprise", "Disk Encryption"} ) node_pools = test_linode_client.lke.node_pool( diff --git a/test/integration/models/networking/test_networking.py b/test/integration/models/networking/test_networking.py index b92cdfadc..87a0e5842 100644 --- a/test/integration/models/networking/test_networking.py +++ b/test/integration/models/networking/test_networking.py @@ -235,7 +235,7 @@ def test_create_and_delete_vlan(test_linode_client, linode_for_vlan_tests): config.interfaces = [] config.save() - vlan_label = "testvlan" + vlan_label = f"{get_test_label(8)}-testvlan" interface = config.interface_create_vlan( label=vlan_label, ipam_address="10.0.0.2/32" ) diff --git a/test/integration/models/nodebalancer/test_nodebalancer.py b/test/integration/models/nodebalancer/test_nodebalancer.py index df07de215..9e7537897 100644 --- a/test/integration/models/nodebalancer/test_nodebalancer.py +++ b/test/integration/models/nodebalancer/test_nodebalancer.py @@ -167,7 +167,9 @@ def test_update_nb(test_linode_client, create_nb): create_nb.id, ) - nb.label = "ThisNewLabel" + new_label = f"{nb.label}-ThisNewLabel" + + nb.label = new_label nb.client_udp_sess_throttle = 5 nb.save() @@ -176,7 +178,7 @@ def test_update_nb(test_linode_client, create_nb): create_nb.id, ) - assert "ThisNewLabel" == nb_updated.label + assert new_label == nb_updated.label assert 5 == nb_updated.client_udp_sess_throttle @@ -215,7 +217,10 @@ def test_update_nb_node(test_linode_client, create_nb_config): create_nb_config.nodebalancer_id, ) node = config.nodes[0] - node.label = "ThisNewLabel" + + new_label = f"{node.label}-ThisNewLabel" + + node.label = new_label node.weight = 50 node.mode = "accept" node.save() @@ -226,7 +231,7 @@ def test_update_nb_node(test_linode_client, create_nb_config): (create_nb_config.id, create_nb_config.nodebalancer_id), ) - assert "ThisNewLabel" == node_updated.label + assert new_label == node_updated.label assert 50 == node_updated.weight assert "accept" == node_updated.mode From 2d3027728e6e637e140db40caba545b7d9b1ca2b Mon Sep 17 00:00:00 2001 From: Lena Garber <114949949+lgarber-akamai@users.noreply.github.com> Date: Mon, 8 Sep 2025 12:43:39 -0400 Subject: [PATCH 6/6] Add no-osl-1 to image test disallow list (#593) --- test/integration/models/image/test_image.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/integration/models/image/test_image.py b/test/integration/models/image/test_image.py index 58da0a56f..18e223ff0 100644 --- a/test/integration/models/image/test_image.py +++ b/test/integration/models/image/test_image.py @@ -13,6 +13,7 @@ "au-mel", "sg-sin-2", "jp-tyo-3", + "no-osl-1", }