Skip to content

Commit

Permalink
feat(aws): Support rollback of a disabled server group (#5077)
Browse files Browse the repository at this point in the history
A disabled server group can be rolled back iff at least one enabled
server group exists in the same cluster.

The largest enabled server group in the cluster will will be selected as
the rollback source.

depends on spinnaker/clouddriver#2455
  • Loading branch information
ajordens committed Mar 29, 2018
1 parent 81c0307 commit ccdfe60
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react';
import { BindAll } from 'lodash-decorators';
import { Dropdown, Tooltip } from 'react-bootstrap';
import { get, find, filter } from 'lodash';
import { get, find, filter, orderBy } from 'lodash';

import { IOwnerOption, IServerGroupActionsProps, IServerGroupJob, NgReact, ReactInjector, SETTINGS } from '@spinnaker/core';

Expand All @@ -26,6 +26,24 @@ export class AmazonServerGroupActions extends React.Component<IAmazonServerGroup
return false;
}

private isRollbackEnabled(): boolean {
const { app, serverGroup } = this.props;

if (!serverGroup.isDisabled) {
// enabled server groups are always a candidate for rollback
return true;
}

// if the server group selected for rollback is disabled, ensure that at least one enabled server group exists
return app.getDataSource('serverGroups').data.some((g: IAmazonServerGroup) =>
g.cluster === serverGroup.cluster &&
g.region === serverGroup.region &&
g.account === serverGroup.account &&
!g.isDisabled
);
}


private hasDisabledInstances(): boolean {
// server group may have disabled instances (out of service) but NOT itself be disabled
return this.props.serverGroup.isDisabled || (get(this.props.serverGroup, 'instanceCounts.outOfService', 0) > 0);
Expand Down Expand Up @@ -140,23 +158,45 @@ export class AmazonServerGroupActions extends React.Component<IAmazonServerGroup
};

private rollbackServerGroup(): void {
const { app, serverGroup } = this.props;
const { app } = this.props;

let serverGroup: IAmazonServerGroup = this.props.serverGroup;
let previousServerGroup: IAmazonServerGroup;
let allServerGroups = app.getDataSource('serverGroups').data.filter((g: IAmazonServerGroup) =>
g.cluster === serverGroup.cluster &&
g.region === serverGroup.region &&
g.account === serverGroup.account
);

if (serverGroup.isDisabled) {
// if the selected server group is disabled, it represents the server group that should be _rolled back to_
previousServerGroup = serverGroup;

/*
* Find an existing server group to rollback, prefer the largest enabled server group.
*
* isRollbackEnabled() ensures that at least one enabled server group exists.
*/
serverGroup = orderBy(
allServerGroups.filter((g: IAmazonServerGroup) => g.name !== previousServerGroup.name && !g.isDisabled),
['instanceCounts.total'], ['desc']
)[0] as IAmazonServerGroup;
}

// the set of all server groups should not include the server group selected for rollback
allServerGroups = allServerGroups.filter((g: IAmazonServerGroup) => g.name !== serverGroup.name);

ReactInjector.modalService.open({
templateUrl: ReactInjector.overrideRegistry.getTemplate('aws.rollback.modal', require('./rollback/rollbackServerGroup.html')),
controller: 'awsRollbackServerGroupCtrl as ctrl',
resolve: {
serverGroup: () => serverGroup,
previousServerGroup: () => previousServerGroup,
disabledServerGroups: () => {
const cluster = find(app.clusters, { name: serverGroup.cluster, account: serverGroup.account, serverGroups: [] });
return filter(cluster.serverGroups, { isDisabled: true, region: serverGroup.region });
},
allServerGroups: () => app.getDataSource('serverGroups').data.filter((g: IAmazonServerGroup) =>
g.cluster === serverGroup.cluster &&
g.region === serverGroup.region &&
g.account === serverGroup.account &&
g.name !== serverGroup.name
),
allServerGroups: () => allServerGroups,
application: () => app
}
});
Expand Down Expand Up @@ -200,8 +240,8 @@ export class AmazonServerGroupActions extends React.Component<IAmazonServerGroup
Server Group Actions
</Dropdown.Toggle>
<Dropdown.Menu className="dropdown-menu">
{!serverGroup.isDisabled && <li><a className="clickable" onClick={this.rollbackServerGroup}>Rollback</a></li>}
{!serverGroup.isDisabled && <li role="presentation" className="divider"/>}
{this.isRollbackEnabled() && <li><a className="clickable" onClick={this.rollbackServerGroup}>Rollback</a></li>}
{this.isRollbackEnabled() && <li role="presentation" className="divider"/>}
<li><a className="clickable" onClick={this.resizeServerGroup}>Resize</a></li>
{!serverGroup.isDisabled && <li><a className="clickable" onClick={this.disableServerGroup}>Disable</a></li>}
{this.hasDisabledInstances() && !this.isEnableLocked() && <li><a className="clickable" onClick={this.enableServerGroup}>Enable</a></li>}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ module.exports = angular.module('spinnaker.amazon.serverGroup.details.rollback.c
])
.controller('awsRollbackServerGroupCtrl', function ($scope, $uibModalInstance, serverGroupWriter,
taskMonitorBuilder,
application, serverGroup, disabledServerGroups, allServerGroups) {
application,
serverGroup, previousServerGroup,
disabledServerGroups, allServerGroups) {
$scope.serverGroup = serverGroup;
$scope.disabledServerGroups = disabledServerGroups.sort((a, b) => b.name.localeCompare(a.name));
$scope.allServerGroups = allServerGroups.sort((a, b) => b.name.localeCompare(a.name));
Expand Down Expand Up @@ -54,6 +56,7 @@ module.exports = angular.module('spinnaker.amazon.serverGroup.details.rollback.c
rollbackType: rollbackType,
rollbackContext: {
rollbackServerGroupName: serverGroup.name,
restoreServerGroupName: previousServerGroup ? previousServerGroup.name : undefined,
targetHealthyRollbackPercentage: healthyPercent
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ <h3>Rollback {{serverGroup.name}}</h3>
<div class="col-sm-3 sm-label-right">
Restore to
</div>
<div class="col-sm-8">
<div class="col-md-7">
<ui-select ng-model="command.rollbackContext.restoreServerGroupName"
class="form-control input-sm"
ng-if="command.rollbackType === 'EXPLICIT'">
Expand Down Expand Up @@ -42,9 +42,7 @@ <h3>Rollback {{serverGroup.name}}</h3>
</div>
</div>

<div class="row">
<task-reason command="command"></task-reason>
</div>
<task-reason command="command"></task-reason>

<div class="row">
<div class="col-sm-11 col-sm-offset-1">
Expand Down

0 comments on commit ccdfe60

Please sign in to comment.