From 8ea6cc1bd9764ee84f26dae720ad9a89d4d42c2a Mon Sep 17 00:00:00 2001 From: Zhiwei Liang Date: Tue, 21 Apr 2026 20:53:33 -0400 Subject: [PATCH] feat: add locks field to various resources --- instances.go | 2 +- lke_clusters.go | 3 +++ lke_node_pools.go | 3 +++ test/unit/fixtures/lke_cluster_get.json | 1 + test/unit/fixtures/lke_cluster_list.json | 4 +++- test/unit/fixtures/lke_node_pool_get.json | 1 + test/unit/fixtures/lke_node_pool_list.json | 2 ++ test/unit/fixtures/volume_get.json | 1 + test/unit/fixtures/volumes_list.json | 1 + test/unit/lke_clusters_test.go | 3 +++ test/unit/lke_node_pools_test.go | 3 +++ test/unit/volume_test.go | 2 ++ volumes.go | 3 +++ 13 files changed, 27 insertions(+), 2 deletions(-) diff --git a/instances.go b/instances.go index 5fb512e61..b694dc1d1 100644 --- a/instances.go +++ b/instances.go @@ -75,7 +75,7 @@ type Instance struct { InterfaceGeneration InterfaceGeneration `json:"interface_generation"` MaintenancePolicy string `json:"maintenance_policy"` - // NOTE: Locks can only be used with v4beta. + // NOTE: Both cannot_delete and cannot_delete_with_subresources apply to Instances and can only be used with v4beta. Locks []LockType `json:"locks"` } diff --git a/lke_clusters.go b/lke_clusters.go index 786b6faaf..4a09099de 100644 --- a/lke_clusters.go +++ b/lke_clusters.go @@ -47,6 +47,9 @@ type LKECluster struct { SubnetID int `json:"subnet_id"` VpcID int `json:"vpc_id"` StackType LKEClusterStackType `json:"stack_type"` + + // NOTE: Locks can only be used with v4beta. + Locks []LockType `json:"locks"` } // LKEClusterCreateOptions fields are those accepted by CreateLKECluster diff --git a/lke_node_pools.go b/lke_node_pools.go index b50507d6d..85f43c153 100644 --- a/lke_node_pools.go +++ b/lke_node_pools.go @@ -83,6 +83,9 @@ type LKENodePool struct { // It may not currently be available to all users and is under v4beta. K8sVersion *string `json:"k8s_version,omitempty"` UpdateStrategy *LKENodePoolUpdateStrategy `json:"update_strategy,omitempty"` + + // NOTE: Only cannot_delete applies to LKE node pools and can only be used with v4beta. + Locks []LockType `json:"locks"` } // LKENodePoolCreateOptions fields are those accepted by CreateLKENodePool diff --git a/test/unit/fixtures/lke_cluster_get.json b/test/unit/fixtures/lke_cluster_get.json index 965ed4cea..162e6ce35 100644 --- a/test/unit/fixtures/lke_cluster_get.json +++ b/test/unit/fixtures/lke_cluster_get.json @@ -3,6 +3,7 @@ "label": "test-cluster", "region": "us-east", "status": "ready", + "locks": ["cannot_delete"], "subnet_id": 123, "vpc_id": 456, "stack_type": "ipv4", diff --git a/test/unit/fixtures/lke_cluster_list.json b/test/unit/fixtures/lke_cluster_list.json index ccce5dc00..b616525e8 100644 --- a/test/unit/fixtures/lke_cluster_list.json +++ b/test/unit/fixtures/lke_cluster_list.json @@ -5,6 +5,7 @@ "label": "test-cluster", "region": "us-east", "status": "ready", + "locks": ["cannot_delete"], "subnet_id": 123, "vpc_id": 456, "stack_type": "ipv4", @@ -16,7 +17,8 @@ "id": 124, "label": "second-cluster", "region": "us-west", - "status": "not_ready" + "status": "not_ready", + "locks": [] } ], "pages": 1, diff --git a/test/unit/fixtures/lke_node_pool_get.json b/test/unit/fixtures/lke_node_pool_get.json index fca17440e..7a5592a4a 100644 --- a/test/unit/fixtures/lke_node_pool_get.json +++ b/test/unit/fixtures/lke_node_pool_get.json @@ -2,6 +2,7 @@ "id": 456, "count": 3, "type": "g6-standard-2", + "locks": ["cannot_delete"], "tags": ["tag1", "tag2"], "labels": {"env": "staging"}, "autoscaler": { diff --git a/test/unit/fixtures/lke_node_pool_list.json b/test/unit/fixtures/lke_node_pool_list.json index 5bb78aada..00f3bbc1f 100644 --- a/test/unit/fixtures/lke_node_pool_list.json +++ b/test/unit/fixtures/lke_node_pool_list.json @@ -4,6 +4,7 @@ "id": 456, "count": 3, "type": "g6-standard-2", + "locks": ["cannot_delete"], "tags": ["tag1"], "labels": {"env": "staging"}, "autoscaler": {"enabled": true, "min": 1, "max": 5} @@ -12,6 +13,7 @@ "id": 789, "count": 2, "type": "g6-standard-4", + "locks": [], "tags": ["tag2"], "labels": {"env": "prod"}, "autoscaler": {"enabled": false, "min": 0, "max": 0} diff --git a/test/unit/fixtures/volume_get.json b/test/unit/fixtures/volume_get.json index 22b539875..ae39a4f48 100644 --- a/test/unit/fixtures/volume_get.json +++ b/test/unit/fixtures/volume_get.json @@ -7,6 +7,7 @@ "linode_id": null, "filesystem_path": "", "tags": ["test"], + "locks": ["cannot_delete_with_subresources"], "hardware_type": "", "linode_label": "", "encryption": "", diff --git a/test/unit/fixtures/volumes_list.json b/test/unit/fixtures/volumes_list.json index d60f8949a..256113776 100644 --- a/test/unit/fixtures/volumes_list.json +++ b/test/unit/fixtures/volumes_list.json @@ -9,6 +9,7 @@ "linode_id": null, "filesystem_path": "", "tags": ["test"], + "locks": ["cannot_delete"], "hardware_type": "", "linode_label": "", "encryption": "", diff --git a/test/unit/lke_clusters_test.go b/test/unit/lke_clusters_test.go index 0dfad0d51..63e09edd7 100644 --- a/test/unit/lke_clusters_test.go +++ b/test/unit/lke_clusters_test.go @@ -65,7 +65,9 @@ func TestLKECluster_List(t *testing.T) { assert.Equal(t, 123, clusters[0].SubnetID) assert.Equal(t, 456, clusters[0].VpcID) assert.Equal(t, linodego.LKEClusterStackIPv4, clusters[0].StackType) + assert.Equal(t, []linodego.LockType{linodego.LockTypeCannotDelete}, clusters[0].Locks) assert.Equal(t, false, clusters[0].ControlPlane.AuditLogsEnabled) + assert.Empty(t, clusters[1].Locks) } func TestLKECluster_Get(t *testing.T) { @@ -85,6 +87,7 @@ func TestLKECluster_Get(t *testing.T) { assert.Equal(t, 123, cluster.SubnetID) assert.Equal(t, 456, cluster.VpcID) assert.Equal(t, linodego.LKEClusterStackIPv4, cluster.StackType) + assert.Equal(t, []linodego.LockType{linodego.LockTypeCannotDelete}, cluster.Locks) assert.Equal(t, false, cluster.ControlPlane.AuditLogsEnabled) } diff --git a/test/unit/lke_node_pools_test.go b/test/unit/lke_node_pools_test.go index c01b63670..d2430abf8 100644 --- a/test/unit/lke_node_pools_test.go +++ b/test/unit/lke_node_pools_test.go @@ -73,6 +73,7 @@ func TestLKENodePool_Get(t *testing.T) { assert.Equal(t, "g6-standard-2", nodePool.Type) assert.Equal(t, 3, nodePool.Count) assert.Equal(t, []string{"tag1", "tag2"}, nodePool.Tags) + assert.Equal(t, []linodego.LockType{linodego.LockTypeCannotDelete}, nodePool.Locks) } func TestLKENodePool_Create(t *testing.T) { @@ -172,7 +173,9 @@ func TestLKENodePool_List(t *testing.T) { assert.NoError(t, err) assert.Len(t, nodePools, 2) assert.Equal(t, 456, nodePools[0].ID) + assert.Equal(t, []linodego.LockType{linodego.LockTypeCannotDelete}, nodePools[0].Locks) assert.Equal(t, 789, nodePools[1].ID) + assert.Empty(t, nodePools[1].Locks) } func TestLKENodePoolNode_Delete(t *testing.T) { diff --git a/test/unit/volume_test.go b/test/unit/volume_test.go index 24d5f5b0a..cf6ba8b1f 100644 --- a/test/unit/volume_test.go +++ b/test/unit/volume_test.go @@ -31,6 +31,7 @@ func TestListVolumes(t *testing.T) { assert.Equal(t, "us-east", volumes[0].Region, "Expected volume region to match") assert.Equal(t, 20, volumes[0].Size, "Expected volume size to match") assert.Equal(t, "test", volumes[0].Tags[0], "Expected volume tag to match") + assert.Equal(t, []linodego.LockType{linodego.LockTypeCannotDelete}, volumes[0].Locks, "Expected volume locks to match") } func TestGetVolume(t *testing.T) { @@ -59,6 +60,7 @@ func TestGetVolume(t *testing.T) { assert.Empty(t, volume.HardwareType, "Expected hardware type to be empty") assert.Empty(t, volume.LinodeLabel, "Expected Linode label to be empty") assert.True(t, volume.IOReady, "Expected IO Ready true") + assert.Equal(t, []linodego.LockType{linodego.LockTypeCannotDeleteWithSubresources}, volume.Locks, "Expected volume locks to match") } func TestCreateVolume(t *testing.T) { diff --git a/volumes.go b/volumes.go index 2fc8fc802..32591c199 100644 --- a/volumes.go +++ b/volumes.go @@ -41,6 +41,9 @@ type Volume struct { Created *time.Time `json:"-"` Updated *time.Time `json:"-"` Encryption string `json:"encryption"` + + // NOTE: Locks can only be used with v4beta. + Locks []LockType `json:"locks"` } // VolumeCreateOptions fields are those accepted by CreateVolume