Merge pull request #14885 from johngmyers/root-volume

v1alpha3: Move IG root volume settings to sub-struct
This commit is contained in:
Kubernetes Prow Robot 2023-01-04 18:11:58 -08:00 committed by GitHub
commit 7b4430ff61
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 427 additions and 217 deletions

View File

@ -596,13 +596,19 @@ func RunCreateCluster(ctx context.Context, f *util.Factory, out io.Writer, c *Cr
if c.ControlPlaneVolumeSize != 0 { if c.ControlPlaneVolumeSize != 0 {
for _, group := range controlPlanes { for _, group := range controlPlanes {
group.Spec.RootVolumeSize = fi.PtrTo(c.ControlPlaneVolumeSize) if group.Spec.RootVolume == nil {
group.Spec.RootVolume = &api.InstanceRootVolumeSpec{}
}
group.Spec.RootVolume.Size = fi.PtrTo(c.ControlPlaneVolumeSize)
} }
} }
if c.NodeVolumeSize != 0 { if c.NodeVolumeSize != 0 {
for _, group := range nodes { for _, group := range nodes {
group.Spec.RootVolumeSize = fi.PtrTo(c.NodeVolumeSize) if group.Spec.RootVolume == nil {
group.Spec.RootVolume = &api.InstanceRootVolumeSpec{}
}
group.Spec.RootVolume.Size = fi.PtrTo(c.NodeVolumeSize)
} }
} }

View File

@ -501,7 +501,10 @@ func decorateWithInstanceGroupSpecs(instanceGroup *kops.InstanceGroup, instanceG
ig := instanceGroup ig := instanceGroup
ig.Spec.MinSize = &instanceGroupOpts.NodeCountMin ig.Spec.MinSize = &instanceGroupOpts.NodeCountMin
ig.Spec.MaxSize = &instanceGroupOpts.NodeCountMax ig.Spec.MaxSize = &instanceGroupOpts.NodeCountMax
ig.Spec.RootVolumeSize = instanceGroupOpts.NodeVolumeSize if ig.Spec.RootVolume == nil {
ig.Spec.RootVolume = &kops.InstanceRootVolumeSpec{}
}
ig.Spec.RootVolume.Size = instanceGroupOpts.NodeVolumeSize
ig.Spec.AdditionalSecurityGroups = instanceGroupOpts.NodeSecurityGroups ig.Spec.AdditionalSecurityGroups = instanceGroupOpts.NodeSecurityGroups
return ig return ig
} }

View File

