Skip to content

new: Add support for Placement Groups - #396

Merged
lgarber-akamai merged 23 commits into
linode:proj/vm-placementfrom
lgarber-akamai:new/vm-placement
May 1, 2024
Merged

new: Add support for Placement Groups#396
lgarber-akamai merged 23 commits into
linode:proj/vm-placementfrom
lgarber-akamai:new/vm-placement

Conversation

@lgarber-akamai

@lgarber-akamai lgarber-akamai commented Apr 16, 2024

Copy link
Copy Markdown
Contributor

📝 Description

This pull request adds support for the upcoming Placement Groups feature, including the following changes:

  • New Endpoints:

    • POST placement/groups
    • GET placement/groups
    • GET placement/groups/{pg_id}
    • PUT placement/groups/{pg_id}
    • POST placement/groups/{pg_id}/assign
    • POST placement/groups/{pg_id}/unassign
    • DELETE placement/groups/{pg_id}
  • Updated Endpoints:

    • GET /linode/instances & /linode/instances/{linode_id} - Updated to include PG info
    • POST /linode/instances - Updated to accept a PG to assign the Linode to on creation
    • POST /linode/instances/{linode_id}/migrate - Updated to accept a PG to assign the Linode to on creation
    • POST /linode/instances/{linode_id}/clone - Updated to accept a PG to assign the Linode to on creation
    • GET /regions & /regions/{region_id} - Updated to include PG limits

This pull request also contains the corresponding unit and integration tests.

✔️ How to Test

The following test steps assume you have pulled down this PR locally and run make install.

Additionally, these tests will not currently run against production so the target API URL will need to be overridden.
e.g.

export LINODE_API_URL=https://.../v4beta
export LINODE_API_CA=$PWD/cacert.pem
export LINODE_TOKEN=...

Unit Testing

make testunit

Integration Testing

make INTEGRATION_TEST_PATH=models/test_placement.py testint

Manual Testing

  1. In a linode_api4 sandbox environment (e.g. dx-devenv), run the following:
import os

from linode_api4 import LinodeClient, PlacementGroupAffinityType

client = LinodeClient(
    os.getenv("LINODE_TOKEN"),
    base_url="https://.../v4beta",
    ca_path="cacert.pem"
)

placement_group = client.placement.group_create(
    "test-pg",
    "eu-west",
    PlacementGroupAffinityType.anti_affinity_local
)

instance = client.linode.instance_create(
    "g6-nanode-1",
    placement_group.region,
    label="test-instance",
    placement_group=placement_group,
)

# Invalidate the placement group to refresh the members
placement_group.invalidate()

print(instance)
print(placement_group)
print("Instance.placement_group:", instance.placement_group)
print("PG.members:", placement_group.members)
  1. Ensure the output looks similar to the following:
Instance: 25137082
PlacementGroup: 597
Instance.placement_group: PlacementGroup: 597
PG.members: [PlacementGroupMember(linode_id=25137082, is_compliant=True)]
  1. Navigate to the PG & Instance in Cloud Manager and ensure everything is configured as expected.
  2. Alter the script to test other features added in this PR.

from linode_api4.objects.region import Region


class PlacementAPIGroup(Group):

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not quite sure what to name this class given the convention here would be {route_name}Group, but that conflicts with PlacementGroup

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise I can think of PlacementsGroup, but I think the current naming PlacementAPIGroup is less confusing and probably the best way to go 👍

Comment thread linode_api4/objects/linode.py Outdated
return self._transfer

@property
def placement_group(self) -> Optional[PlacementGroup]:

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surely there's a way better way to do this, but for the time being we don't have a way to transform an arbitrary ID into an object like we can with derived classes & slugs.



@dataclass
class PlacementGroupMember(JSONObject):

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the future it'd be nice to have a property method to access the underlying Linode object from here.

@lgarber-akamai
lgarber-akamai marked this pull request as ready for review April 17, 2024 18:46
@lgarber-akamai
lgarber-akamai requested a review from a team as a code owner April 17, 2024 18:46
@lgarber-akamai
lgarber-akamai requested review from yec-akamai and ykim-akamai and removed request for a team April 17, 2024 18:46
return len(vars(self))


class StrEnum(str, Enum):

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like the comment says, we can remove this in favor of the official StrEnum class once Python 3.11 is our minimum supported version 👍

@lgarber-akamai

Copy link
Copy Markdown
Contributor Author

@jriddle-linode jriddle-linode added the new-feature for new features in the changelog. label Apr 17, 2024

@yec-akamai yec-akamai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Just small comments.

I'm getting 500: Internal server error currently when running the integration tests. It's probably an api issue ongoing? Will try again later.

from linode_api4.objects.region import Region


class PlacementAPIGroup(Group):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise I can think of PlacementsGroup, but I think the current naming PlacementAPIGroup is less confusing and probably the best way to go 👍

Comment thread linode_api4/groups/placement.py Outdated
@lgarber-akamai

lgarber-akamai commented Apr 24, 2024

Copy link
Copy Markdown
Contributor Author

LGTM! Just small comments.

I'm getting 500: Internal server error currently when running the integration tests. It's probably an api issue ongoing? Will try again later.

@yec-akamai Assuming you're running against Alpha it's probably an API issue. I'll look into it and let you know once it's been fixed 👍

edit: Just confirmed this is an API error

@yec-akamai yec-akamai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works well on my end!

For some reason the test region eu-west doesn't work for me. It raised linode_api4.errors.ApiError: 403: The Linode plan you chose is not currently available in the selected region. Please select another region or plan type, or contact Support for assistance. But I switched to use other region, i.e. us-east, can work and pass the tests.

@lgarber-akamai

Copy link
Copy Markdown
Contributor Author

Works well on my end!

For some reason the test region eu-west doesn't work for me. It raised linode_api4.errors.ApiError: 403: The Linode plan you chose is not currently available in the selected region. Please select another region or plan type, or contact Support for assistance. But I switched to use other region, i.e. us-east, can work and pass the tests.

@yec-akamai Thanks for taking a second look! The eu-west issue is known internally so I switched over to us-east for the time being 👍

@ykim-akamai ykim-akamai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies for taking long reviewing this, verified test and manual steps locally with changing region to 'us-east'. Excellent work!

@lgarber-akamai
lgarber-akamai merged commit 0c039d8 into linode:proj/vm-placement May 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

new-feature for new features in the changelog.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants