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

project: Linode Disk Encryption #541

Merged
merged 13 commits into from
Jul 23, 2024
15 changes: 8 additions & 7 deletions instance_disks.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@ import (

// InstanceDisk represents an Instance Disk object
type InstanceDisk struct {
ID int `json:"id"`
Label string `json:"label"`
Status DiskStatus `json:"status"`
Size int `json:"size"`
Filesystem DiskFilesystem `json:"filesystem"`
Created *time.Time `json:"-"`
Updated *time.Time `json:"-"`
ID int `json:"id"`
Label string `json:"label"`
Status DiskStatus `json:"status"`
Size int `json:"size"`
Filesystem DiskFilesystem `json:"filesystem"`
Created *time.Time `json:"-"`
Updated *time.Time `json:"-"`
DiskEncryption InstanceDiskEncryption `json:"disk_encryption"`
}

// DiskFilesystem constants start with Filesystem and include Linode API Filesystems
Expand Down
12 changes: 12 additions & 0 deletions instances.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ type Instance struct {

// NOTE: Placement Groups may not currently be available to all users.
PlacementGroup *InstancePlacementGroup `json:"placement_group"`

DiskEncryption InstanceDiskEncryption `json:"disk_encryption"`
LKEClusterID int `json:"lke_cluster_id"`
}

// InstanceSpec represents a linode spec
Expand Down Expand Up @@ -95,6 +98,13 @@ type InstanceBackup struct {
} `json:"schedule,omitempty"`
}

type InstanceDiskEncryption string

const (
InstanceDiskEncryptionEnabled InstanceDiskEncryption = "enabled"
InstanceDiskEncryptionDisabled InstanceDiskEncryption = "disabled"
)

