Merge pull request #8549 from spotinst/feature-spotinst-ocean-instance-types

Spotinst: Add support for blacklisting or whitelisting instance types in Ocean
This commit is contained in:
Kubernetes Prow Robot 2020-02-23 07:24:47 -08:00 committed by GitHub
commit a264f1d4d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 107 additions and 21 deletions

View File

@ -61,6 +61,12 @@ const (
// Launch Spec for the Ocean cluster.
InstanceGroupLabelOceanDefaultLaunchSpec = "spotinst.io/ocean-default-launchspec"
// InstanceGroupLabelOceanInstanceTypes[White|Black]list are the metadata labels
// used on the instance group to specify whether to whitelist or blacklist
// specific instance types.
InstanceGroupLabelOceanInstanceTypesWhitelist = "spotinst.io/ocean-instance-types-whitelist"
InstanceGroupLabelOceanInstanceTypesBlacklist = "spotinst.io/ocean-instance-types-blacklist"
// InstanceGroupLabelAutoScalerDisabled is the metadata label used on the
// instance group to specify whether the auto scaler should be enabled.
InstanceGroupLabelAutoScalerDisabled = "spotinst.io/autoscaler-disabled"
@ -320,7 +326,7 @@ func (b *InstanceGroupModelBuilder) buildOcean(c *fi.ModelBuilderContext, igs ..
// Image.
ocean.ImageID = fi.String(ig.Spec.Image)
// Strategy.
// Strategy and instance types.
for k, v := range ig.ObjectMeta.Labels {
switch k {
case InstanceGroupLabelSpotPercentage:
@ -340,6 +346,18 @@ func (b *InstanceGroupModelBuilder) buildOcean(c *fi.ModelBuilderContext, igs ..
if err != nil {
return err
}
case InstanceGroupLabelOceanInstanceTypesWhitelist:
ocean.InstanceTypesWhitelist, err = parseStringSlice(v)
if err != nil {
return err
}
case InstanceGroupLabelOceanInstanceTypesBlacklist:
ocean.InstanceTypesBlacklist, err = parseStringSlice(v)
if err != nil {
return err
}
}
}
@ -760,6 +778,14 @@ func parseInt(str string) (*int64, error) {
return &v, nil
}
func parseStringSlice(str string) ([]string, error) {
v := strings.Split(str, ",")
for i, s := range v {
v[i] = strings.TrimSpace(s)
}
return v, nil
}
func defaultSpotPercentage(ig *kops.InstanceGroup) *float64 {
var percentage float64

View File

@ -46,7 +46,8 @@ type Ocean struct {
SpotPercentage *float64
UtilizeReservedInstances *bool
FallbackToOnDemand *bool
InstanceTypes []string
InstanceTypesWhitelist []string
InstanceTypesBlacklist []string
Tags map[string]string
UserData *fi.ResourceHolder
ImageID *string
@ -166,8 +167,14 @@ func (o *Ocean) Find(c *fi.Context) (*Ocean, error) {
// Instance types.
{
if itypes := compute.InstanceTypes; itypes != nil {
if itypes.Whitelist != nil && len(itypes.Whitelist) > 0 {
actual.InstanceTypes = itypes.Whitelist
// Whitelist.
if len(itypes.Whitelist) > 0 {
actual.InstanceTypesWhitelist = itypes.Whitelist
}
// Blacklist.
if len(itypes.Blacklist) > 0 {
actual.InstanceTypesBlacklist = itypes.Blacklist
}
}
}
@ -361,6 +368,25 @@ func (_ *Ocean) create(cloud awsup.AWSCloud, a, e, changes *Ocean) error {
}
}
// Instance types.
{
itypes := new(aws.InstanceTypes)
// Whitelist.
if e.InstanceTypesWhitelist != nil {
itypes.SetWhitelist(e.InstanceTypesWhitelist)
}
// Blacklist.
if e.InstanceTypesBlacklist != nil {
itypes.SetBlacklist(e.InstanceTypesBlacklist)
}
if len(itypes.Whitelist) > 0 || len(itypes.Blacklist) > 0 {
ocean.Compute.SetInstanceTypes(itypes)
}
}
// Launch specification.
{
ocean.Compute.LaunchSpecification.SetMonitoring(e.Monitoring)
@ -583,17 +609,36 @@ func (_ *Ocean) update(cloud awsup.AWSCloud, a, e, changes *Ocean) error {
// Instance types.
{
if changes.InstanceTypes != nil {
if ocean.Compute == nil {
ocean.Compute = new(aws.Compute)
}
if ocean.Compute.InstanceTypes == nil {
ocean.Compute.InstanceTypes = new(aws.InstanceTypes)
}
// Whitelist.
{
if changes.InstanceTypesWhitelist != nil {
if ocean.Compute == nil {
ocean.Compute = new(aws.Compute)
}
if ocean.Compute.InstanceTypes == nil {
ocean.Compute.InstanceTypes = new(aws.InstanceTypes)
}
ocean.Compute.InstanceTypes.SetWhitelist(e.InstanceTypes)
changes.InstanceTypes = nil
changed = true
ocean.Compute.InstanceTypes.SetWhitelist(e.InstanceTypesWhitelist)
changes.InstanceTypesWhitelist = nil
changed = true
}
}
// Blacklist.
{
if changes.InstanceTypesBlacklist != nil {
if ocean.Compute == nil {
ocean.Compute = new(aws.Compute)
}
if ocean.Compute.InstanceTypes == nil {
ocean.Compute.InstanceTypes = new(aws.InstanceTypes)
}
ocean.Compute.InstanceTypes.SetBlacklist(e.InstanceTypesBlacklist)
changes.InstanceTypesBlacklist = nil
changed = true
}
}
}
@ -868,13 +913,15 @@ func (_ *Ocean) update(cloud awsup.AWSCloud, a, e, changes *Ocean) error {
}
type terraformOcean struct {
Name *string `json:"name,omitempty"`
ControllerClusterID *string `json:"controller_id,omitempty"`
Region *string `json:"region,omitempty"`
SubnetIDs []*terraform.Literal `json:"subnet_ids,omitempty"`
AutoScaler *terraformAutoScaler `json:"autoscaler,omitempty"`
Tags []*terraformKV `json:"tags,omitempty"`
Lifecycle *terraformLifecycle `json:"lifecycle,omitempty"`
Name *string `json:"name,omitempty"`
ControllerClusterID *string `json:"controller_id,omitempty"`
Region *string `json:"region,omitempty"`
InstanceTypesWhitelist []string `json:"whitelist,omitempty"`
InstanceTypesBlacklist []string `json:"blacklist,omitempty"`
SubnetIDs []*terraform.Literal `json:"subnet_ids,omitempty"`
AutoScaler *terraformAutoScaler `json:"autoscaler,omitempty"`
Tags []*terraformKV `json:"tags,omitempty"`
Lifecycle *terraformLifecycle `json:"lifecycle,omitempty"`
*terraformOceanCapacity
*terraformOceanStrategy
@ -1013,6 +1060,19 @@ func (_ *Ocean) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *Oce
}
}
// Instance types.
{
// Whitelist.
if e.InstanceTypesWhitelist != nil {
tf.InstanceTypesWhitelist = e.InstanceTypesWhitelist
}
// Blacklist.
if e.InstanceTypesBlacklist != nil {
tf.InstanceTypesBlacklist = e.InstanceTypesBlacklist
}
}
// Auto Scaler.
{
if opts := e.AutoScalerOpts; opts != nil {