Skip to content

Commit abe918c

Browse files
authored
Merge pull request #4954 from giantswarm/pr-non-root-volumes
✨ Add non root volumes to AWSMachinePool
2 parents ae3323c + 1c956d2 commit abe918c

File tree

8 files changed

+145
-5
lines changed

8 files changed

+145
-5
lines changed

config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachinepools.yaml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,50 @@ spec:
738738
name:
739739
description: The name of the launch template.
740740
type: string
741+
nonRootVolumes:
742+
description: Configuration options for the non root storage volumes.
743+
items:
744+
description: Volume encapsulates the configuration options for
745+
the storage device.
746+
properties:
747+
deviceName:
748+
description: Device name
749+
type: string
750+
encrypted:
751+
description: Encrypted is whether the volume should be encrypted
752+
or not.
753+
type: boolean
754+
encryptionKey:
755+
description: |-
756+
EncryptionKey is the KMS key to use to encrypt the volume. Can be either a KMS key ID or ARN.
757+
If Encrypted is set and this is omitted, the default AWS key will be used.
758+
The key must already exist and be accessible by the controller.
759+
type: string
760+
iops:
761+
description: IOPS is the number of IOPS requested for the
762+
disk. Not applicable to all types.
763+
format: int64
764+
type: integer
765+
size:
766+
description: |-
767+
Size specifies size (in Gi) of the storage device.
768+
Must be greater than the image snapshot size or 8 (whichever is greater).
769+
format: int64
770+
minimum: 8
771+
type: integer
772+
throughput:
773+
description: Throughput to provision in MiB/s supported
774+
for the volume type. Not applicable to all types.
775+
format: int64
776+
type: integer
777+
type:
778+
description: Type is the type of the volume (e.g. gp2, io1,
779+
etc...).
780+
type: string
781+
required:
782+
- size
783+
type: object
784+
type: array
741785
privateDnsName:
742786
description: PrivateDNSName is the options for the instance hostname.
743787
properties:

config/crd/bases/infrastructure.cluster.x-k8s.io_awsmanagedmachinepools.yaml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,50 @@ spec:
734734
name:
735735
description: The name of the launch template.
736736
type: string
737+
nonRootVolumes:
738+
description: Configuration options for the non root storage volumes.
739+
items:
740+
description: Volume encapsulates the configuration options for
741+
the storage device.
742+
properties:
743+
deviceName:
744+
description: Device name
745+
type: string
746+
encrypted:
747+
description: Encrypted is whether the volume should be encrypted
748+
or not.
749+
type: boolean
750+
encryptionKey:
751+
description: |-
752+
EncryptionKey is the KMS key to use to encrypt the volume. Can be either a KMS key ID or ARN.
753+
If Encrypted is set and this is omitted, the default AWS key will be used.
754+
The key must already exist and be accessible by the controller.
755+
type: string
756+
iops:
757+
description: IOPS is the number of IOPS requested for the
758+
disk. Not applicable to all types.
759+
format: int64
760+
type: integer
761+
size:
762+
description: |-
763+
Size specifies size (in Gi) of the storage device.
764+
Must be greater than the image snapshot size or 8 (whichever is greater).
765+
format: int64
766+
minimum: 8
767+
type: integer
768+
throughput:
769+
description: Throughput to provision in MiB/s supported
770+
for the volume type. Not applicable to all types.
771+
format: int64
772+
type: integer
773+
type:
774+
description: Type is the type of the volume (e.g. gp2, io1,
775+
etc...).
776+
type: string
777+
required:
778+
- size
779+
type: object
780+
type: array
737781
privateDnsName:
738782
description: PrivateDNSName is the options for the instance hostname.
739783
properties:

exp/api/v1beta1/conversion.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@ package v1beta1
1818

1919
import (
2020
apiconversion "k8s.io/apimachinery/pkg/conversion"
21+
utilconversion "sigs.k8s.io/cluster-api/util/conversion"
22+
"sigs.k8s.io/controller-runtime/pkg/conversion"
23+
2124
infrav1beta1 "sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta1"
2225
infrav1 "sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2"
2326
infrav1exp "sigs.k8s.io/cluster-api-provider-aws/v2/exp/api/v1beta2"
24-
utilconversion "sigs.k8s.io/cluster-api/util/conversion"
25-
"sigs.k8s.io/controller-runtime/pkg/conversion"
2627
)
2728

2829
// ConvertTo converts the v1beta1 AWSMachinePool receiver to a v1beta2 AWSMachinePool.
@@ -56,6 +57,7 @@ func (src *AWSMachinePool) ConvertTo(dstRaw conversion.Hub) error {
5657
}
5758

5859
dst.Spec.DefaultInstanceWarmup = restored.Spec.DefaultInstanceWarmup
60+
dst.Spec.AWSLaunchTemplate.NonRootVolumes = restored.Spec.AWSLaunchTemplate.NonRootVolumes
5961

6062
return nil
6163
}
@@ -101,6 +103,7 @@ func (src *AWSManagedMachinePool) ConvertTo(dstRaw conversion.Hub) error {
101103
dst.Spec.AWSLaunchTemplate = restored.Spec.AWSLaunchTemplate
102104
}
103105
dst.Spec.AWSLaunchTemplate.InstanceMetadataOptions = restored.Spec.AWSLaunchTemplate.InstanceMetadataOptions
106+
dst.Spec.AWSLaunchTemplate.NonRootVolumes = restored.Spec.AWSLaunchTemplate.NonRootVolumes
104107

105108
if restored.Spec.AWSLaunchTemplate.PrivateDNSName != nil {
106109
dst.Spec.AWSLaunchTemplate.PrivateDNSName = restored.Spec.AWSLaunchTemplate.PrivateDNSName

exp/api/v1beta1/zz_generated.conversion.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

exp/api/v1beta2/awsmachinepool_webhook.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,31 @@ func (r *AWSMachinePool) validateRootVolume() field.ErrorList {
8282
return allErrs
8383
}
8484

85+
func (r *AWSMachinePool) validateNonRootVolumes() field.ErrorList {
86+
var allErrs field.ErrorList
87+
88+
for _, volume := range r.Spec.AWSLaunchTemplate.NonRootVolumes {
89+
if v1beta2.VolumeTypesProvisioned.Has(string(volume.Type)) && volume.IOPS == 0 {
90+
allErrs = append(allErrs, field.Required(field.NewPath("spec.template.spec.nonRootVolumes.iops"), "iops required if type is 'io1' or 'io2'"))
91+
}
92+
93+
if volume.Throughput != nil {
94+
if volume.Type != v1beta2.VolumeTypeGP3 {
95+
allErrs = append(allErrs, field.Required(field.NewPath("spec.template.spec.nonRootVolumes.throughput"), "throughput is valid only for type 'gp3'"))
96+
}
97+
if *volume.Throughput < 0 {
98+
allErrs = append(allErrs, field.Required(field.NewPath("spec.template.spec.nonRootVolumes.throughput"), "throughput must be nonnegative"))
99+
}
100+
}
101+
102+
if volume.DeviceName == "" {
103+
allErrs = append(allErrs, field.Required(field.NewPath("spec.template.spec.nonRootVolumes.deviceName"), "non root volume should have device name"))
104+
}
105+
}
106+
107+
return allErrs
108+
}
109+
85110
func (r *AWSMachinePool) validateSubnets() field.ErrorList {
86111
var allErrs field.ErrorList
87112

@@ -124,6 +149,7 @@ func (r *AWSMachinePool) ValidateCreate() (admission.Warnings, error) {
124149

125150
allErrs = append(allErrs, r.validateDefaultCoolDown()...)
126151
allErrs = append(allErrs, r.validateRootVolume()...)
152+
allErrs = append(allErrs, r.validateNonRootVolumes()...)
127153
allErrs = append(allErrs, r.Spec.AdditionalTags.Validate()...)
128154
allErrs = append(allErrs, r.validateSubnets()...)
129155
allErrs = append(allErrs, r.validateAdditionalSecurityGroups()...)

exp/api/v1beta2/types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ type AWSLaunchTemplate struct {
9696
// +optional
9797
RootVolume *infrav1.Volume `json:"rootVolume,omitempty"`
9898

99+
// Configuration options for the non root storage volumes.
100+
// +optional
101+
NonRootVolumes []infrav1.Volume `json:"nonRootVolumes,omitempty"`
102+
99103
// SSHKeyName is the name of the ssh key to attach to the instance. Valid values are empty string
100104
// (do not use SSH keys), a valid SSH key name, or omitted (use the default SSH key name)
101105
// +optional

exp/api/v1beta2/zz_generated.deepcopy.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/cloud/services/ec2/launchtemplate.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,8 @@ func (s *Service) createLaunchTemplateData(scope scope.LaunchTemplateScope, imag
522522
data.InstanceMarketOptions = getLaunchTemplateInstanceMarketOptionsRequest(scope.GetLaunchTemplate().SpotMarketOptions)
523523
data.PrivateDnsNameOptions = getLaunchTemplatePrivateDNSNameOptionsRequest(scope.GetLaunchTemplate().PrivateDNSName)
524524

525+
blockDeviceMappings := []*ec2.LaunchTemplateBlockDeviceMappingRequest{}
526+
525527
// Set up root volume
526528
if lt.RootVolume != nil {
527529
rootDeviceName, err := s.checkRootVolume(lt.RootVolume, *data.ImageId)
@@ -532,9 +534,18 @@ func (s *Service) createLaunchTemplateData(scope scope.LaunchTemplateScope, imag
532534
lt.RootVolume.DeviceName = aws.StringValue(rootDeviceName)
533535

534536
req := volumeToLaunchTemplateBlockDeviceMappingRequest(lt.RootVolume)
535-
data.BlockDeviceMappings = []*ec2.LaunchTemplateBlockDeviceMappingRequest{
536-
req,
537-
}
537+
blockDeviceMappings = append(blockDeviceMappings, req)
538+
}
539+
540+
for vi := range lt.NonRootVolumes {
541+
nonRootVolume := lt.NonRootVolumes[vi]
542+
543+
blockDeviceMapping := volumeToLaunchTemplateBlockDeviceMappingRequest(&nonRootVolume)
544+
blockDeviceMappings = append(blockDeviceMappings, blockDeviceMapping)
545+
}
546+
547+
if len(blockDeviceMappings) > 0 {
548+
data.BlockDeviceMappings = blockDeviceMappings
538549
}
539550

540551
data.TagSpecifications = s.buildLaunchTemplateTagSpecificationRequest(scope, userDataSecretKey)

0 commit comments

Comments
 (0)