// InstanceTransfer pool stats for a Linode Instance during the current billing month
type InstanceTransfer struct {
// Bytes of transfer this instance has consumed
Expand Down Expand Up @@ -141,6 +151,7 @@ type InstanceCreateOptions struct {
Tags []string `json:"tags,omitempty"`
Metadata *InstanceMetadataOptions `json:"metadata,omitempty"`
FirewallID int `json:"firewall_id,omitempty"`
DiskEncryption InstanceDiskEncryption `json:"disk_encryption,omitempty"`

// NOTE: Placement Groups may not currently be available to all users.
PlacementGroup *InstanceCreatePlacementGroupOptions `json:"placement_group,omitempty"`
Expand Down Expand Up @@ -402,6 +413,7 @@ type InstanceRebuildOptions struct {
Booted *bool `json:"booted,omitempty"`
Metadata *InstanceMetadataOptions `json:"metadata,omitempty"`
Type string `json:"type,omitempty"`
DiskEncryption InstanceDiskEncryption `json:"disk_encryption,omitempty"`
}

// RebuildInstance Deletes all Disks and Configs on this Linode,
Expand Down
30 changes: 30 additions & 0 deletions k8s/pkg/condition/lke.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,39 @@ func ClusterHasReadyNode(ctx context.Context, options linodego.ClusterConditionO
return false, nil
}

// ClusterNodesReady is a ClusterConditionFunc which polls for all nodes to have the
// condition NodeReady=True.
func ClusterNodesReady(ctx context.Context, options linodego.ClusterConditionOptions) (bool, error) {
clientset, err := k8s.BuildClientsetFromConfig(options.LKEClusterKubeconfig, options.TransportWrapper)
if err != nil {
return false, err
}

nodes, err := clientset.CoreV1().Nodes().List(ctx, v1.ListOptions{})
if err != nil {
return false, fmt.Errorf("failed to get nodes for cluster: %w", err)
}

for _, node := range nodes.Items {
for _, condition := range node.Status.Conditions {
if condition.Type == corev1.NodeReady && condition.Status != corev1.ConditionTrue {
return false, nil
}
}
}
return true, nil
}

// WaitForLKEClusterReady polls with a given timeout for the LKE Cluster's api-server
// to be healthy and for the cluster to have at least one node with the NodeReady
// condition true.
func WaitForLKEClusterReady(ctx context.Context, client linodego.Client, clusterID int, options linodego.LKEClusterPollOptions) error {
return client.WaitForLKEClusterConditions(ctx, clusterID, options, ClusterHasReadyNode)
}

// WaitForLKEClusterAndNodesReady polls with a given timeout for the LKE
// Cluster's api-server to be healthy and for all cluster nodes to have the
// NodeReady condition true.
func WaitForLKEClusterAndNodesReady(ctx context.Context, client linodego.Client, clusterID int, options linodego.LKEClusterPollOptions) error {
return client.WaitForLKEClusterConditions(ctx, clusterID, options, ClusterNodesReady)
}
3 changes: 2 additions & 1 deletion lke_node_pools.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ type LKENodePool struct {
Linodes []LKENodePoolLinode `json:"nodes"`
Tags []string `json:"tags"`

Autoscaler LKENodePoolAutoscaler `json:"autoscaler"`
Autoscaler LKENodePoolAutoscaler `json:"autoscaler"`
DiskEncryption InstanceDiskEncryption `json:"disk_encryption,omitempty"`
}

// LKENodePoolCreateOptions fields are those accepted by CreateLKENodePool
Expand Down
252 changes: 252 additions & 0 deletions test/integration/fixtures/TestInstance_DiskEncryption.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
---
version: 1
interactions:
- request:
body: ""
form: {}
headers:
Accept:
- application/json
Content-Type:
- application/json
User-Agent:
- linodego/dev https://github.com/linode/linodego
url: https://api.linode.com/v4beta/regions
method: GET
response:
body: '{"data": [{"id": "ap-west", "label": "Mumbai, India", "country": "in",
"capabilities": ["Linodes", "Backups", "NodeBalancers", "Vlans", "VPCs", "Managed
Databases"], "status": "ok", "resolvers": {"ipv4": "172.105.34.5,172.105.35.5,172.105.36.5,172.105.37.5,172.105.38.5,172.105.39.5,172.105.40.5,172.105.41.5,172.105.42.5,172.105.43.5",
"ipv6": "1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678"},
"placement_group_limits": {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg":
5}, "site_type": "core"}, {"id": "ca-central", "label": "Toronto, Ontario, CAN",
"country": "ca", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Vlans",
"VPCs", "Managed Databases"], "status": "ok", "resolvers": {"ipv4": "172.105.0.5,172.105.3.5,172.105.4.5,172.105.5.5,172.105.6.5,172.105.7.5,172.105.8.5,172.105.9.5,172.105.10.5,172.105.11.5",
"ipv6": "1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678"},
"placement_group_limits": {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg":
5}, "site_type": "core"}, {"id": "ap-southeast", "label": "Sydney, NSW, Australia",
"country": "au", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Vlans",
"VPCs", "Managed Databases"], "status": "ok", "resolvers": {"ipv4": "172.105.166.5,172.105.169.5,172.105.168.5,172.105.172.5,172.105.162.5,172.105.170.5,172.105.167.5,172.105.171.5,172.105.181.5,172.105.161.5",
"ipv6": "1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678"},
"placement_group_limits": {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg":
5}, "site_type": "core"}, {"id": "us-central", "label": "Dallas, TX, USA", "country":
"us", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Kubernetes",
"Managed Databases"], "status": "ok", "resolvers": {"ipv4": "72.14.179.5,72.14.188.5,173.255.199.5,66.228.53.5,96.126.122.5,96.126.124.5,96.126.127.5,198.58.107.5,198.58.111.5,23.239.24.5",
"ipv6": "1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678"},
"placement_group_limits": {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg":
5}, "site_type": "core"}, {"id": "us-west", "label": "Fremont, CA, USA", "country":
"us", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Managed Databases"],
"status": "ok", "resolvers": {"ipv4": "173.230.145.5,173.230.147.5,173.230.155.5,173.255.212.5,173.255.219.5,173.255.241.5,173.255.243.5,173.255.244.5,74.207.241.5,74.207.242.5",
"ipv6": "1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678"},
"placement_group_limits": {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg":
5}, "site_type": "core"}, {"id": "us-southeast", "label": "Atlanta, GA, USA",
"country": "us", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Managed
Databases"], "status": "ok", "resolvers": {"ipv4": "74.207.231.5,173.230.128.5,173.230.129.5,173.230.136.5,173.230.140.5,66.228.59.5,66.228.62.5,50.116.35.5,50.116.41.5,23.239.18.5",
"ipv6": "1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678"},
"placement_group_limits": {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg":
5}, "site_type": "core"}, {"id": "us-east", "label": "Newark, NJ, USA", "country":
"us", "capabilities": ["Linodes", "Disk Encryption", "Backups", "NodeBalancers",
"Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall",
"Bare Metal", "Vlans", "VPCs", "Block Storage Migrations", "Managed Databases",
"Placement Group"], "status": "ok", "resolvers": {"ipv4": "66.228.42.5,96.126.106.5,50.116.53.5,50.116.58.5,50.116.61.5,50.116.62.5,66.175.211.5,97.107.133.4,207.192.69.4,207.192.69.5",
"ipv6": "1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678"},
"placement_group_limits": {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg":
5}, "site_type": "core"}, {"id": "eu-west", "label": "London, England, UK",
"country": "uk", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Cloud
Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", "Placement Group"],
"status": "ok", "resolvers": {"ipv4": "178.79.182.5,176.58.107.5,176.58.116.5,176.58.121.5,151.236.220.5,212.71.252.5,212.71.253.5,109.74.192.20,109.74.193.20,109.74.194.20",
"ipv6": "1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678"},
"placement_group_limits": {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg":
5}, "site_type": "core"}, {"id": "ap-south", "label": "Singapore, SG", "country":
"sg", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Object Storage",
"Managed Databases"], "status": "ok", "resolvers": {"ipv4": "139.162.11.5,139.162.13.5,139.162.14.5,139.162.15.5,139.162.16.5,139.162.21.5,139.162.27.5,103.3.60.18,103.3.60.19,103.3.60.20",
"ipv6": "1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678"},
"placement_group_limits": {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg":
5}, "site_type": "core"}, {"id": "eu-central", "label": "Frankfurt, DE", "country":
"de", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Object Storage",
"Managed Databases"], "status": "ok", "resolvers": {"ipv4": "139.162.130.5,139.162.131.5,139.162.132.5,139.162.133.5,139.162.134.5,139.162.135.5,139.162.136.5,139.162.137.5,139.162.138.5,139.162.139.5",
"ipv6": "1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678"},
"placement_group_limits": {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg":
5}, "site_type": "core"}, {"id": "ap-northeast", "label": "Tokyo 2, JP", "country":
"jp", "capabilities": ["Linodes", "Backups", "NodeBalancers", "Managed Databases"],
"status": "ok", "resolvers": {"ipv4": "139.162.66.5,139.162.67.5,139.162.68.5,139.162.69.5,139.162.70.5,139.162.71.5,139.162.72.5,139.162.73.5,139.162.74.5,139.162.75.5",
"ipv6": "1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678,1234::5678"},
"placement_group_limits": {"maximum_pgs_per_customer": 100, "maximum_linodes_per_pg":
5}, "site_type": "core"}], "page": 1, "pages": 1, "results": 11}'
headers:
Access-Control-Allow-Credentials:
- "true"
Access-Control-Allow-Headers:
- Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter
Access-Control-Allow-Methods:
- HEAD, GET, OPTIONS, POST, PUT, DELETE
Access-Control-Allow-Origin:
- '*'
Access-Control-Expose-Headers:
- X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status
Cache-Control:
- private, max-age=900
- private, max-age=60, s-maxage=60
Connection:
- keep-alive
Content-Length:
- "7192"
Content-Security-Policy:
- default-src 'none'
Content-Type:
- application/json
Server:
- nginx
Strict-Transport-Security:
- max-age=31536000
Vary:
- Authorization, X-Filter
- Authorization, X-Filter
X-Accepted-Oauth-Scopes:
- '*'
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- DENY
- DENY
X-Oauth-Scopes:
- account:read_write databases:read_write domains:read_write events:read_write
firewall:read_write images:read_write ips:read_write linodes:read_write lke:read_write
longview:read_write nodebalancers:read_write object_storage:read_write stackscripts:read_write
volumes:read_write vpc:read_write
X-Ratelimit-Limit:
- "400"
X-Xss-Protection:
- 1; mode=block
status: 200 OK
code: 200
duration: ""
- request:
body: '{"region":"us-east","type":"g6-nanode-1","label":"go-test-ins-72053mvwvvd0","root_pass":"TKfph1YRz3$A''xB:+y:zjp95QFW$OB9^7NW29]0?evp15]f69;Cb2#7Pv0?^G`x.","image":"linode/debian9","disk_encryption":"enabled","booted":false}'
form: {}
headers:
Accept:
- application/json
Content-Type:
- application/json
User-Agent:
- linodego/dev https://github.com/linode/linodego
url: https://api.linode.com/v4beta/linode/instances
method: POST
response:
body: '{"id": 25161592, "label": "go-test-ins-72053mvwvvd0", "group": "", "status":
"provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05",
"type": "g6-nanode-1", "ipv4": ["139.144.131.14"], "ipv6": "1234::5678/128",
"image": "linode/debian9", "region": "us-east", "specs": {"disk": 25600, "memory":
1024, "vcpus": 1, "gpus": 0, "transfer": 1000}, "alerts": {"cpu": 90, "network_in":
10, "network_out": 10, "transfer_quota": 80, "io": 10000}, "backups": {"enabled":
false, "available": false, "schedule": {"day": null, "window": null}, "last_successful":
null}, "hypervisor": "kvm", "watchdog_enabled": true, "tags": [], "host_uuid":
"6f6d2db69b53136a16a2b9fa33f42654a2c5d4a7", "has_user_data": false, "placement_group":
null, "disk_encryption": "enabled"}'
headers:
Access-Control-Allow-Credentials:
- "true"
Access-Control-Allow-Headers:
- Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter
Access-Control-Allow-Methods:
- HEAD, GET, OPTIONS, POST, PUT, DELETE
Access-Control-Allow-Origin:
- '*'
Access-Control-Expose-Headers:
- X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status
Cache-Control:
- private, max-age=60, s-maxage=60
Connection:
- keep-alive
Content-Length:
- "797"
Content-Security-Policy:
- default-src 'none'
Content-Type:
- application/json
Server:
- nginx
Strict-Transport-Security:
- max-age=31536000
Vary:
- Authorization, X-Filter
X-Accepted-Oauth-Scopes:
- linodes:read_write
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- DENY
- DENY
X-Oauth-Scopes:
- account:read_write databases:read_write domains:read_write events:read_write
firewall:read_write images:read_write ips:read_write linodes:read_write lke:read_write
longview:read_write nodebalancers:read_write object_storage:read_write stackscripts:read_write
volumes:read_write vpc:read_write
X-Ratelimit-Limit:
- "10"
X-Xss-Protection:
- 1; mode=block
status: 200 OK
code: 200
duration: ""
- request:
body: ""
form: {}
headers:
Accept:
- application/json
Content-Type:
- application/json
User-Agent:
- linodego/dev https://github.com/linode/linodego
url: https://api.linode.com/v4beta/linode/instances/25161592
method: DELETE
response:
body: '{}'
headers:
Access-Control-Allow-Credentials:
- "true"
Access-Control-Allow-Headers:
- Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter
Access-Control-Allow-Methods:
- HEAD, GET, OPTIONS, POST, PUT, DELETE
Access-Control-Allow-Origin:
- '*'
Access-Control-Expose-Headers:
- X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status
Cache-Control:
- private, max-age=60, s-maxage=60
Connection:
- keep-alive
Content-Length:
- "2"
Content-Security-Policy:
- default-src 'none'
Content-Type:
- application/json
Server:
- nginx
Strict-Transport-Security:
- max-age=31536000
Vary:
- Authorization, X-Filter
X-Accepted-Oauth-Scopes:
- linodes:read_write
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- DENY
- DENY
X-Oauth-Scopes:
- account:read_write databases:read_write domains:read_write events:read_write
firewall:read_write images:read_write ips:read_write linodes:read_write lke:read_write
longview:read_write nodebalancers:read_write object_storage:read_write stackscripts:read_write
volumes:read_write vpc:read_write
X-Ratelimit-Limit:
- "400"
X-Xss-Protection:
- 1; mode=block
status: 200 OK
code: 200
duration: ""
Loading
Loading