Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for migrations field for Placement Groups #617

Merged
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
27 changes: 20 additions & 7 deletions placement_groups.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,26 @@ type PlacementGroupMember struct {

// PlacementGroup represents a Linode placement group.
type PlacementGroup struct {
ID int `json:"id"`
Label string `json:"label"`
Region string `json:"region"`
PlacementGroupType PlacementGroupType `json:"placement_group_type"`
PlacementGroupPolicy PlacementGroupPolicy `json:"placement_group_policy"`
IsCompliant bool `json:"is_compliant"`
Members []PlacementGroupMember `json:"members"`
ID int `json:"id"`
Label string `json:"label"`
Region string `json:"region"`
PlacementGroupType PlacementGroupType `json:"placement_group_type"`
PlacementGroupPolicy PlacementGroupPolicy `json:"placement_group_policy"`
IsCompliant bool `json:"is_compliant"`
Members []PlacementGroupMember `json:"members"`
Migrations PlacementGroupMigrations `json:"migrations"`
}

// PlacementGroupMigrations represent the instances that are being migrated to or from the placement group.
type PlacementGroupMigrations struct {
Inbound []struct {
// The unique identifier for a compute instance being migrated into the placement group.
LinodeID int `json:"linode_id"`
} `json:"inbound"`
Outbound []struct {
// The unique identifier for a compute instance being migrated out of the placement group.
LinodeID int `json:"linode_id"`
} `json:"outbound"`
}

// PlacementGroupCreateOptions represents the options to use
Expand Down
1,159 changes: 1,159 additions & 0 deletions test/integration/fixtures/TestInstance_MigrateToPG.yaml

Large diffs are not rendered by default.

103 changes: 103 additions & 0 deletions test/integration/instances_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,109 @@ func TestInstance_Migrate(t *testing.T) {
}
}

func TestInstance_MigrateToPG(t *testing.T) {
client, clientTeardown := createTestClient(t, "fixtures/TestInstance_MigrateToPG")

defer func() {
clientTeardown()
}()

regions := getRegionsWithCaps(t, client, []string{"Placement Group"})

pgOutboundCreateOpts := linodego.PlacementGroupCreateOptions{
Label: "linodego-test-" + getUniqueText(),
Region: regions[0],
PlacementGroupType: linodego.PlacementGroupTypeAntiAffinityLocal,
PlacementGroupPolicy: linodego.PlacementGroupPolicyFlexible,
}

pgOutbound, err := client.CreatePlacementGroup(context.Background(), pgOutboundCreateOpts)
if err != nil {
t.Fatalf("failed to create placement group: %s", err)
}

instanceCreateOpts := linodego.InstanceCreateOptions{
Label: "go-test-ins-" + randLabel(),
RootPass: randPassword(),
Region: regions[0],
Type: "g6-nanode-1",
Image: "linode/debian9",
Booted: linodego.Pointer(true),
PlacementGroup: &linodego.InstanceCreatePlacementGroupOptions{
ID: pgOutbound.ID,
},
}

instance, err := client.CreateInstance(context.Background(), instanceCreateOpts)
if err != nil {
t.Fatalf("failed to create instance: %s", err)
}

instance, err = client.WaitForInstanceStatus(
context.Background(),
instance.ID,
linodego.InstanceRunning,
180,
)
if err != nil {
t.Errorf("Error waiting for instance readiness for migration: %s", err.Error())
}

pgInboundCreateOpts := linodego.PlacementGroupCreateOptions{
Label: "linodego-test-" + getUniqueText(),
Region: regions[1],
PlacementGroupType: linodego.PlacementGroupTypeAntiAffinityLocal,
PlacementGroupPolicy: linodego.PlacementGroupPolicyFlexible,
}

pgInbound, err := client.CreatePlacementGroup(context.Background(), pgInboundCreateOpts)
if err != nil {
t.Fatalf("failed to create placement group: %s", err)
}

upgrade := false

err = client.MigrateInstance(
context.Background(),
instance.ID,
linodego.InstanceMigrateOptions{
Type: "cold",
Region: regions[1],
Upgrade: &upgrade,
PlacementGroup: &linodego.InstanceCreatePlacementGroupOptions{ID: pgInbound.ID},
},
)
if err != nil {
t.Errorf("failed to migrate instance %d: %v", instance.ID, err.Error())
}

pgInboundRefreshed, err := client.GetPlacementGroup(context.Background(), pgInbound.ID)
if err != nil {
t.Fatalf("failed to get placement group: %s", err)
}

pgOutboundRefreshed, err := client.GetPlacementGroup(context.Background(), pgOutbound.ID)
if err != nil {
t.Fatalf("failed to get placement group: %s", err)
}

require.Equal(t, pgInboundRefreshed.ID, pgInbound.ID)
require.Equal(t, pgInboundRefreshed.Migrations.Inbound[0].LinodeID, instance.ID)
require.Equal(t, pgOutboundRefreshed.Migrations.Outbound[0].LinodeID, instance.ID)

if err := client.DeleteInstance(context.Background(), instance.ID); err != nil {
t.Errorf("failed to delete instance: %s", err)
}

if err := client.DeletePlacementGroup(context.Background(), pgInboundRefreshed.ID); err != nil {
t.Errorf("failed to delete placement group: %s", err)
}

if err := client.DeletePlacementGroup(context.Background(), pgOutboundRefreshed.ID); err != nil {
t.Errorf("failed to delete placement group: %s", err)
}
}

