-
Notifications
You must be signed in to change notification settings - Fork 900
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Essentially a copy & paste from AWS with very minor modifications!
- Loading branch information
Showing
4 changed files
with
268 additions
and
0 deletions.
There are no files selected for viewing
124 changes: 124 additions & 0 deletions
124
serverGroup/details/rollback/rollbackServerGroup.controller.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
'use strict'; | ||
|
||
const angular = require('angular'); | ||
|
||
import { get } from 'lodash'; | ||
import { SERVER_GROUP_WRITER, TASK_MONITOR_BUILDER } from '@spinnaker/core'; | ||
|
||
module.exports = angular.module('spinnaker.titus.serverGroup.details.rollback.controller', [ | ||
SERVER_GROUP_WRITER, | ||
TASK_MONITOR_BUILDER, | ||
]) | ||
.controller('titusRollbackServerGroupCtrl', function ($scope, $uibModalInstance, serverGroupWriter, | ||
taskMonitorBuilder, | ||
application, serverGroup, 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)); | ||
$scope.verification = {}; | ||
|
||
var desired = serverGroup.capacity.desired; | ||
|
||
var rollbackType = 'EXPLICIT'; | ||
|
||
if (allServerGroups.length === 0 && serverGroup.entityTags) { | ||
const previousServerGroup = get(serverGroup, 'entityTags.creationMetadata.value.previousServerGroup'); | ||
if (previousServerGroup) { | ||
rollbackType = 'PREVIOUS_IMAGE'; | ||
$scope.previousServerGroup = { | ||
name: previousServerGroup.name, | ||
imageName: previousServerGroup.imageName | ||
}; | ||
|
||
if (previousServerGroup.imageId && previousServerGroup.imageId !== previousServerGroup.imageName) { | ||
$scope.previousServerGroup.imageId = previousServerGroup.imageId; | ||
} | ||
} | ||
} | ||
|
||
if (desired < 10) { | ||
var healthyPercent = 100; | ||
} else if (desired < 20) { | ||
// accept 1 instance in an unknown state during rollback | ||
healthyPercent = 90; | ||
} else { | ||
healthyPercent = 95; | ||
} | ||
|
||
$scope.command = { | ||
rollbackType: rollbackType, | ||
rollbackContext: { | ||
rollbackServerGroupName: serverGroup.name, | ||
targetHealthyRollbackPercentage: healthyPercent | ||
} | ||
}; | ||
|
||
$scope.minHealthy = function(percent) { | ||
return Math.ceil(desired * percent / 100); | ||
}; | ||
|
||
if (application && application.attributes) { | ||
if (application.attributes.platformHealthOnlyShowOverride && application.attributes.platformHealthOnly) { | ||
$scope.command.interestingHealthProviderNames = ['Titus']; | ||
} | ||
|
||
$scope.command.platformHealthOnlyShowOverride = application.attributes.platformHealthOnlyShowOverride; | ||
} | ||
|
||
this.isValid = function () { | ||
var command = $scope.command; | ||
if (!$scope.verification.verified) { | ||
return false; | ||
} | ||
|
||
if (rollbackType === 'PREVIOUS_IMAGE') { | ||
// no need to validate when using an explicit image | ||
return true; | ||
} | ||
|
||
return command.rollbackContext.restoreServerGroupName !== undefined; | ||
}; | ||
|
||
$scope.taskMonitor = taskMonitorBuilder.buildTaskMonitor({ | ||
application: application, | ||
title: 'Rollback ' + serverGroup.name, | ||
modalInstance: $uibModalInstance, | ||
}); | ||
|
||
this.rollback = function () { | ||
if (!this.isValid()) { | ||
return; | ||
} | ||
|
||
var submitMethod = function () { | ||
return serverGroupWriter.rollbackServerGroup(serverGroup, application, $scope.command); | ||
}; | ||
|
||
$scope.taskMonitor.submit(submitMethod); | ||
}; | ||
|
||
this.cancel = function () { | ||
$uibModalInstance.dismiss(); | ||
}; | ||
|
||
this.label = function (serverGroup) { | ||
if (!serverGroup) { | ||
return ''; | ||
} | ||
|
||
if (!serverGroup.buildInfo || !serverGroup.buildInfo.images) { | ||
return serverGroup.name; | ||
} | ||
|
||
var imageName = serverGroup.buildInfo.images[0]; | ||
if (imageName.indexOf('/') > 0) { | ||
imageName = imageName.substring(imageName.indexOf('/') + 1); | ||
} | ||
|
||
return serverGroup.name + ' (' + imageName + ')' | ||
}; | ||
|
||
this.group = function (serverGroup) { | ||
return serverGroup.isDisabled ? 'Disabled Server Groups' : 'Enabled Server Groups'; | ||
}; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
<div modal-page class="confirmation-modal"> | ||
<task-monitor monitor="taskMonitor"></task-monitor> | ||
<form role="form"> | ||
<modal-close dismiss="$dismiss()"></modal-close> | ||
<div class="modal-header"> | ||
<h3>Rollback {{serverGroup.name}}</h3> | ||
</div> | ||
<div class="modal-body confirmation-modal"> | ||
<div class="row"> | ||
<div class="col-sm-3 sm-label-right"> | ||
Restore to | ||
</div> | ||
<div class="col-sm-8"> | ||
<ui-select ng-model="command.rollbackContext.restoreServerGroupName" | ||
class="form-control input-sm" | ||
ng-if="command.rollbackType === 'EXPLICIT'"> | ||
<ui-select-match placeholder="Select...">{{ctrl.label($select.selected)}}</ui-select-match> | ||
<ui-select-choices group-by="ctrl.group" repeat="serverGroup.name as serverGroup in allServerGroups"> | ||
<span ng-bind-html="ctrl.label(serverGroup)"></span> | ||
</ui-select-choices> | ||
</ui-select> | ||
<div ng-if="command.rollbackType === 'PREVIOUS_IMAGE'" style="margin-top: 5px"> | ||
{{ previousServerGroup.name }} <span class="small">(no longer deployed)</span><br/> | ||
<span class="small"> | ||
<strong>Image</strong>: {{ previousServerGroup.imageName}} | ||
<span ng-if="previousServerGroup.imageId">({{ previousServerGroup.imageId }})</span><br/> | ||
</span> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<div class="row" ng-if="command.platformHealthOnlyShowOverride"> | ||
<div class="col-sm-10 col-sm-offset-1"> | ||
<platform-health-override command="command" | ||
platform-health-type="'Titus'" | ||
show-help-details="true" | ||
field-columns="12"> | ||
</platform-health-override> | ||
</div> | ||
</div> | ||
|
||
<div class="row"> | ||
<task-reason command="command"></task-reason> | ||
</div> | ||
|
||
<div class="row"> | ||
<div class="col-sm-11 col-sm-offset-1"> | ||
Consider rollback successful when | ||
<input type="number" | ||
min="0" | ||
max="100" | ||
ng-model="command.rollbackContext.targetHealthyRollbackPercentage" | ||
class="form-control input-sm inline-number" | ||
/> | ||
percent of instances are healthy. | ||
</div> | ||
</div> | ||
|
||
<div class="row"> | ||
<div class="col-sm-4 sm-label-right"> | ||
Rollback Operations | ||
</div> | ||
</div> | ||
<div class="row" ng-if="command.rollbackType === 'EXPLICIT'"> | ||
<div class="col-sm-11 col-sm-offset-1"> | ||
<ol> | ||
<li>Enable <em>{{ command.rollbackContext.restoreServerGroupName || 'previous server group' }}</em></li> | ||
<li>Resize <em>{{ command.rollbackContext.restoreServerGroupName || 'previous server group' }}</em> to [ | ||
<strong>min</strong>: {{serverGroup.capacity.desired}}, | ||
<strong>max</strong>: {{ serverGroup.capacity.max }}, | ||
<strong>desired</strong>: {{ serverGroup.capacity.desired }} | ||
]<br/>(minimum capacity pinned at {{serverGroup.capacity.desired}} to prevent autoscaling down during rollback) | ||
<li ng-if="command.rollbackContext.targetHealthyRollbackPercentage < 100"> | ||
Wait for at least {{minHealthy(command.rollbackContext.targetHealthyRollbackPercentage)}} | ||
instances to report as healthy | ||
</li> | ||
</li> | ||
<li>Disable {{ serverGroup.name }}</li> | ||
<li>Restore minimum capacity of <em>{{ command.rollbackContext.restoreServerGroupName || 'previous server group' }}</em> [ | ||
<strong>min</strong>: {{ serverGroup.capacity.min }} | ||
]</li> | ||
</ol> | ||
<p> | ||
This rollback will affect server groups in {{ serverGroup.account }} ({{ serverGroup.region }}). | ||
</p> | ||
</div> | ||
</div> | ||
<div class="row" ng-if="command.rollbackType === 'PREVIOUS_IMAGE'"> | ||
<div class="col-sm-11 col-sm-offset-1"> | ||
<ol> | ||
<li>Deploy <em>{{ previousServerGroup.imageId }}</em> [ | ||
<strong>min</strong>: {{serverGroup.capacity.desired}}, | ||
<strong>max</strong>: {{ serverGroup.capacity.max }}, | ||
<strong>desired</strong>: {{ serverGroup.capacity.desired }} | ||
]<br/>(minimum capacity pinned at {{serverGroup.capacity.desired}} to prevent autoscaling down during deploy) | ||
<li ng-if="command.rollbackContext.targetHealthyRollbackPercentage < 100"> | ||
Wait for at least {{minHealthy(command.rollbackContext.targetHealthyRollbackPercentage)}} | ||
instances to report as healthy | ||
</li> | ||
</li> | ||
<li>Disable {{ serverGroup.name }}</li> | ||
<li>Restore minimum capacity of <em>new server group</em> [ | ||
<strong>min</strong>: {{ serverGroup.capacity.min }} | ||
]</li> | ||
</ol> | ||
<p> | ||
This rollback will affect server groups in {{ serverGroup.account }} ({{ serverGroup.region }}). | ||
</p> | ||
</div> | ||
</div> | ||
|
||
</div> | ||
<aws-footer action="ctrl.rollback()" | ||
cancel="ctrl.cancel()" | ||
is-valid="ctrl.isValid()" | ||
account="serverGroup.account" | ||
verification="verification"></aws-footer> | ||
</form> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters