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

Additional volume options #161

Merged
merged 6 commits into from
Aug 7, 2020
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 24 additions & 5 deletions api/v1alpha1/instancegroup_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,14 +187,18 @@ type EKSConfiguration struct {

type UserDataStage struct {
Name string `json:"name,omitempty"`
Stage string `json:"stage,omitempty"`
Data string `json:"data,omitempty"`
Stage string `json:"stage"`
Data string `json:"data"`
}

type NodeVolume struct {
Name string `json:"name,omitempty"`
Type string `json:"type,omitempty"`
Size int64 `json:"size,omitempty"`
Name string `json:"name"`
Type string `json:"type"`
Size int64 `json:"size"`
Iops int64 `json:"iops,omitempty"`
DeleteOnTermination *bool `json:"deleteOnTermination,omitempty"`
Encrypted *bool `json:"encrypted,omitempty"`
SnapshotID string `json:"snapshotId,omitempty"`
}
type EKSFargateSpec struct {
ClusterName string `json:"clusterName"`
Expand Down Expand Up @@ -313,6 +317,21 @@ func (c *EKSConfiguration) Validate() error {
if common.StringEmpty(c.KeyPairName) {
return errors.Errorf("validation failed, 'keyPair' is a required parameter")
}

for _, v := range c.Volumes {
if !common.ContainsEqualFold(awsprovider.AllowedVolumeTypes, v.Type) {
return errors.Errorf("validation failed, volume type '%v' is unsuppoeted", v.Type)
}
if v.SnapshotID != "" {
if v.Size > 0 {
return errors.Errorf("validation failed, 'volume.snapshotId' and 'volume.size' are mutually exclusive")
}
}
if v.Iops != 0 && v.Iops < 100 {
return errors.Errorf("validation failed, volume IOPS must be min 100")
}
}

if len(c.Volumes) == 0 {
c.Volumes = []NodeVolume{
{
Expand Down
14 changes: 13 additions & 1 deletion api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions config/crd/bases/instancemgr.keikoproj.io_instancegroups.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -158,18 +158,34 @@ spec:
type: string
stage:
type: string
required:
- data
- stage
type: object
type: array
volumes:
items:
properties:
deleteOnTermination:
type: boolean
encrypted:
type: boolean
iops:
format: int64
type: integer
name:
type: string
size:
format: int64
type: integer
snapshotId:
type: string
type:
type: string
required:
- name
- size
- type
type: object
type: array
type: object
Expand Down
29 changes: 24 additions & 5 deletions controllers/providers/aws/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ var (
"GroupTotalInstances",
"GroupTotalCapacity",
}

AllowedVolumeTypes = []string{"gp2", "io1", "sc1", "st1"}
)

const (
Expand Down Expand Up @@ -151,15 +153,32 @@ func (w *AwsWorker) InstanceProfileExist(name string) (*iam.InstanceProfile, boo
return out.InstanceProfile, true
}

func (w *AwsWorker) GetBasicBlockDevice(name, volType string, volSize int64) *autoscaling.BlockDeviceMapping {
return &autoscaling.BlockDeviceMapping{
func (w *AwsWorker) GetBasicBlockDevice(name, volType, snapshot string, volSize, iops int64, delete, encrypt *bool) *autoscaling.BlockDeviceMapping {
device := &autoscaling.BlockDeviceMapping{
DeviceName: aws.String(name),
Ebs: &autoscaling.Ebs{
VolumeSize: aws.Int64(volSize),
VolumeType: aws.String(volType),
DeleteOnTermination: aws.Bool(true),
VolumeType: aws.String(volType),
},
}
if delete != nil {
device.Ebs.DeleteOnTermination = delete
} else {
device.Ebs.DeleteOnTermination = aws.Bool(true)
}
if encrypt != nil {
device.Ebs.Encrypted = encrypt
}
if iops != 0 {
device.Ebs.Iops = aws.Int64(iops)
eytan-avisror marked this conversation as resolved.
Show resolved Hide resolved
}
if volSize != 0 {
device.Ebs.VolumeSize = aws.Int64(volSize)
}
if !common.StringEmpty(snapshot) {
device.Ebs.SnapshotId = aws.String(snapshot)
}

return device
}

func (w *AwsWorker) CreateLaunchConfig(input *autoscaling.CreateLaunchConfigurationInput) error {
Expand Down
2 changes: 1 addition & 1 deletion controllers/provisioners/eks/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ func (ctx *EksInstanceGroupContext) GetBlockDeviceList() []*autoscaling.BlockDev

customVolumes := configuration.GetVolumes()
for _, v := range customVolumes {
devices = append(devices, ctx.AwsWorker.GetBasicBlockDevice(v.Name, v.Type, v.Size))
devices = append(devices, ctx.AwsWorker.GetBasicBlockDevice(v.Name, v.Type, v.SnapshotID, v.Size, v.Iops, v.DeleteOnTermination, v.Encrypted))
}

return devices
Expand Down
2 changes: 1 addition & 1 deletion controllers/provisioners/eks/update_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ func TestLaunchConfigurationDrifted(t *testing.T) {
keyDrift.KeyName = aws.String("some-key")
usrDrift.UserData = aws.String("some-userdata")
devDrift.BlockDeviceMappings = []*autoscaling.BlockDeviceMapping{
w.GetBasicBlockDevice("some-device", "some-type", 0),
w.GetBasicBlockDevice("some-device", "some-type", "", 32, 0, nil, nil),
}

tests := []struct {
Expand Down
14 changes: 9 additions & 5 deletions docs/EKS.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ spec:
configuration:
userData:
- name: <string> : name of the stage
stage: <string> : represents the stage of the script, allowed values are PreBootstrap, PostBootstrap
data: <string> : represents the script payload to inject
stage: <string> : represents the stage of the script, allowed values are PreBootstrap, PostBootstrap (required)
data: <string> : represents the script payload to inject (required)
```

### NodeVolume
Expand All @@ -112,9 +112,13 @@ spec:
eks:
configuration:
volumes:
- name: <string> : represents the device name, e.g. /dev/xvda
type: <string> : represents the type of volume, must be one of supported types "standard", "io1", "gp2", "st1", "sc1".
size: <int64> : represents a volume size in gigabytes
- name: <string> : represents the device name, e.g. /dev/xvda (required)
type: <string> : represents the type of volume, must be one of supported types "standard", "io1", "gp2", "st1", "sc1" (required)
size: <int64> : represents a volume size in gigabytes, cannot be used with snapshotId
snapshotId : <string> : represents a snapshot ID to use, cannot be used with size
iops: <int64> : represents number of IOPS to provision volume with (min 100)
deleteOnTermination : <bool> : delete the EBS volume when the instance is terminated (defaults to true)
encrypted: <bool> : encrypt the EBS volume with a KMS key
```

### Taint
Expand Down