in upup/pkg/fi/cloudup/spotinsttasks/ocean.go [588:994]
func (_ *Ocean) update(cloud awsup.AWSCloud, a, e, changes *Ocean) error {
klog.V(2).Infof("Updating Ocean %q", *e.Name)
actual, err := e.find(cloud.Spotinst().Ocean(), *e.Name)
if err != nil {
klog.Errorf("Unable to resolve Ocean %q, error: %s", *e.Name, err)
return err
}
var changed bool
ocean := new(aws.Cluster)
ocean.SetId(actual.ID)
// Strategy.
{
// Fallback to on-demand.
if changes.FallbackToOnDemand != nil {
if ocean.Strategy == nil {
ocean.Strategy = new(aws.Strategy)
}
ocean.Strategy.SetFallbackToOnDemand(e.FallbackToOnDemand)
changes.FallbackToOnDemand = nil
changed = true
}
// Utilize reserved instances.
if changes.UtilizeReservedInstances != nil {
if ocean.Strategy == nil {
ocean.Strategy = new(aws.Strategy)
}
ocean.Strategy.SetUtilizeReservedInstances(e.UtilizeReservedInstances)
changes.UtilizeReservedInstances = nil
changed = true
}
// Utilize commitments.
if changes.UtilizeCommitments != nil {
if ocean.Strategy == nil {
ocean.Strategy = new(aws.Strategy)
}
ocean.Strategy.SetUtilizeCommitments(e.UtilizeCommitments)
changes.UtilizeCommitments = nil
changed = true
}
// Draining timeout.
if changes.DrainingTimeout != nil {
if ocean.Strategy == nil {
ocean.Strategy = new(aws.Strategy)
}
ocean.Strategy.SetDrainingTimeout(fi.Int(int(*e.DrainingTimeout)))
changes.DrainingTimeout = nil
changed = true
}
// Grace period.
if changes.GracePeriod != nil {
if ocean.Strategy == nil {
ocean.Strategy = new(aws.Strategy)
}
ocean.Strategy.SetGracePeriod(fi.Int(int(*e.GracePeriod)))
changes.GracePeriod = nil
changed = true
}
}
// Compute.
{
// Subnets.
{
if changes.Subnets != nil {
if ocean.Compute == nil {
ocean.Compute = new(aws.Compute)
}
subnetIDs := make([]string, len(e.Subnets))
for i, subnet := range e.Subnets {
subnetIDs[i] = fi.StringValue(subnet.ID)
}
ocean.Compute.SetSubnetIDs(subnetIDs)
changes.Subnets = nil
changed = true
}
}
// Instance types.
{
// 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
}
}
// 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
}
}
}
// Launch specification.
{
// Security groups.
{
if changes.SecurityGroups != nil {
if ocean.Compute == nil {
ocean.Compute = new(aws.Compute)
}
if ocean.Compute.LaunchSpecification == nil {
ocean.Compute.LaunchSpecification = new(aws.LaunchSpecification)
}
securityGroupIDs := make([]string, len(e.SecurityGroups))
for i, sg := range e.SecurityGroups {
securityGroupIDs[i] = *sg.ID
}
ocean.Compute.LaunchSpecification.SetSecurityGroupIDs(securityGroupIDs)
changes.SecurityGroups = nil
changed = true
}
}
// User data.
{
if changes.UserData != nil {
userData, err := fi.ResourceAsString(e.UserData)
if err != nil {
return err
}
if len(userData) > 0 {
if ocean.Compute == nil {
ocean.Compute = new(aws.Compute)
}
if ocean.Compute.LaunchSpecification == nil {
ocean.Compute.LaunchSpecification = new(aws.LaunchSpecification)
}
encoded := base64.StdEncoding.EncodeToString([]byte(userData))
ocean.Compute.LaunchSpecification.SetUserData(fi.String(encoded))
changed = true
}
changes.UserData = nil
}
}
// Image.
{
if changes.ImageID != nil {
image, err := resolveImage(cloud, fi.StringValue(e.ImageID))
if err != nil {
return err
}
if *actual.Compute.LaunchSpecification.ImageID != *image.ImageId {
if ocean.Compute == nil {
ocean.Compute = new(aws.Compute)
}
if ocean.Compute.LaunchSpecification == nil {
ocean.Compute.LaunchSpecification = new(aws.LaunchSpecification)
}
ocean.Compute.LaunchSpecification.SetImageId(image.ImageId)
changed = true
}
changes.ImageID = nil
}
}
// Tags.
{
if changes.Tags != nil {
if ocean.Compute == nil {
ocean.Compute = new(aws.Compute)
}
if ocean.Compute.LaunchSpecification == nil {
ocean.Compute.LaunchSpecification = new(aws.LaunchSpecification)
}
ocean.Compute.LaunchSpecification.SetTags(e.buildTags())
changes.Tags = nil
changed = true
}
}
// IAM instance profile.
{
if changes.IAMInstanceProfile != nil {
if ocean.Compute == nil {
ocean.Compute = new(aws.Compute)
}
if ocean.Compute.LaunchSpecification == nil {
ocean.Compute.LaunchSpecification = new(aws.LaunchSpecification)
}
iprof := new(aws.IAMInstanceProfile)
iprof.SetName(e.IAMInstanceProfile.GetName())
ocean.Compute.LaunchSpecification.SetIAMInstanceProfile(iprof)
changes.IAMInstanceProfile = nil
changed = true
}
}
// Monitoring.
{
if changes.Monitoring != nil {
if ocean.Compute == nil {
ocean.Compute = new(aws.Compute)
}
if ocean.Compute.LaunchSpecification == nil {
ocean.Compute.LaunchSpecification = new(aws.LaunchSpecification)
}
ocean.Compute.LaunchSpecification.SetMonitoring(e.Monitoring)
changes.Monitoring = nil
changed = true
}
}
// SSH key.
{
if changes.SSHKey != nil {
if ocean.Compute == nil {
ocean.Compute = new(aws.Compute)
}
if ocean.Compute.LaunchSpecification == nil {
ocean.Compute.LaunchSpecification = new(aws.LaunchSpecification)
}
ocean.Compute.LaunchSpecification.SetKeyPair(e.SSHKey.Name)
changes.SSHKey = nil
changed = true
}
}
// Public IP.
{
if changes.AssociatePublicIP != nil {
if ocean.Compute == nil {
ocean.Compute = new(aws.Compute)
}
if ocean.Compute.LaunchSpecification == nil {
ocean.Compute.LaunchSpecification = new(aws.LaunchSpecification)
}
ocean.Compute.LaunchSpecification.SetAssociatePublicIPAddress(e.AssociatePublicIP)
changes.AssociatePublicIP = nil
changed = true
}
}
// Root volume options.
{
if opts := changes.RootVolumeOpts; opts != nil {
// Volume size.
if opts.Size != nil {
if ocean.Compute == nil {
ocean.Compute = new(aws.Compute)
}
if ocean.Compute.LaunchSpecification == nil {
ocean.Compute.LaunchSpecification = new(aws.LaunchSpecification)
}
ocean.Compute.LaunchSpecification.SetRootVolumeSize(fi.Int(int(*opts.Size)))
changed = true
}
// EBS optimization.
if opts.Optimization != nil {
if ocean.Compute == nil {
ocean.Compute = new(aws.Compute)
}
if ocean.Compute.LaunchSpecification == nil {
ocean.Compute.LaunchSpecification = new(aws.LaunchSpecification)
}
ocean.Compute.LaunchSpecification.SetEBSOptimized(e.RootVolumeOpts.Optimization)
changed = true
}
changes.RootVolumeOpts = nil
}
}
}
}
// Capacity.
{
if changes.MinSize != nil {
if ocean.Capacity == nil {
ocean.Capacity = new(aws.Capacity)
}
ocean.Capacity.SetMinimum(fi.Int(int(*e.MinSize)))
changes.MinSize = nil
changed = true
// Scale up the target capacity, if needed.
if int64(*actual.Capacity.Target) < *e.MinSize {
ocean.Capacity.SetTarget(fi.Int(int(*e.MinSize)))
}
}
if changes.MaxSize != nil {
if ocean.Capacity == nil {
ocean.Capacity = new(aws.Capacity)
}
ocean.Capacity.SetMaximum(fi.Int(int(*e.MaxSize)))
changes.MaxSize = nil
changed = true
}
}
// Auto Scaler.
{
if opts := changes.AutoScalerOpts; opts != nil {
if opts.Enabled != nil {
autoScaler := new(aws.AutoScaler)
autoScaler.IsEnabled = e.AutoScalerOpts.Enabled
autoScaler.IsAutoConfig = e.AutoScalerOpts.AutoConfig
autoScaler.AutoHeadroomPercentage = e.AutoScalerOpts.AutoHeadroomPercentage
autoScaler.Cooldown = e.AutoScalerOpts.Cooldown
// Scale down.
if down := opts.Down; down != nil {
autoScaler.Down = &aws.AutoScalerDown{
MaxScaleDownPercentage: down.MaxPercentage,
EvaluationPeriods: down.EvaluationPeriods,
}
} else if a.AutoScalerOpts.Down != nil {
autoScaler.SetDown(nil)
}
// Resource limits.
if limits := opts.ResourceLimits; limits != nil {
autoScaler.ResourceLimits = &aws.AutoScalerResourceLimits{
MaxVCPU: limits.MaxVCPU,
MaxMemoryGiB: limits.MaxMemory,
}
} else if a.AutoScalerOpts.ResourceLimits != nil {
autoScaler.SetResourceLimits(nil)
}
ocean.SetAutoScaler(autoScaler)
changed = true
}
changes.AutoScalerOpts = nil
}
}
empty := &Ocean{}
if !reflect.DeepEqual(empty, changes) {
klog.Warningf("Not all changes applied to Ocean %q: %v", *ocean.ID, changes)
}
if !changed {
klog.V(2).Infof("No changes detected in Ocean %q", *ocean.ID)
return nil
}
klog.V(2).Infof("Updating Ocean %q (config: %s)", *ocean.ID, stringutil.Stringify(ocean))
// Wrap the raw object as an Ocean.
oc, err := spotinst.NewOcean(cloud.ProviderID(), ocean)
if err != nil {
return err
}
// Update an existing Ocean.
if err := cloud.Spotinst().Ocean().Update(context.Background(), oc); err != nil {
return fmt.Errorf("spotinst: failed to update ocean: %v", err)
}
return nil
}