Skip to content

Commit

Permalink
feat(spotinst/ocean): add support for blacklisting or whitelisting in…
Browse files Browse the repository at this point in the history
…stance types
  • Loading branch information
liranp committed Feb 13, 2020
1 parent 91867ce commit d20fbf3
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 20 deletions.
28 changes: 27 additions & 1 deletion pkg/model/spotinstmodel/instance_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,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"
Expand Down Expand Up @@ -321,7 +327,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:
Expand All @@ -341,6 +347,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
}
}
}

Expand Down Expand Up @@ -763,6 +781,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

Expand Down
98 changes: 79 additions & 19 deletions upup/pkg/fi/cloudup/spotinsttasks/ocean.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
}
}
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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.InstanceTypesWhitelist)
changes.InstanceTypesWhitelist = nil
changed = true
}
}

ocean.Compute.InstanceTypes.SetWhitelist(e.InstanceTypes)
changes.InstanceTypes = 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
}
}
}

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down

0 comments on commit d20fbf3

Please sign in to comment.