func TestInstance_Disks_List(t *testing.T) {
client, instance, teardown, err := setupInstance(t, "fixtures/TestInstance_Disks_List", true)
defer teardown()
Expand Down
18 changes: 18 additions & 0 deletions test/unit/fixtures/placement_group_assign.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"id": 528,
"is_compliant": true,
"label": "PG_Miami_failover",
"members": [
{
"is_compliant": true,
"linode_id": 123
},
{
"is_compliant": true,
"linode_id": 456
}
],
"placement_group_policy": "strict",
"placement_group_type": "anti-affinity:local",
"region": "us-mia"
}
14 changes: 14 additions & 0 deletions test/unit/fixtures/placement_group_create.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"id": 528,
"is_compliant": true,
"label": "PG_Miami_failover",
"members": [
{
"is_compliant": true,
"linode_id": 123
}
],
"placement_group_policy": "strict",
"placement_group_type": "anti-affinity:local",
"region": "us-mia"
}
14 changes: 14 additions & 0 deletions test/unit/fixtures/placement_group_unassign.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"id": 528,
"is_compliant": true,
"label": "PG_Miami_failover",
"members": [
{
"is_compliant": true,
"linode_id": 123
}
],
"placement_group_policy": "strict",
"placement_group_type": "anti-affinity:local",
"region": "us-mia"
}
14 changes: 14 additions & 0 deletions test/unit/fixtures/placement_group_update.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"id": 528,
"is_compliant": true,
"label": "PG_Miami_failover_new",
"members": [
{
"is_compliant": true,
"linode_id": 123
}
],
"placement_group_policy": "strict",
"placement_group_type": "anti-affinity:local",
"region": "us-mia"
}
26 changes: 26 additions & 0 deletions test/unit/fixtures/placement_groups_get.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"id": 528,
"is_compliant": true,
"label": "PG_Miami_failover",
"members": [
{
"is_compliant": true,
"linode_id": 123
}
],
"migrations": {
"inbound": [
{
"linode_id": 123
}
],
"outbound": [
{
"linode_id": 456
}
]
},
"placement_group_policy": "strict",
"placement_group_type": "anti-affinity:local",
"region": "us-mia"
}
33 changes: 33 additions & 0 deletions test/unit/fixtures/placement_groups_list.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"data": [
{
"id": 528,
"is_compliant": true,
"label": "PG_Miami_failover",
"members": [
{
"is_compliant": true,
"linode_id": 123
}
],
"migrations": {
"inbound": [
{
"linode_id": 123
}
],
"outbound": [
{
"linode_id": 456
}
]
},
"placement_group_policy": "strict",
"placement_group_type": "anti-affinity:local",
"region": "us-mia"
}
],
"page": 1,
"pages": 1,
"results": 1
}
Loading