@ -165,8 +165,8 @@ func TestDecorateWithInstanceGroupSpecs(t *testing.T) {
if *actualIG.Spec.MinSize != instanceGroupOpts.NodeCountMin { if *actualIG.Spec.MinSize != instanceGroupOpts.NodeCountMin {
t.Fatalf("expected instance group MinSize to be %d but got %d", instanceGroupOpts.NodeCountMin, actualIG.Spec.MinSize) t.Fatalf("expected instance group MinSize to be %d but got %d", instanceGroupOpts.NodeCountMin, actualIG.Spec.MinSize)
} }
if *actualIG.Spec.RootVolumeSize != *instanceGroupOpts.NodeVolumeSize { if *actualIG.Spec.RootVolume.Size != *instanceGroupOpts.NodeVolumeSize {
t.Fatalf("expected instance group RootVolumeSize to be %d but got %d", instanceGroupOpts.NodeVolumeSize, actualIG.Spec.RootVolumeSize) t.Fatalf("expected instance group RootVolumeSize to be %d but got %d", instanceGroupOpts.NodeVolumeSize, actualIG.Spec.RootVolume.Size)
} }
if !reflect.DeepEqual(actualIG.Spec.AdditionalSecurityGroups, instanceGroupOpts.NodeSecurityGroups) { if !reflect.DeepEqual(actualIG.Spec.AdditionalSecurityGroups, instanceGroupOpts.NodeSecurityGroups) {
t.Fatalf("expected instance group MaxSize to be %d but got %d", instanceGroupOpts.NodeCountMax, actualIG.Spec.MaxSize) t.Fatalf("expected instance group MaxSize to be %d but got %d", instanceGroupOpts.NodeCountMax, actualIG.Spec.MaxSize)

View File

@ -355,4 +355,10 @@ the removal of fields no longer in use.
|------------------------------------------|------------------------------------------| |------------------------------------------|------------------------------------------|
| associatePublicIp | associatePublicIP | | associatePublicIp | associatePublicIP |
| externalLoadBalancers[\*].targetGroupArn | externalLoadBalancers[\*].targetGroupARN | | externalLoadBalancers[\*].targetGroupArn | externalLoadBalancers[\*].targetGroupARN |
| rootVolumeIops | rootVolumeIOPS | | rootVolumeEncryption | rootVolume.encryption |
| rootVolumeEncryptionKey | rootVolume.encryptionKey |
| rootVolumeIops | rootVolume.iops |
| rootVolumeOptimization | rootVolume.optimization |
| rootVolumeSize | rootVolume.size |
| rootVolumeThroughput | rootVolume.throughput |
| rootVolumeType | rootVolume.type |

View File

@ -108,20 +108,8 @@ type InstanceGroupSpec struct {
Autoscale *bool `json:"autoscale,omitempty"` Autoscale *bool `json:"autoscale,omitempty"`
// MachineType is the instance class // MachineType is the instance class
MachineType string `json:"machineType,omitempty"` MachineType string `json:"machineType,omitempty"`
// RootVolumeSize is the size of the EBS root volume to use, in GB // RootVolume specifies options for the instances' root volumes.
RootVolumeSize *int32 `json:"rootVolumeSize,omitempty"` RootVolume *InstanceRootVolumeSpec `json:"rootVolume,omitempty"`
// RootVolumeType is the type of the EBS root volume to use (e.g. gp2)
RootVolumeType *string `json:"rootVolumeType,omitempty"`
// RootVolumeIOPS is the provisioned IOPS when the volume type is io1, io2 or gp3 (AWS only).
RootVolumeIOPS *int32 `json:"rootVolumeIOPS,omitempty"`
// RootVolumeThroughput is the volume throughput in MBps when the volume type is gp3 (AWS only).
RootVolumeThroughput *int32 `json:"rootVolumeThroughput,omitempty"`
// RootVolumeOptimization enables EBS optimization for an instance
RootVolumeOptimization *bool `json:"rootVolumeOptimization,omitempty"`
// RootVolumeEncryption enables EBS root volume encryption for an instance
RootVolumeEncryption *bool `json:"rootVolumeEncryption,omitempty"`
// RootVolumeEncryptionKey provides the key identifier for root volume encryption
RootVolumeEncryptionKey *string `json:"rootVolumeEncryptionKey,omitempty"`
// Volumes is a collection of additional volumes to create for instances within this instance group // Volumes is a collection of additional volumes to create for instances within this instance group
Volumes []VolumeSpec `json:"volumes,omitempty"` Volumes []VolumeSpec `json:"volumes,omitempty"`
// VolumeMounts a collection of volume mounts // VolumeMounts a collection of volume mounts
@ -232,6 +220,24 @@ var SpotAllocationStrategies = []string{
SpotAllocationStrategyPriceCapacityOptimized, SpotAllocationStrategyPriceCapacityOptimized,
} }
// InstanceRootVolumeSpec specifies options for an instance's root volume.
type InstanceRootVolumeSpec struct {
// Size is the size of the EBS root volume to use, in GB.
Size *int32 `json:"size,omitempty"`
// Type is the type of the EBS root volume to use (for example gp2).
Type *string `json:"type,omitempty"`
// IOPS is the provisioned IOPS when the volume type is io1, io2 or gp3 (AWS only).
IOPS *int32 `json:"iops,omitempty"`
// Throughput is the volume throughput in MBps when the volume type is gp3 (AWS only).
Throughput *int32 `json:"throughput,omitempty"`
// Optimization enables EBS optimization for an instance.
Optimization *bool `json:"optimization,omitempty"`
// Encryption enables EBS root volume encryption for an instance.
Encryption *bool `json:"encryption,omitempty"`
// EncryptionKey provides the key identifier for root volume encryption.
EncryptionKey *string `json:"encryptionKey,omitempty"`
}
// InstanceMetadataOptions defines the EC2 instance metadata service options (AWS Only) // InstanceMetadataOptions defines the EC2 instance metadata service options (AWS Only)
type InstanceMetadataOptions struct { type InstanceMetadataOptions struct {
// HTTPPutResponseHopLimit is the desired HTTP PUT response hop limit for instance metadata requests. // HTTPPutResponseHopLimit is the desired HTTP PUT response hop limit for instance metadata requests.

View File

@ -586,6 +586,48 @@ func Convert_v1alpha2_InstanceGroupSpec_To_kops_InstanceGroupSpec(in *InstanceGr
if in.Role == "Master" { if in.Role == "Master" {
out.Role = kops.InstanceGroupRoleControlPlane out.Role = kops.InstanceGroupRoleControlPlane
} }
if in.RootVolumeEncryption != nil {
if out.RootVolume == nil {
out.RootVolume = &kops.InstanceRootVolumeSpec{}
}
out.RootVolume.Encryption = in.RootVolumeEncryption
}
if in.RootVolumeEncryptionKey != nil {
if out.RootVolume == nil {
out.RootVolume = &kops.InstanceRootVolumeSpec{}
}
out.RootVolume.EncryptionKey = in.RootVolumeEncryptionKey
}
if in.RootVolumeIOPS != nil {
if out.RootVolume == nil {
out.RootVolume = &kops.InstanceRootVolumeSpec{}
}
out.RootVolume.IOPS = in.RootVolumeIOPS
}
if in.RootVolumeOptimization != nil {
if out.RootVolume == nil {
out.RootVolume = &kops.InstanceRootVolumeSpec{}
}
out.RootVolume.Optimization = in.RootVolumeOptimization
}
if in.RootVolumeSize != nil {
if out.RootVolume == nil {
out.RootVolume = &kops.InstanceRootVolumeSpec{}
}
out.RootVolume.Size = in.RootVolumeSize
}
if in.RootVolumeThroughput != nil {
if out.RootVolume == nil {
out.RootVolume = &kops.InstanceRootVolumeSpec{}
}
out.RootVolume.Throughput = in.RootVolumeThroughput
}
if in.RootVolumeType != nil {
if out.RootVolume == nil {
out.RootVolume = &kops.InstanceRootVolumeSpec{}
}
out.RootVolume.Type = in.RootVolumeType
}
return nil return nil
} }
@ -596,6 +638,16 @@ func Convert_kops_InstanceGroupSpec_To_v1alpha2_InstanceGroupSpec(in *kops.Insta
if in.Role == kops.InstanceGroupRoleControlPlane { if in.Role == kops.InstanceGroupRoleControlPlane {
out.Role = "Master" out.Role = "Master"
} }
if in.RootVolume != nil {
rv := in.RootVolume
out.RootVolumeEncryption = rv.Encryption
out.RootVolumeEncryptionKey = rv.EncryptionKey
out.RootVolumeIOPS = rv.IOPS
out.RootVolumeOptimization = rv.Optimization
out.RootVolumeSize = rv.Size
out.RootVolumeThroughput = rv.Throughput
out.RootVolumeType = rv.Type
}
return nil return nil
} }

View File

@ -19,6 +19,7 @@ package v1alpha2
import ( import (
"k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kops/pkg/apis/kops"
) )
// +genclient // +genclient
@ -68,22 +69,31 @@ type InstanceGroupSpec struct {
Autoscale *bool `json:"autoscale,omitempty"` Autoscale *bool `json:"autoscale,omitempty"`
// MachineType is the instance class // MachineType is the instance class
MachineType string `json:"machineType,omitempty"` MachineType string `json:"machineType,omitempty"`
// RootVolume specifies options for the instances' root volumes.
RootVolume *kops.InstanceRootVolumeSpec `json:"-"`
// RootVolumeSize is the size of the EBS root volume to use, in GB // RootVolumeSize is the size of the EBS root volume to use, in GB
// +k8s:conversion-gen=false
RootVolumeSize *int32 `json:"rootVolumeSize,omitempty"` RootVolumeSize *int32 `json:"rootVolumeSize,omitempty"`
// RootVolumeType is the type of the EBS root volume to use (e.g. gp2) // RootVolumeType is the type of the EBS root volume to use (e.g. gp2)
// +k8s:conversion-gen=false
RootVolumeType *string `json:"rootVolumeType,omitempty"` RootVolumeType *string `json:"rootVolumeType,omitempty"`
// RootVolumeIOPS is the provisioned IOPS when the volume type is io1, io2 or gp3 (AWS only). // RootVolumeIOPS is the provisioned IOPS when the volume type is io1, io2 or gp3 (AWS only).
// +k8s:conversion-gen=false
RootVolumeIOPS *int32 `json:"rootVolumeIops,omitempty"` RootVolumeIOPS *int32 `json:"rootVolumeIops,omitempty"`
// RootVolumeThroughput is the volume throughput in MBps when the volume type is gp3 (AWS only). // RootVolumeThroughput is the volume throughput in MBps when the volume type is gp3 (AWS only).
// +k8s:conversion-gen=false
RootVolumeThroughput *int32 `json:"rootVolumeThroughput,omitempty"` RootVolumeThroughput *int32 `json:"rootVolumeThroughput,omitempty"`
// RootVolumeOptimization enables EBS optimization for an instance // RootVolumeOptimization enables EBS optimization for an instance
// +k8s:conversion-gen=false
RootVolumeOptimization *bool `json:"rootVolumeOptimization,omitempty"` RootVolumeOptimization *bool `json:"rootVolumeOptimization,omitempty"`
// RootVolumeDeleteOnTermination is unused. // RootVolumeDeleteOnTermination is unused.
// +k8s:conversion-gen=false // +k8s:conversion-gen=false
RootVolumeDeleteOnTermination *bool `json:"rootVolumeDeleteOnTermination,omitempty"` RootVolumeDeleteOnTermination *bool `json:"rootVolumeDeleteOnTermination,omitempty"`
// RootVolumeEncryption enables EBS root volume encryption for an instance // RootVolumeEncryption enables EBS root volume encryption for an instance
// +k8s:conversion-gen=false
RootVolumeEncryption *bool `json:"rootVolumeEncryption,omitempty"` RootVolumeEncryption *bool `json:"rootVolumeEncryption,omitempty"`
// RootVolumeEncryptionKey provides the key identifier for root volume encryption // RootVolumeEncryptionKey provides the key identifier for root volume encryption
// +k8s:conversion-gen=false
RootVolumeEncryptionKey *string `json:"rootVolumeEncryptionKey,omitempty"` RootVolumeEncryptionKey *string `json:"rootVolumeEncryptionKey,omitempty"`
// Volumes is a collection of additional volumes to create for instances within this InstanceGroup // Volumes is a collection of additional volumes to create for instances within this InstanceGroup
Volumes []VolumeSpec `json:"volumes,omitempty"` Volumes []VolumeSpec `json:"volumes,omitempty"`

View File

@ -4090,14 +4090,15 @@ func autoConvert_v1alpha2_InstanceGroupSpec_To_kops_InstanceGroupSpec(in *Instan
out.MaxSize = in.MaxSize out.MaxSize = in.MaxSize
out.Autoscale = in.Autoscale out.Autoscale = in.Autoscale
out.MachineType = in.MachineType out.MachineType = in.MachineType
out.RootVolumeSize = in.RootVolumeSize out.RootVolume = in.RootVolume
out.RootVolumeType = in.RootVolumeType // INFO: in.RootVolumeSize opted out of conversion generation
out.RootVolumeIOPS = in.RootVolumeIOPS // INFO: in.RootVolumeType opted out of conversion generation
out.RootVolumeThroughput = in.RootVolumeThroughput // INFO: in.RootVolumeIOPS opted out of conversion generation
out.RootVolumeOptimization = in.RootVolumeOptimization // INFO: in.RootVolumeThroughput opted out of conversion generation
// INFO: in.RootVolumeOptimization opted out of conversion generation
// INFO: in.RootVolumeDeleteOnTermination opted out of conversion generation // INFO: in.RootVolumeDeleteOnTermination opted out of conversion generation
out.RootVolumeEncryption = in.RootVolumeEncryption // INFO: in.RootVolumeEncryption opted out of conversion generation
out.RootVolumeEncryptionKey = in.RootVolumeEncryptionKey // INFO: in.RootVolumeEncryptionKey opted out of conversion generation
if in.Volumes != nil { if in.Volumes != nil {
in, out := &in.Volumes, &out.Volumes in, out := &in.Volumes, &out.Volumes
*out = make([]kops.VolumeSpec, len(*in)) *out = make([]kops.VolumeSpec, len(*in))
@ -4272,13 +4273,7 @@ func autoConvert_kops_InstanceGroupSpec_To_v1alpha2_InstanceGroupSpec(in *kops.I
out.MaxSize = in.MaxSize out.MaxSize = in.MaxSize
out.Autoscale = in.Autoscale out.Autoscale = in.Autoscale
out.MachineType = in.MachineType out.MachineType = in.MachineType
out.RootVolumeSize = in.RootVolumeSize out.RootVolume = in.RootVolume
out.RootVolumeType = in.RootVolumeType
out.RootVolumeIOPS = in.RootVolumeIOPS
out.RootVolumeThroughput = in.RootVolumeThroughput
out.RootVolumeOptimization = in.RootVolumeOptimization
out.RootVolumeEncryption = in.RootVolumeEncryption
out.RootVolumeEncryptionKey = in.RootVolumeEncryptionKey
if in.Volumes != nil { if in.Volumes != nil {
in, out := &in.Volumes, &out.Volumes in, out := &in.Volumes, &out.Volumes
*out = make([]VolumeSpec, len(*in)) *out = make([]VolumeSpec, len(*in))

View File

@ -26,6 +26,7 @@ import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime" runtime "k8s.io/apimachinery/pkg/runtime"
intstr "k8s.io/apimachinery/pkg/util/intstr" intstr "k8s.io/apimachinery/pkg/util/intstr"
kops "k8s.io/kops/pkg/apis/kops"
) )
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
@ -2333,6 +2334,11 @@ func (in *InstanceGroupSpec) DeepCopyInto(out *InstanceGroupSpec) {
*out = new(bool) *out = new(bool)
**out = **in **out = **in
} }
if in.RootVolume != nil {
in, out := &in.RootVolume, &out.RootVolume
*out = new(kops.InstanceRootVolumeSpec)
(*in).DeepCopyInto(*out)
}
if in.RootVolumeSize != nil { if in.RootVolumeSize != nil {
in, out := &in.RootVolumeSize, &out.RootVolumeSize in, out := &in.RootVolumeSize, &out.RootVolumeSize
*out = new(int32) *out = new(int32)

View File

@ -68,20 +68,8 @@ type InstanceGroupSpec struct {
Autoscale *bool `json:"autoscale,omitempty"` Autoscale *bool `json:"autoscale,omitempty"`
// MachineType is the instance class // MachineType is the instance class
MachineType string `json:"machineType,omitempty"` MachineType string `json:"machineType,omitempty"`
// RootVolumeSize is the size of the EBS root volume to use, in GB // RootVolume specifies options for the instances' root volumes.
RootVolumeSize *int32 `json:"rootVolumeSize,omitempty"` RootVolume *InstanceRootVolumeSpec `json:"rootVolume,omitempty"`
// RootVolumeType is the type of the EBS root volume to use (e.g. gp2)
RootVolumeType *string `json:"rootVolumeType,omitempty"`
// RootVolumeIOPS is the provisioned IOPS when the volume type is io1, io2 or gp3 (AWS only).
RootVolumeIOPS *int32 `json:"rootVolumeIOPS,omitempty"`
// RootVolumeThroughput is the volume throughput in MBps when the volume type is gp3 (AWS only).
RootVolumeThroughput *int32 `json:"rootVolumeThroughput,omitempty"`
// RootVolumeOptimization enables EBS optimization for an instance
RootVolumeOptimization *bool `json:"rootVolumeOptimization,omitempty"`
// RootVolumeEncryption enables EBS root volume encryption for an instance
RootVolumeEncryption *bool `json:"rootVolumeEncryption,omitempty"`
// RootVolumeEncryptionKey provides the key identifier for root volume encryption
RootVolumeEncryptionKey *string `json:"rootVolumeEncryptionKey,omitempty"`
// Volumes is a collection of additional volumes to create for instances within this InstanceGroup // Volumes is a collection of additional volumes to create for instances within this InstanceGroup
Volumes []VolumeSpec `json:"volumes,omitempty"` Volumes []VolumeSpec `json:"volumes,omitempty"`
// VolumeMounts a collection of volume mounts // VolumeMounts a collection of volume mounts
@ -171,6 +159,24 @@ type InstanceGroupSpec struct {
GCPProvisioningModel *string `json:"gcpProvisioningModel,omitempty"` GCPProvisioningModel *string `json:"gcpProvisioningModel,omitempty"`
} }
// InstanceRootVolumeSpec specifies options for an instance's root volume.
type InstanceRootVolumeSpec struct {
// Size is the size of the EBS root volume to use, in GB.
Size *int32 `json:"size,omitempty"`
// Type is the type of the EBS root volume to use (for example gp2).
Type *string `json:"type,omitempty"`
// IOPS is the provisioned IOPS when the volume type is io1, io2 or gp3 (AWS only).
IOPS *int32 `json:"iops,omitempty"`
// Throughput is the volume throughput in MBps when the volume type is gp3 (AWS only).
Throughput *int32 `json:"throughput,omitempty"`
// Optimization enables EBS optimization for an instance.
Optimization *bool `json:"optimization,omitempty"`
// Encryption enables EBS root volume encryption for an instance.
Encryption *bool `json:"encryption,omitempty"`
// EncryptionKey provides the key identifier for root volume encryption.
EncryptionKey *string `json:"encryptionKey,omitempty"`
}
// InstanceMetadataOptions defines the EC2 instance metadata service options (AWS Only) // InstanceMetadataOptions defines the EC2 instance metadata service options (AWS Only)
type InstanceMetadataOptions struct { type InstanceMetadataOptions struct {
// HTTPPutResponseHopLimit is the desired HTTP PUT response hop limit for instance metadata requests. // HTTPPutResponseHopLimit is the desired HTTP PUT response hop limit for instance metadata requests.

View File

@ -664,6 +664,16 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil { }); err != nil {
return err return err
} }
if err := s.AddGeneratedConversionFunc((*InstanceRootVolumeSpec)(nil), (*kops.InstanceRootVolumeSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha3_InstanceRootVolumeSpec_To_kops_InstanceRootVolumeSpec(a.(*InstanceRootVolumeSpec), b.(*kops.InstanceRootVolumeSpec), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*kops.InstanceRootVolumeSpec)(nil), (*InstanceRootVolumeSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_kops_InstanceRootVolumeSpec_To_v1alpha3_InstanceRootVolumeSpec(a.(*kops.InstanceRootVolumeSpec), b.(*InstanceRootVolumeSpec), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*KarpenterConfig)(nil), (*kops.KarpenterConfig)(nil), func(a, b interface{}, scope conversion.Scope) error { if err := s.AddGeneratedConversionFunc((*KarpenterConfig)(nil), (*kops.KarpenterConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha3_KarpenterConfig_To_kops_KarpenterConfig(a.(*KarpenterConfig), b.(*kops.KarpenterConfig), scope) return Convert_v1alpha3_KarpenterConfig_To_kops_KarpenterConfig(a.(*KarpenterConfig), b.(*kops.KarpenterConfig), scope)
}); err != nil { }); err != nil {
@ -4361,13 +4371,15 @@ func autoConvert_v1alpha3_InstanceGroupSpec_To_kops_InstanceGroupSpec(in *Instan
out.MaxSize = in.MaxSize out.MaxSize = in.MaxSize
out.Autoscale = in.Autoscale out.Autoscale = in.Autoscale
out.MachineType = in.MachineType out.MachineType = in.MachineType
out.RootVolumeSize = in.RootVolumeSize if in.RootVolume != nil {
out.RootVolumeType = in.RootVolumeType in, out := &in.RootVolume, &out.RootVolume
out.RootVolumeIOPS = in.RootVolumeIOPS *out = new(kops.InstanceRootVolumeSpec)
out.RootVolumeThroughput = in.RootVolumeThroughput if err := Convert_v1alpha3_InstanceRootVolumeSpec_To_kops_InstanceRootVolumeSpec(*in, *out, s); err != nil {
out.RootVolumeOptimization = in.RootVolumeOptimization return err
out.RootVolumeEncryption = in.RootVolumeEncryption }
out.RootVolumeEncryptionKey = in.RootVolumeEncryptionKey } else {
out.RootVolume = nil
}
if in.Volumes != nil { if in.Volumes != nil {
in, out := &in.Volumes, &out.Volumes in, out := &in.Volumes, &out.Volumes
*out = make([]kops.VolumeSpec, len(*in)) *out = make([]kops.VolumeSpec, len(*in))
@ -4547,13 +4559,15 @@ func autoConvert_kops_InstanceGroupSpec_To_v1alpha3_InstanceGroupSpec(in *kops.I
out.MaxSize = in.MaxSize out.MaxSize = in.MaxSize
out.Autoscale = in.Autoscale out.Autoscale = in.Autoscale
out.MachineType = in.MachineType out.MachineType = in.MachineType
out.RootVolumeSize = in.RootVolumeSize if in.RootVolume != nil {
out.RootVolumeType = in.RootVolumeType in, out := &in.RootVolume, &out.RootVolume
out.RootVolumeIOPS = in.RootVolumeIOPS *out = new(InstanceRootVolumeSpec)
out.RootVolumeThroughput = in.RootVolumeThroughput if err := Convert_kops_InstanceRootVolumeSpec_To_v1alpha3_InstanceRootVolumeSpec(*in, *out, s); err != nil {
out.RootVolumeOptimization = in.RootVolumeOptimization return err
out.RootVolumeEncryption = in.RootVolumeEncryption }
out.RootVolumeEncryptionKey = in.RootVolumeEncryptionKey } else {
out.RootVolume = nil
}
if in.Volumes != nil { if in.Volumes != nil {
in, out := &in.Volumes, &out.Volumes in, out := &in.Volumes, &out.Volumes
*out = make([]VolumeSpec, len(*in)) *out = make([]VolumeSpec, len(*in))
@ -4801,6 +4815,38 @@ func Convert_kops_InstanceRequirementsSpec_To_v1alpha3_InstanceRequirementsSpec(
return autoConvert_kops_InstanceRequirementsSpec_To_v1alpha3_InstanceRequirementsSpec(in, out, s) return autoConvert_kops_InstanceRequirementsSpec_To_v1alpha3_InstanceRequirementsSpec(in, out, s)
} }
func autoConvert_v1alpha3_InstanceRootVolumeSpec_To_kops_InstanceRootVolumeSpec(in *InstanceRootVolumeSpec, out *kops.InstanceRootVolumeSpec, s conversion.Scope) error {
out.Size = in.Size
out.Type = in.Type
out.IOPS = in.IOPS
out.Throughput = in.Throughput
out.Optimization = in.Optimization
out.Encryption = in.Encryption
out.EncryptionKey = in.EncryptionKey
return nil
}
// Convert_v1alpha3_InstanceRootVolumeSpec_To_kops_InstanceRootVolumeSpec is an autogenerated conversion function.
func Convert_v1alpha3_InstanceRootVolumeSpec_To_kops_InstanceRootVolumeSpec(in *InstanceRootVolumeSpec, out *kops.InstanceRootVolumeSpec, s conversion.Scope) error {
return autoConvert_v1alpha3_InstanceRootVolumeSpec_To_kops_InstanceRootVolumeSpec(in, out, s)
}
func autoConvert_kops_InstanceRootVolumeSpec_To_v1alpha3_InstanceRootVolumeSpec(in *kops.InstanceRootVolumeSpec, out *InstanceRootVolumeSpec, s conversion.Scope) error {
out.Size = in.Size
out.Type = in.Type
out.IOPS = in.IOPS
out.Throughput = in.Throughput
out.Optimization = in.Optimization
out.Encryption = in.Encryption
out.EncryptionKey = in.EncryptionKey
return nil
}
// Convert_kops_InstanceRootVolumeSpec_To_v1alpha3_InstanceRootVolumeSpec is an autogenerated conversion function.
func Convert_kops_InstanceRootVolumeSpec_To_v1alpha3_InstanceRootVolumeSpec(in *kops.InstanceRootVolumeSpec, out *InstanceRootVolumeSpec, s conversion.Scope) error {
return autoConvert_kops_InstanceRootVolumeSpec_To_v1alpha3_InstanceRootVolumeSpec(in, out, s)
}
func autoConvert_v1alpha3_KarpenterConfig_To_kops_KarpenterConfig(in *KarpenterConfig, out *kops.KarpenterConfig, s conversion.Scope) error { func autoConvert_v1alpha3_KarpenterConfig_To_kops_KarpenterConfig(in *KarpenterConfig, out *kops.KarpenterConfig, s conversion.Scope) error {
out.Enabled = in.Enabled out.Enabled = in.Enabled
return nil return nil

View File

@ -2271,40 +2271,10 @@ func (in *InstanceGroupSpec) DeepCopyInto(out *InstanceGroupSpec) {
*out = new(bool) *out = new(bool)
**out = **in **out = **in
} }
if in.RootVolumeSize != nil { if in.RootVolume != nil {
in, out := &in.RootVolumeSize, &out.RootVolumeSize in, out := &in.RootVolume, &out.RootVolume
*out = new(int32) *out = new(InstanceRootVolumeSpec)
**out = **in (*in).DeepCopyInto(*out)
}
if in.RootVolumeType != nil {
in, out := &in.RootVolumeType, &out.RootVolumeType
*out = new(string)
**out = **in
}
if in.RootVolumeIOPS != nil {
in, out := &in.RootVolumeIOPS, &out.RootVolumeIOPS
*out = new(int32)
**out = **in
}
if in.RootVolumeThroughput != nil {
in, out := &in.RootVolumeThroughput, &out.RootVolumeThroughput
*out = new(int32)
**out = **in
}
if in.RootVolumeOptimization != nil {
in, out := &in.RootVolumeOptimization, &out.RootVolumeOptimization
*out = new(bool)
**out = **in
}
if in.RootVolumeEncryption != nil {
in, out := &in.RootVolumeEncryption, &out.RootVolumeEncryption
*out = new(bool)
**out = **in
}
if in.RootVolumeEncryptionKey != nil {
in, out := &in.RootVolumeEncryptionKey, &out.RootVolumeEncryptionKey
*out = new(string)
**out = **in
} }
if in.Volumes != nil { if in.Volumes != nil {
in, out := &in.Volumes, &out.Volumes in, out := &in.Volumes, &out.Volumes
@ -2565,6 +2535,57 @@ func (in *InstanceRequirementsSpec) DeepCopy() *InstanceRequirementsSpec {
return out return out
} }
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *InstanceRootVolumeSpec) DeepCopyInto(out *InstanceRootVolumeSpec) {
*out = *in
if in.Size != nil {
in, out := &in.Size, &out.Size
*out = new(int32)
**out = **in
}
if in.Type != nil {
in, out := &in.Type, &out.Type
*out = new(string)
**out = **in
}
if in.IOPS != nil {
in, out := &in.IOPS, &out.IOPS
*out = new(int32)
**out = **in
}
if in.Throughput != nil {
in, out := &in.Throughput, &out.Throughput
*out = new(int32)
**out = **in
}
if in.Optimization != nil {
in, out := &in.Optimization, &out.Optimization
*out = new(bool)
**out = **in
}
if in.Encryption != nil {
in, out := &in.Encryption, &out.Encryption
*out = new(bool)
**out = **in
}
if in.EncryptionKey != nil {
in, out := &in.EncryptionKey, &out.EncryptionKey
*out = new(string)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceRootVolumeSpec.
func (in *InstanceRootVolumeSpec) DeepCopy() *InstanceRootVolumeSpec {
if in == nil {
return nil
}
out := new(InstanceRootVolumeSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *KarpenterConfig) DeepCopyInto(out *KarpenterConfig) { func (in *KarpenterConfig) DeepCopyInto(out *KarpenterConfig) {
*out = *in *out = *in

View File

@ -89,12 +89,14 @@ func ValidateInstanceGroup(g *kops.InstanceGroup, cloud fi.Cloud, strict bool) f
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "image"), "image must be specified.")) allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "image"), "image must be specified."))
} }
if fi.ValueOf(g.Spec.RootVolumeIOPS) < 0 { if g.Spec.RootVolume != nil {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "rootVolumeIOPS"), g.Spec.RootVolumeIOPS, "RootVolumeIOPS must be greater than 0")) if fi.ValueOf(g.Spec.RootVolume.IOPS) < 0 {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "rootVolume", "iops"), g.Spec.RootVolume.IOPS, "IOPS must be greater than 0"))
} }
if fi.ValueOf(g.Spec.RootVolumeThroughput) < 0 { if fi.ValueOf(g.Spec.RootVolume.Throughput) < 0 {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "rootVolumeThroughput"), g.Spec.RootVolumeThroughput, "RootVolumeThroughput must be greater than 0")) allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "rootVolume", "throughput"), g.Spec.RootVolume.Throughput, "Throughput must be greater than 0"))
}
} }
// @check all the hooks are valid in this instancegroup // @check all the hooks are valid in this instancegroup
@ -254,8 +256,8 @@ func CrossValidateInstanceGroup(g *kops.InstanceGroup, cluster *kops.Cluster, cl
} }
if cluster.Spec.GetCloudProvider() == kops.CloudProviderAWS { if cluster.Spec.GetCloudProvider() == kops.CloudProviderAWS {
if g.Spec.RootVolumeType != nil { if g.Spec.RootVolume != nil && g.Spec.RootVolume.Type != nil {
allErrs = append(allErrs, IsValidValue(field.NewPath("spec", "rootVolumeType"), g.Spec.RootVolumeType, []string{"standard", "gp3", "gp2", "io1", "io2"})...) allErrs = append(allErrs, IsValidValue(field.NewPath("spec", "rootVolume", "type"), g.Spec.RootVolume.Type, []string{"standard", "gp3", "gp2", "io1", "io2"})...)
} }
warmPool := cluster.Spec.CloudProvider.AWS.WarmPool.ResolveDefaults(g) warmPool := cluster.Spec.CloudProvider.AWS.WarmPool.ResolveDefaults(g)

View File

@ -211,17 +211,19 @@ func TestValidBootDevice(t *testing.T) {
}, },
{ {
volumeType: "st1", volumeType: "st1",
expected: []string{"Unsupported value::spec.rootVolumeType"}, expected: []string{"Unsupported value::spec.rootVolume.type"},
}, },
{ {
volumeType: "sc1", volumeType: "sc1",
expected: []string{"Unsupported value::spec.rootVolumeType"}, expected: []string{"Unsupported value::spec.rootVolume.type"},
}, },
} }
for _, g := range grid { for _, g := range grid {
ig := createMinimalInstanceGroup() ig := createMinimalInstanceGroup()
ig.Spec.RootVolumeType = fi.PtrTo(g.volumeType) ig.Spec.RootVolume = &kops.InstanceRootVolumeSpec{
Type: fi.PtrTo(g.volumeType),
}
errs := CrossValidateInstanceGroup(ig, cluster, nil, true) errs := CrossValidateInstanceGroup(ig, cluster, nil, true)
testErrors(t, g.volumeType, errs, g.expected) testErrors(t, g.volumeType, errs, g.expected)
} }

View File

@ -2434,40 +2434,10 @@ func (in *InstanceGroupSpec) DeepCopyInto(out *InstanceGroupSpec) {
*out = new(bool) *out = new(bool)
**out = **in **out = **in
} }
if in.RootVolumeSize != nil { if in.RootVolume != nil {
in, out := &in.RootVolumeSize, &out.RootVolumeSize in, out := &in.RootVolume, &out.RootVolume
*out = new(int32) *out = new(InstanceRootVolumeSpec)
**out = **in (*in).DeepCopyInto(*out)
}
if in.RootVolumeType != nil {
in, out := &in.RootVolumeType, &out.RootVolumeType
*out = new(string)
**out = **in
}
if in.RootVolumeIOPS != nil {
in, out := &in.RootVolumeIOPS, &out.RootVolumeIOPS
*out = new(int32)
**out = **in
}
if in.RootVolumeThroughput != nil {
in, out := &in.RootVolumeThroughput, &out.RootVolumeThroughput
*out = new(int32)
**out = **in
}
if in.RootVolumeOptimization != nil {
in, out := &in.RootVolumeOptimization, &out.RootVolumeOptimization
*out = new(bool)
**out = **in
}
if in.RootVolumeEncryption != nil {
in, out := &in.RootVolumeEncryption, &out.RootVolumeEncryption
*out = new(bool)
**out = **in
}
if in.RootVolumeEncryptionKey != nil {
in, out := &in.RootVolumeEncryptionKey, &out.RootVolumeEncryptionKey
*out = new(string)
**out = **in
} }
if in.Volumes != nil { if in.Volumes != nil {
in, out := &in.Volumes, &out.Volumes in, out := &in.Volumes, &out.Volumes
@ -2728,6 +2698,57 @@ func (in *InstanceRequirementsSpec) DeepCopy() *InstanceRequirementsSpec {
return out return out
} }
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *InstanceRootVolumeSpec) DeepCopyInto(out *InstanceRootVolumeSpec) {
*out = *in
if in.Size != nil {
in, out := &in.Size, &out.Size
*out = new(int32)
**out = **in
}
if in.Type != nil {
in, out := &in.Type, &out.Type
*out = new(string)
**out = **in
}
if in.IOPS != nil {
in, out := &in.IOPS, &out.IOPS
*out = new(int32)
**out = **in
}
if in.Throughput != nil {
in, out := &in.Throughput, &out.Throughput
*out = new(int32)
**out = **in
}
if in.Optimization != nil {
in, out := &in.Optimization, &out.Optimization
*out = new(bool)
**out = **in
}
if in.Encryption != nil {
in, out := &in.Encryption, &out.Encryption
*out = new(bool)
**out = **in
}
if in.EncryptionKey != nil {
in, out := &in.EncryptionKey, &out.EncryptionKey
*out = new(string)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceRootVolumeSpec.
func (in *InstanceRootVolumeSpec) DeepCopy() *InstanceRootVolumeSpec {
if in == nil {
return nil
}
out := new(InstanceRootVolumeSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *KarpenterConfig) DeepCopyInto(out *KarpenterConfig) { func (in *KarpenterConfig) DeepCopyInto(out *KarpenterConfig) {
*out = *in *out = *in

View File

@ -142,25 +142,29 @@ func (b *AutoscalingGroupModelBuilder) buildLaunchTemplateTask(c *fi.CloudupMode
if err != nil { if err != nil {
return nil, err return nil, err
} }
if fi.ValueOf(ig.Spec.RootVolumeSize) > 0 { var rootVolumeType string
rootVolumeSize = fi.ValueOf(ig.Spec.RootVolumeSize) rootVolumeEncryption := DefaultVolumeEncryption
rootVolumeKmsKey := ""
if ig.Spec.RootVolume != nil {
if fi.ValueOf(ig.Spec.RootVolume.Size) > 0 {
rootVolumeSize = fi.ValueOf(ig.Spec.RootVolume.Size)
} }
rootVolumeType := fi.ValueOf(ig.Spec.RootVolumeType) rootVolumeType = fi.ValueOf(ig.Spec.RootVolume.Type)
if ig.Spec.RootVolume.Encryption != nil {
rootVolumeEncryption = fi.ValueOf(ig.Spec.RootVolume.Encryption)
}
if fi.ValueOf(ig.Spec.RootVolume.Encryption) && ig.Spec.RootVolume.EncryptionKey != nil {
rootVolumeKmsKey = *ig.Spec.RootVolume.EncryptionKey
}
}
if rootVolumeType == "" { if rootVolumeType == "" {
rootVolumeType = DefaultVolumeType rootVolumeType = DefaultVolumeType
} }
rootVolumeEncryption := DefaultVolumeEncryption
if ig.Spec.RootVolumeEncryption != nil {
rootVolumeEncryption = fi.ValueOf(ig.Spec.RootVolumeEncryption)
}
rootVolumeKmsKey := ""
if fi.ValueOf(ig.Spec.RootVolumeEncryption) && ig.Spec.RootVolumeEncryptionKey != nil {
rootVolumeKmsKey = *ig.Spec.RootVolumeEncryptionKey
}
securityGroups, err := b.buildSecurityGroups(c, ig) securityGroups, err := b.buildSecurityGroups(c, ig)
if err != nil { if err != nil {
return nil, err return nil, err
@ -188,8 +192,7 @@ func (b *AutoscalingGroupModelBuilder) buildLaunchTemplateTask(c *fi.CloudupMode
InstanceInterruptionBehavior: ig.Spec.InstanceInterruptionBehavior, InstanceInterruptionBehavior: ig.Spec.InstanceInterruptionBehavior,
InstanceMonitoring: fi.PtrTo(false), InstanceMonitoring: fi.PtrTo(false),
IPv6AddressCount: fi.PtrTo(int64(0)), IPv6AddressCount: fi.PtrTo(int64(0)),
RootVolumeIops: fi.PtrTo(int64(fi.ValueOf(ig.Spec.RootVolumeIOPS))), RootVolumeIops: fi.PtrTo(int64(0)),
RootVolumeOptimization: ig.Spec.RootVolumeOptimization,
RootVolumeSize: fi.PtrTo(int64(rootVolumeSize)), RootVolumeSize: fi.PtrTo(int64(rootVolumeSize)),
RootVolumeType: fi.PtrTo(rootVolumeType), RootVolumeType: fi.PtrTo(rootVolumeType),
RootVolumeEncryption: fi.PtrTo(rootVolumeEncryption), RootVolumeEncryption: fi.PtrTo(rootVolumeEncryption),
@ -198,6 +201,10 @@ func (b *AutoscalingGroupModelBuilder) buildLaunchTemplateTask(c *fi.CloudupMode
Tags: tags, Tags: tags,
UserData: userData, UserData: userData,
} }
if ig.Spec.RootVolume != nil {
lt.RootVolumeIops = fi.PtrTo(int64(fi.ValueOf(ig.Spec.RootVolume.IOPS)))
lt.RootVolumeOptimization = ig.Spec.RootVolume.Optimization
}
if ig.Spec.Manager == kops.InstanceManagerCloudGroup { if ig.Spec.Manager == kops.InstanceManagerCloudGroup {
lt.InstanceType = fi.PtrTo(strings.Split(ig.Spec.MachineType, ",")[0]) lt.InstanceType = fi.PtrTo(strings.Split(ig.Spec.MachineType, ",")[0])
@ -288,17 +295,17 @@ func (b *AutoscalingGroupModelBuilder) buildLaunchTemplateTask(c *fi.CloudupMode
} }
if rootVolumeType == ec2.VolumeTypeIo1 || rootVolumeType == ec2.VolumeTypeIo2 { if rootVolumeType == ec2.VolumeTypeIo1 || rootVolumeType == ec2.VolumeTypeIo2 {
if fi.ValueOf(ig.Spec.RootVolumeIOPS) < 100 { if ig.Spec.RootVolume == nil || fi.ValueOf(ig.Spec.RootVolume.IOPS) < 100 {
lt.RootVolumeIops = fi.PtrTo(int64(DefaultVolumeIonIops)) lt.RootVolumeIops = fi.PtrTo(int64(DefaultVolumeIonIops))
} }
} else if rootVolumeType == ec2.VolumeTypeGp3 { } else if rootVolumeType == ec2.VolumeTypeGp3 {
if fi.ValueOf(ig.Spec.RootVolumeIOPS) < 3000 { if ig.Spec.RootVolume == nil || fi.ValueOf(ig.Spec.RootVolume.IOPS) < 3000 {
lt.RootVolumeIops = fi.PtrTo(int64(DefaultVolumeGp3Iops)) lt.RootVolumeIops = fi.PtrTo(int64(DefaultVolumeGp3Iops))
} }
if fi.ValueOf(ig.Spec.RootVolumeThroughput) < 125 { if ig.Spec.RootVolume == nil || fi.ValueOf(ig.Spec.RootVolume.Throughput) < 125 {
lt.RootVolumeThroughput = fi.PtrTo(int64(DefaultVolumeGp3Throughput)) lt.RootVolumeThroughput = fi.PtrTo(int64(DefaultVolumeGp3Throughput))
} else { } else {
lt.RootVolumeThroughput = fi.PtrTo(int64(fi.ValueOf(ig.Spec.RootVolumeThroughput))) lt.RootVolumeThroughput = fi.PtrTo(int64(fi.ValueOf(ig.Spec.RootVolume.Throughput)))
} }
} else { } else {
lt.RootVolumeIops = nil lt.RootVolumeIops = nil

View File

@ -51,7 +51,10 @@ func buildNodeInstanceGroup(subnets ...string) *kops.InstanceGroup {
func TestRootVolumeOptimizationFlag(t *testing.T) { func TestRootVolumeOptimizationFlag(t *testing.T) {
cluster := buildMinimalCluster() cluster := buildMinimalCluster()
ig := buildNodeInstanceGroup("subnet-us-test-1a") ig := buildNodeInstanceGroup("subnet-us-test-1a")
ig.Spec.RootVolumeOptimization = fi.PtrTo(true) if ig.Spec.RootVolume == nil {
ig.Spec.RootVolume = &kops.InstanceRootVolumeSpec{}
}
ig.Spec.RootVolume.Optimization = fi.PtrTo(true)
k := [][]byte{} k := [][]byte{}
k = append(k, []byte(sshPublicKeyEntry)) k = append(k, []byte(sshPublicKeyEntry))

View File

@ -707,23 +707,31 @@ func (b *SpotInstanceGroupModelBuilder) buildPublicIPOpts(ig *kops.InstanceGroup
func (b *SpotInstanceGroupModelBuilder) buildRootVolumeOpts(ig *kops.InstanceGroup) (*spotinsttasks.RootVolumeOpts, error) { func (b *SpotInstanceGroupModelBuilder) buildRootVolumeOpts(ig *kops.InstanceGroup) (*spotinsttasks.RootVolumeOpts, error) {
opts := new(spotinsttasks.RootVolumeOpts) opts := new(spotinsttasks.RootVolumeOpts)
var size int32
var typ string
var iops int32
var throughput int32
if ig.Spec.RootVolume != nil {
// Optimization. // Optimization.
{ {
if fi.ValueOf(ig.Spec.RootVolumeOptimization) { if fi.ValueOf(ig.Spec.RootVolume.Optimization) {
opts.Optimization = ig.Spec.RootVolumeOptimization opts.Optimization = ig.Spec.RootVolume.Optimization
} }
} }
// Encryption. // Encryption.
{ {
if fi.ValueOf(ig.Spec.RootVolumeEncryption) { if fi.ValueOf(ig.Spec.RootVolume.Encryption) {
opts.Encryption = ig.Spec.RootVolumeEncryption opts.Encryption = ig.Spec.RootVolume.Encryption
} }
} }
// Size. size = fi.ValueOf(ig.Spec.RootVolume.Size)
{ typ = fi.ValueOf(ig.Spec.RootVolume.Type)
size := fi.ValueOf(ig.Spec.RootVolumeSize) iops = fi.ValueOf(ig.Spec.RootVolume.IOPS)
throughput = fi.ValueOf(ig.Spec.RootVolume.Throughput)
}
if size == 0 { if size == 0 {
var err error var err error
size, err = defaults.DefaultInstanceGroupVolumeSize(ig.Spec.Role) size, err = defaults.DefaultInstanceGroupVolumeSize(ig.Spec.Role)
@ -732,32 +740,19 @@ func (b *SpotInstanceGroupModelBuilder) buildRootVolumeOpts(ig *kops.InstanceGro
} }
} }
opts.Size = fi.PtrTo(int64(size)) opts.Size = fi.PtrTo(int64(size))
}
// Type.
{
typ := fi.ValueOf(ig.Spec.RootVolumeType)
if typ == "" { if typ == "" {
typ = "gp2" typ = "gp2"
} }
opts.Type = fi.PtrTo(typ) opts.Type = fi.PtrTo(typ)
}
// IOPS.
{
iops := fi.ValueOf(ig.Spec.RootVolumeIOPS)
if iops > 0 { if iops > 0 {
opts.IOPS = fi.PtrTo(int64(iops)) opts.IOPS = fi.PtrTo(int64(iops))
} }
}
// Throughput.
{
throughput := fi.ValueOf(ig.Spec.RootVolumeThroughput)
if throughput > 0 { if throughput > 0 {
opts.Throughput = fi.PtrTo(int64(throughput)) opts.Throughput = fi.PtrTo(int64(throughput))
} }
}
return opts, nil return opts, nil
} }

View File

@ -78,7 +78,9 @@ func newTestInstanceGroup() *kops.InstanceGroup {
Spec: kops.InstanceGroupSpec{ Spec: kops.InstanceGroupSpec{
Role: kops.InstanceGroupRoleNode, Role: kops.InstanceGroupRoleNode,
Image: "Canonical:UbuntuServer:18.04-LTS:latest", Image: "Canonical:UbuntuServer:18.04-LTS:latest",
RootVolumeSize: fi.PtrTo(int32(32)), RootVolume: &kops.InstanceRootVolumeSpec{
Size: fi.PtrTo(int32(32)),
},
Subnets: []string{"test-subnet"}, Subnets: []string{"test-subnet"},
}, },
} }

View File

@ -169,8 +169,8 @@ func getCapacity(spec *kops.InstanceGroupSpec) (*int64, error) {
func getStorageProfile(spec *kops.InstanceGroupSpec) (*compute.VirtualMachineScaleSetStorageProfile, error) { func getStorageProfile(spec *kops.InstanceGroupSpec) (*compute.VirtualMachineScaleSetStorageProfile, error) {
var volumeSize int32 var volumeSize int32
if spec.RootVolumeSize != nil { if spec.RootVolume != nil && spec.RootVolume.Size != nil {
volumeSize = *spec.RootVolumeSize volumeSize = *spec.RootVolume.Size
} else { } else {
var err error var err error
volumeSize, err = defaults.DefaultInstanceGroupVolumeSize(spec.Role) volumeSize, err = defaults.DefaultInstanceGroupVolumeSize(spec.Role)
@ -180,8 +180,8 @@ func getStorageProfile(spec *kops.InstanceGroupSpec) (*compute.VirtualMachineSca
} }
var storageAccountType compute.StorageAccountTypes var storageAccountType compute.StorageAccountTypes
if spec.RootVolumeType != nil { if spec.RootVolume != nil && spec.RootVolume.Type != nil {
storageAccountType = compute.StorageAccountTypes(*spec.RootVolumeType) storageAccountType = compute.StorageAccountTypes(*spec.RootVolume.Type)
} else { } else {
storageAccountType = compute.StorageAccountTypesPremiumLRS storageAccountType = compute.StorageAccountTypesPremiumLRS
} }

View File

@ -143,8 +143,10 @@ func TestGetStorageProfile(t *testing.T) {
{ {
spec: kops.InstanceGroupSpec{ spec: kops.InstanceGroupSpec{
Image: "Canonical:UbuntuServer:18.04-LTS:latest", Image: "Canonical:UbuntuServer:18.04-LTS:latest",
RootVolumeType: fi.PtrTo(string(compute.StorageAccountTypesStandardLRS)), RootVolume: &kops.InstanceRootVolumeSpec{
RootVolumeSize: fi.PtrTo(int32(128)), Type: fi.PtrTo(string(compute.StorageAccountTypesStandardLRS)),
Size: fi.PtrTo(int32(128)),
},
}, },
profile: &compute.VirtualMachineScaleSetStorageProfile{ profile: &compute.VirtualMachineScaleSetStorageProfile{
ImageReference: &compute.ImageReference{ ImageReference: &compute.ImageReference{

View File

@ -62,14 +62,18 @@ func (b *AutoscalingGroupModelBuilder) buildInstanceTemplate(c *fi.CloudupModelB
} }
{ {
volumeSize := fi.ValueOf(ig.Spec.RootVolumeSize) var volumeSize int32
var volumeType string
if ig.Spec.RootVolume != nil {
volumeSize = fi.ValueOf(ig.Spec.RootVolume.Size)
volumeType = fi.ValueOf(ig.Spec.RootVolume.Type)
}
if volumeSize == 0 { if volumeSize == 0 {
volumeSize, err = defaults.DefaultInstanceGroupVolumeSize(ig.Spec.Role) volumeSize, err = defaults.DefaultInstanceGroupVolumeSize(ig.Spec.Role)
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
volumeType := fi.ValueOf(ig.Spec.RootVolumeType)
if volumeType == "" { if volumeType == "" {
volumeType = DefaultVolumeType volumeType = DefaultVolumeType
} }

View File

@ -115,6 +115,13 @@ spec:
maxSize: 2 maxSize: 2
minSize: 2 minSize: 2
role: Node role: Node
rootVolumeEncryption: true
rootVolumeEncryptionKey: 1234abcd-12ab-34cd-56ef-1234567890ab
rootVolumeIops: 300
rootVolumeOptimization: true
rootVolumeSize: 33
rootVolumeThroughput: 421
rootVolumeType: gp3
subnets: subnets:
- us-test-1a - us-test-1a

View File

@ -114,6 +114,14 @@ spec:
maxSize: 2 maxSize: 2
minSize: 2 minSize: 2
role: Node role: Node
rootVolume:
encryption: true
encryptionKey: 1234abcd-12ab-34cd-56ef-1234567890ab
iops: 300
optimization: true
size: 33
throughput: 421
type: gp3
subnets: subnets:
- us-test-1a - us-test-1a