From bf2614f3e197ef4801a2882c52468f060d292888 Mon Sep 17 00:00:00 2001 From: Ye Chen Date: Fri, 23 Jan 2026 12:20:23 -0500 Subject: [PATCH 1/3] linode alerts --- instances.go | 23 +++++++++--- test/unit/fixtures/instance_clone.json | 11 +++++- test/unit/fixtures/instance_create.json | 11 +++++- test/unit/fixtures/instance_get.json | 11 +++++- test/unit/fixtures/instance_update.json | 11 +++++- test/unit/instance_test.go | 48 +++++++++++++++++++++++++ 6 files changed, 106 insertions(+), 9 deletions(-) diff --git a/instances.go b/instances.go index 7a1352790..3810e2114 100644 --- a/instances.go +++ b/instances.go @@ -98,11 +98,13 @@ type InstanceSpec struct { // InstanceAlert represents a metric alert type InstanceAlert struct { - CPU int `json:"cpu"` - IO int `json:"io"` - NetworkIn int `json:"network_in"` - NetworkOut int `json:"network_out"` - TransferQuota int `json:"transfer_quota"` + CPU int `json:"cpu"` + IO int `json:"io"` + NetworkIn int `json:"network_in"` + NetworkOut int `json:"network_out"` + TransferQuota int `json:"transfer_quota"` + SystemAlerts *[]int `json:"system_alerts,omitempty"` + UserAlerts *[]int `json:"user_alerts,omitempty"` } // InstanceBackup represents backup settings for an instance @@ -228,6 +230,14 @@ type InstanceCreateOptions struct { // NOTE: MaintenancePolicy can only be used with v4beta. MaintenancePolicy *string `json:"maintenance_policy,omitempty"` + + // Note: Alerts can only be used with v4beta. + Alerts *InstanceAlertsOptions `json:"alerts,omitempty"` +} + +type InstanceAlertsOptions struct { + SystemAlerts *[]int `json:"system_alerts,omitempty"` + UserAlerts *[]int `json:"user_alerts,omitempty"` } // InstanceCreatePlacementGroupOptions represents the placement group @@ -403,6 +413,9 @@ type InstanceCloneOptions struct { // Deprecated: group is a deprecated property denoting a group label for the Linode. Group string `json:"group,omitempty"` + + // Note: Alerts can only be used with v4beta. + Alerts *InstanceAlertsOptions `json:"alerts,omitempty"` } // InstanceResizeOptions is an options struct used when resizing an instance diff --git a/test/unit/fixtures/instance_clone.json b/test/unit/fixtures/instance_clone.json index 3fc031976..c09a233f7 100644 --- a/test/unit/fixtures/instance_clone.json +++ b/test/unit/fixtures/instance_clone.json @@ -4,5 +4,14 @@ "region": "us-east", "type": "g6-standard-1", "status": "provisioning", - "maintenance_policy": "linode/migrate" + "maintenance_policy": "linode/migrate", + "alerts": { + "cpu": 0, + "io": 0, + "network_in": 0, + "network_out": 0, + "transfer_quota": 0, + "system_alerts": [123,456], + "user_alerts": [555] + } } diff --git a/test/unit/fixtures/instance_create.json b/test/unit/fixtures/instance_create.json index a145a9b01..7a9248b8a 100644 --- a/test/unit/fixtures/instance_create.json +++ b/test/unit/fixtures/instance_create.json @@ -4,5 +4,14 @@ "region": "us-east", "type": "g6-standard-1", "status": "provisioning", - "maintenance_policy": "linode/migrate" + "maintenance_policy": "linode/migrate", + "alerts": { + "cpu": 0, + "io": 0, + "network_in": 0, + "network_out": 0, + "transfer_quota": 0, + "system_alerts": [123,456], + "user_alerts": [555] + } } diff --git a/test/unit/fixtures/instance_get.json b/test/unit/fixtures/instance_get.json index 419ee7633..0c6c8d89c 100644 --- a/test/unit/fixtures/instance_get.json +++ b/test/unit/fixtures/instance_get.json @@ -17,5 +17,14 @@ "placement_group": { "migrating_to": 2468 }, - "maintenance_policy": "linode/migrate" + "maintenance_policy": "linode/migrate", + "alerts": { + "cpu": 0, + "io": 0, + "network_in": 0, + "network_out": 0, + "transfer_quota": 0, + "system_alerts": [123,456], + "user_alerts": [555] + } } diff --git a/test/unit/fixtures/instance_update.json b/test/unit/fixtures/instance_update.json index dca96c6ce..6da11c4ad 100644 --- a/test/unit/fixtures/instance_update.json +++ b/test/unit/fixtures/instance_update.json @@ -1,5 +1,14 @@ { "id": 123, "label": "updated-instance", - "maintenance_policy": "linode/power_off_on" + "maintenance_policy": "linode/power_off_on", + "alerts": { + "cpu": 0, + "io": 0, + "network_in": 0, + "network_out": 0, + "transfer_quota": 0, + "system_alerts": [123,456], + "user_alerts": [555] + } } diff --git a/test/unit/instance_test.go b/test/unit/instance_test.go index f10e08d6f..13a3caf56 100644 --- a/test/unit/instance_test.go +++ b/test/unit/instance_test.go @@ -77,6 +77,15 @@ func TestInstance_Get(t *testing.T) { assert.Equal(t, "linode/migrate", instance.MaintenancePolicy) require.NotNil(t, instance.PlacementGroup.MigratingTo) assert.Equal(t, 2468, *instance.PlacementGroup.MigratingTo) + if instance.Alerts.SystemAlerts != nil { + systemAlerts := *instance.Alerts.SystemAlerts + assert.Equal(t, 123, systemAlerts[0]) + assert.Equal(t, 456, systemAlerts[1]) + } + if instance.Alerts.UserAlerts != nil { + userAlerts := *instance.Alerts.UserAlerts + assert.Equal(t, 555, userAlerts[0]) + } } func TestInstance_Migrate(t *testing.T) { @@ -180,6 +189,10 @@ func TestInstance_Create(t *testing.T) { Image: "linode/ubuntu22.04", RootPass: "securepassword", MaintenancePolicy: linodego.Pointer("linode/migrate"), + Alerts: &linodego.InstanceAlertsOptions{ + SystemAlerts: &[]int{123, 456}, + UserAlerts: &[]int{555}, + }, } base.MockPost("linode/instances", fixtureData) @@ -188,6 +201,15 @@ func TestInstance_Create(t *testing.T) { assert.NoError(t, err) assert.Equal(t, "new-instance", instance.Label) assert.Equal(t, "linode/migrate", instance.MaintenancePolicy) + if instance.Alerts.SystemAlerts != nil { + systemAlerts := *instance.Alerts.SystemAlerts + assert.Equal(t, 123, systemAlerts[0]) + assert.Equal(t, 456, systemAlerts[1]) + } + if instance.Alerts.UserAlerts != nil { + userAlerts := *instance.Alerts.UserAlerts + assert.Equal(t, 555, userAlerts[0]) + } } func TestInstance_Update(t *testing.T) { @@ -201,6 +223,10 @@ func TestInstance_Update(t *testing.T) { updateOptions := linodego.InstanceUpdateOptions{ Label: "updated-instance", MaintenancePolicy: linodego.Pointer("linode/power_off_on"), + Alerts: &linodego.InstanceAlert{ + SystemAlerts: &[]int{123, 456}, + UserAlerts: &[]int{555}, + }, } base.MockPut("linode/instances/123", fixtureData) @@ -209,6 +235,15 @@ func TestInstance_Update(t *testing.T) { assert.NoError(t, err) assert.Equal(t, "updated-instance", instance.Label) assert.Equal(t, "linode/power_off_on", instance.MaintenancePolicy) + if instance.Alerts.SystemAlerts != nil { + systemAlerts := *instance.Alerts.SystemAlerts + assert.Equal(t, 123, systemAlerts[0]) + assert.Equal(t, 456, systemAlerts[1]) + } + if instance.Alerts.UserAlerts != nil { + userAlerts := *instance.Alerts.UserAlerts + assert.Equal(t, 555, userAlerts[0]) + } } func TestInstance_Delete(t *testing.T) { @@ -256,6 +291,10 @@ func TestInstance_Clone(t *testing.T) { Region: "us-east", Type: "g6-standard-1", Label: "cloned-instance", + Alerts: &linodego.InstanceAlertsOptions{ + SystemAlerts: &[]int{123, 456}, + UserAlerts: &[]int{555}, + }, } base.MockPost("linode/instances/123/clone", fixtureData) @@ -264,6 +303,15 @@ func TestInstance_Clone(t *testing.T) { assert.NoError(t, err) assert.Equal(t, "cloned-instance", instance.Label) assert.Equal(t, "linode/migrate", instance.MaintenancePolicy) + if instance.Alerts.SystemAlerts != nil { + systemAlerts := *instance.Alerts.SystemAlerts + assert.Equal(t, 123, systemAlerts[0]) + assert.Equal(t, 456, systemAlerts[1]) + } + if instance.Alerts.UserAlerts != nil { + userAlerts := *instance.Alerts.UserAlerts + assert.Equal(t, 555, userAlerts[0]) + } } func TestInstance_Resize(t *testing.T) { From ab26fb38791b2aff2f1bebe50b62144305313fdf Mon Sep 17 00:00:00 2001 From: Ye Chen Date: Fri, 23 Jan 2026 12:26:57 -0500 Subject: [PATCH 2/3] add docs --- instances.go | 7 ++++--- test/unit/instance_test.go | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/instances.go b/instances.go index 3810e2114..04c5239ad 100644 --- a/instances.go +++ b/instances.go @@ -232,10 +232,11 @@ type InstanceCreateOptions struct { MaintenancePolicy *string `json:"maintenance_policy,omitempty"` // Note: Alerts can only be used with v4beta. - Alerts *InstanceAlertsOptions `json:"alerts,omitempty"` + Alerts *InstanceACLPAlertsOptions `json:"alerts,omitempty"` } -type InstanceAlertsOptions struct { +// InstanceACLPAlertsOptions represents ACLP alerts options for instance creation and cloning. +type InstanceACLPAlertsOptions struct { SystemAlerts *[]int `json:"system_alerts,omitempty"` UserAlerts *[]int `json:"user_alerts,omitempty"` } @@ -415,7 +416,7 @@ type InstanceCloneOptions struct { Group string `json:"group,omitempty"` // Note: Alerts can only be used with v4beta. - Alerts *InstanceAlertsOptions `json:"alerts,omitempty"` + Alerts *InstanceACLPAlertsOptions `json:"alerts,omitempty"` } // InstanceResizeOptions is an options struct used when resizing an instance diff --git a/test/unit/instance_test.go b/test/unit/instance_test.go index 13a3caf56..bca1120cb 100644 --- a/test/unit/instance_test.go +++ b/test/unit/instance_test.go @@ -189,7 +189,7 @@ func TestInstance_Create(t *testing.T) { Image: "linode/ubuntu22.04", RootPass: "securepassword", MaintenancePolicy: linodego.Pointer("linode/migrate"), - Alerts: &linodego.InstanceAlertsOptions{ + Alerts: &linodego.InstanceACLPAlertsOptions{ SystemAlerts: &[]int{123, 456}, UserAlerts: &[]int{555}, }, @@ -291,7 +291,7 @@ func TestInstance_Clone(t *testing.T) { Region: "us-east", Type: "g6-standard-1", Label: "cloned-instance", - Alerts: &linodego.InstanceAlertsOptions{ + Alerts: &linodego.InstanceACLPAlertsOptions{ SystemAlerts: &[]int{123, 456}, UserAlerts: &[]int{555}, }, From c096fa3bb339469ae034166699af980e741a1b5a Mon Sep 17 00:00:00 2001 From: Ye Chen Date: Fri, 23 Jan 2026 12:34:18 -0500 Subject: [PATCH 3/3] address comments --- test/unit/fixtures/interface_list.json | 9 +++++ test/unit/instance_test.go | 53 ++++++++++++++++++++------ 2 files changed, 50 insertions(+), 12 deletions(-) diff --git a/test/unit/fixtures/interface_list.json b/test/unit/fixtures/interface_list.json index 1f86dad65..597487c6f 100644 --- a/test/unit/fixtures/interface_list.json +++ b/test/unit/fixtures/interface_list.json @@ -15,6 +15,15 @@ "vlan": { "vlan_label": "my_vlan", "ipam_address": "10.0.0.1/24" + }, + "alerts": { + "cpu": 0, + "io": 0, + "network_in": 0, + "network_out": 0, + "transfer_quota": 0, + "system_alerts": [123,456], + "user_alerts": [555] } }, { diff --git a/test/unit/instance_test.go b/test/unit/instance_test.go index bca1120cb..d21449b96 100644 --- a/test/unit/instance_test.go +++ b/test/unit/instance_test.go @@ -44,6 +44,19 @@ func TestInstances_List(t *testing.T) { require.NotNil(t, linode.PlacementGroup.MigratingTo) assert.Equal(t, 2468, *linode.PlacementGroup.MigratingTo) assert.Equal(t, "linode/migrate", linode.MaintenancePolicy) + if linode.Alerts.SystemAlerts != nil { + systemAlerts := *linode.Alerts.SystemAlerts + if len(systemAlerts) > 2 { + assert.Equal(t, 123, systemAlerts[0]) + assert.Equal(t, 456, systemAlerts[1]) + } + } + if linode.Alerts.UserAlerts != nil { + userAlerts := *linode.Alerts.UserAlerts + if len(userAlerts) > 0 { + assert.Equal(t, 555, userAlerts[0]) + } + } } func TestInstance_Get(t *testing.T) { @@ -79,12 +92,16 @@ func TestInstance_Get(t *testing.T) { assert.Equal(t, 2468, *instance.PlacementGroup.MigratingTo) if instance.Alerts.SystemAlerts != nil { systemAlerts := *instance.Alerts.SystemAlerts - assert.Equal(t, 123, systemAlerts[0]) - assert.Equal(t, 456, systemAlerts[1]) + if len(systemAlerts) > 2 { + assert.Equal(t, 123, systemAlerts[0]) + assert.Equal(t, 456, systemAlerts[1]) + } } if instance.Alerts.UserAlerts != nil { userAlerts := *instance.Alerts.UserAlerts - assert.Equal(t, 555, userAlerts[0]) + if len(userAlerts) > 0 { + assert.Equal(t, 555, userAlerts[0]) + } } } @@ -203,12 +220,16 @@ func TestInstance_Create(t *testing.T) { assert.Equal(t, "linode/migrate", instance.MaintenancePolicy) if instance.Alerts.SystemAlerts != nil { systemAlerts := *instance.Alerts.SystemAlerts - assert.Equal(t, 123, systemAlerts[0]) - assert.Equal(t, 456, systemAlerts[1]) + if len(systemAlerts) > 2 { + assert.Equal(t, 123, systemAlerts[0]) + assert.Equal(t, 456, systemAlerts[1]) + } } if instance.Alerts.UserAlerts != nil { userAlerts := *instance.Alerts.UserAlerts - assert.Equal(t, 555, userAlerts[0]) + if len(userAlerts) > 0 { + assert.Equal(t, 555, userAlerts[0]) + } } } @@ -237,12 +258,16 @@ func TestInstance_Update(t *testing.T) { assert.Equal(t, "linode/power_off_on", instance.MaintenancePolicy) if instance.Alerts.SystemAlerts != nil { systemAlerts := *instance.Alerts.SystemAlerts - assert.Equal(t, 123, systemAlerts[0]) - assert.Equal(t, 456, systemAlerts[1]) + if len(systemAlerts) > 2 { + assert.Equal(t, 123, systemAlerts[0]) + assert.Equal(t, 456, systemAlerts[1]) + } } if instance.Alerts.UserAlerts != nil { userAlerts := *instance.Alerts.UserAlerts - assert.Equal(t, 555, userAlerts[0]) + if len(userAlerts) > 0 { + assert.Equal(t, 555, userAlerts[0]) + } } } @@ -305,12 +330,16 @@ func TestInstance_Clone(t *testing.T) { assert.Equal(t, "linode/migrate", instance.MaintenancePolicy) if instance.Alerts.SystemAlerts != nil { systemAlerts := *instance.Alerts.SystemAlerts - assert.Equal(t, 123, systemAlerts[0]) - assert.Equal(t, 456, systemAlerts[1]) + if len(systemAlerts) > 2 { + assert.Equal(t, 123, systemAlerts[0]) + assert.Equal(t, 456, systemAlerts[1]) + } } if instance.Alerts.UserAlerts != nil { userAlerts := *instance.Alerts.UserAlerts - assert.Equal(t, 555, userAlerts[0]) + if len(userAlerts) > 0 { + assert.Equal(t, 555, userAlerts[0]) + } } }