@spinnaker/titus 0.5.4 → 0.5.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (19) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/dist/index.js +1 -1
  3. package/dist/index.js.map +1 -1
  4. package/dist/serverGroup/details/scalingPolicy/targetTracking/UpsertTargetTrackingModal.d.ts +9 -0
  5. package/dist/serverGroup/details/scalingPolicy/upsert/TitusScalingPolicyCommandBuilderService.d.ts +3 -2
  6. package/dist/serverGroup/details/scalingPolicy/upsert/UpsertScalingPolicyModal.d.ts +9 -0
  7. package/package.json +6 -6
  8. package/src/serverGroup/details/scalingPolicy/CreateScalingPolicyButton.tsx +17 -43
  9. package/src/serverGroup/details/scalingPolicy/alarmBasedSummary.component.js +10 -17
  10. package/src/serverGroup/details/scalingPolicy/targetTracking/UpsertTargetTrackingModal.tsx +81 -0
  11. package/src/serverGroup/details/scalingPolicy/targetTracking/targetTrackingSummary.component.ts +10 -18
  12. package/src/serverGroup/details/scalingPolicy/upsert/TitusScalingPolicyCommandBuilderService.ts +5 -9
  13. package/src/serverGroup/details/scalingPolicy/upsert/UpsertScalingPolicyModal.tsx +158 -0
  14. package/dist/serverGroup/details/scalingPolicy/targetTracking/upsertTargetTracking.controller.d.ts +0 -40
  15. package/dist/serverGroup/details/scalingPolicy/upsert/upsertScalingPolicy.controller.d.ts +0 -2
  16. package/src/serverGroup/details/scalingPolicy/targetTracking/upsertTargetTracking.controller.ts +0 -98
  17. package/src/serverGroup/details/scalingPolicy/targetTracking/upsertTargetTracking.modal.html +0 -154
  18. package/src/serverGroup/details/scalingPolicy/upsert/upsertScalingPolicy.controller.js +0 -188
  19. package/src/serverGroup/details/scalingPolicy/upsert/upsertScalingPolicy.modal.html +0 -88
@@ -1,98 +0,0 @@
1
- import { IComponentController } from 'angular';
2
- import { IModalServiceInstance } from 'angular-ui-bootstrap';
3
- import { cloneDeep } from 'lodash';
4
- import { Subject } from 'rxjs';
5
-
6
- import {
7
- ITargetTrackingConfiguration,
8
- ITargetTrackingPolicy,
9
- IUpsertScalingPolicyCommand,
10
- ScalingPolicyWriter,
11
- } from '@spinnaker/amazon';
12
- import { Application, IServerGroup, TaskMonitor } from '@spinnaker/core';
13
-
14
- import { IAlarmRenderingServerGroup } from './targetTrackingSummary.component';
15
-
16
- export interface ITargetTrackingState {
17
- unit: string;
18
- scaleInChanged: boolean;
19
- }
20
-
21
- export interface ITargetTrackingPolicyCommand extends IUpsertScalingPolicyCommand {
22
- jobId: string;
23
- targetTrackingConfiguration: ITargetTrackingConfiguration;
24
- }
25
-
26
- export interface ITitusServerGroup extends IServerGroup {
27
- id: string;
28
- }
29
-
30
- export interface ITitusTargetTrackingPolicy extends ITargetTrackingPolicy {
31
- id?: string;
32
- }
33
-
34
- export class UpsertTargetTrackingController implements IComponentController {
35
- public statistics = ['Average', 'Maximum', 'Minimum', 'SampleCount', 'Sum'];
36
- public alarmUpdated = new Subject();
37
-
38
- public taskMonitor: TaskMonitor;
39
- public state: ITargetTrackingState;
40
- public command: ITargetTrackingPolicyCommand;
41
-
42
- public static $inject = ['$uibModalInstance', 'policy', 'serverGroup', 'alarmServerGroup', 'application'];
43
- constructor(
44
- private $uibModalInstance: IModalServiceInstance,
45
- public policy: ITitusTargetTrackingPolicy,
46
- public serverGroup: ITitusServerGroup,
47
- public alarmServerGroup: IAlarmRenderingServerGroup,
48
- public application: Application,
49
- ) {}
50
-
51
- public $onInit() {
52
- this.command = this.buildCommand();
53
- this.state = {
54
- unit: null,
55
- scaleInChanged: false,
56
- };
57
- }
58
-
59
- public scaleInChanged(): void {
60
- this.state.scaleInChanged = true;
61
- }
62
-
63
- public updateUnit = (unit: string) => {
64
- this.state.unit = unit;
65
- };
66
-
67
- public cancel(): void {
68
- this.$uibModalInstance.dismiss();
69
- }
70
-
71
- public save(): void {
72
- const action = this.policy.id ? 'Update' : 'Create';
73
- const command = cloneDeep(this.command);
74
- this.taskMonitor = new TaskMonitor({
75
- application: this.application,
76
- title: `${action} scaling policy for ${this.serverGroup.name}`,
77
- modalInstance: this.$uibModalInstance,
78
- submitMethod: () => ScalingPolicyWriter.upsertScalingPolicy(this.application, command),
79
- });
80
-
81
- this.taskMonitor.submit();
82
- }
83
-
84
- private buildCommand(): ITargetTrackingPolicyCommand {
85
- return {
86
- scalingPolicyID: this.policy.id,
87
- type: 'upsertScalingPolicy',
88
- cloudProvider: 'titus',
89
- jobId: this.serverGroup.id,
90
- credentials: this.serverGroup.account,
91
- region: this.serverGroup.region,
92
- serverGroupName: this.serverGroup.name,
93
- adjustmentType: null,
94
- name: this.policy.id,
95
- targetTrackingConfiguration: { ...this.policy.targetTrackingConfiguration },
96
- };
97
- }
98
- }
@@ -1,154 +0,0 @@
1
- <div modal-page class="scaling-policy-modal form-inline">
2
- <task-monitor monitor="$ctrl.taskMonitor"></task-monitor>
3
- <modal-close dismiss="$dismiss()"></modal-close>
4
- <div class="modal-header">
5
- <h4 class="modal-title">{{$ctrl.policy.id ? "Update" : "Create"}} scaling policy</h4>
6
- </div>
7
- <div class="modal-body">
8
- <form name="form" novalidate>
9
- <h4 class="section-heading">Target Metric</h4>
10
- <div class="section-body">
11
- <p>
12
- With target tracking policies, Amazon will automatically adjust the size of your job to keep the selected
13
- metric as close as possible to the selected value.
14
- </p>
15
- <p>
16
- <b>Note:</b> metrics must be sent to Amazon CloudWatch before they can be used in auto scaling. If you do not
17
- see a metric below, click "Configure available metrics" in the server group details to set up forwarding from
18
- Atlas to CloudWatch.
19
- </p>
20
- <div class="row" style="margin-bottom: 10px">
21
- <div class="col-md-2 sm-label-right">Metric</div>
22
- <div class="col-md-10 content-fields">
23
- <aws-metric-selector
24
- alarm-updated="$ctrl.alarmUpdated"
25
- alarm="$ctrl.command.targetTrackingConfiguration.customizedMetricSpecification"
26
- server-group="$ctrl.alarmServerGroup"
27
- ></aws-metric-selector>
28
- </div>
29
- </div>
30
-
31
- <div class="row" style="margin-bottom: 10px">
32
- <div class="col-md-2 sm-label-right">Target</div>
33
- <div class="col-md-10 content-fields">
34
- <select
35
- class="form-control input-sm"
36
- required
37
- ng-model="$ctrl.command.targetTrackingConfiguration.customizedMetricSpecification.statistic"
38
- ng-change="$ctrl.alarmUpdated.next()"
39
- ng-options="stat for stat in $ctrl.statistics"
40
- ></select>
41
- <span class="input-label" style="vertical-align: top; margin-top: 7px"> of </span>
42
- <div style="display: inline-block">
43
- <input
44
- type="number"
45
- class="form-control input-sm"
46
- style="width: 100px"
47
- ng-change="$ctrl.alarmUpdated.next()"
48
- ng-model="$ctrl.command.targetTrackingConfiguration.targetValue"
49
- />
50
- <span class="input-label" ng-bind="$ctrl.state.unit" ng-if="$ctrl.state.unit !== 'None'"></span>
51
- </div>
52
- </div>
53
- </div>
54
-
55
- <div class="row">
56
- <div class="col-md-10 col-md-offset-1">
57
- <div>
58
- <target-tracking-chart
59
- config="$ctrl.command.targetTrackingConfiguration"
60
- alarm-updated="$ctrl.alarmUpdated"
61
- server-group="$ctrl.alarmServerGroup"
62
- unit="$ctrl.state.unit"
63
- update-unit="$ctrl.updateUnit"
64
- ></target-tracking-chart>
65
- </div>
66
- </div>
67
- </div>
68
- </div>
69
- <h4 class="section-heading">Additional Settings</h4>
70
- <div class="section-body section-additional-settings">
71
- <div class="row">
72
- <div class="col-md-3 sm-label-right">Scale In</div>
73
- <div class="col-md-9">
74
- <div class="checkbox" style="margin-top: 5px">
75
- <label>
76
- <input
77
- type="checkbox"
78
- ng-model="$ctrl.command.targetTrackingConfiguration.disableScaleIn"
79
- ng-change="$ctrl.scaleInChanged()"
80
- />
81
- Disable Scale-downs
82
- </label>
83
- <div class="small" style="margin-top: 5px">
84
- <p>
85
- This option disables scale-downs for the target tracking policy, while keeping the scale-ups. This
86
- means that Server Group will not scale down unless you explicitly set up a separate step policy to
87
- scale it down.
88
- </p>
89
- <p>This is useful when you have special requirements, such as gradual or delayed scale-down.</p>
90
- </div>
91
- </div>
92
- </div>
93
- </div>
94
-
95
- <div class="row" ng-if="$ctrl.state.scaleInChanged">
96
- <div class="col-md-10 col-md-offset-1 well">
97
- <div ng-if="$ctrl.command.targetTrackingConfiguration.disableScaleIn">
98
- This policy will not scale down. Make sure you have another policy (either TT or Step) that will scale in
99
- this ASG.
100
- </div>
101
- <div ng-if="!$ctrl.command.targetTrackingConfiguration.disableScaleIn">
102
- This policy will scale both in and out. Make sure you don't have other scaling policies, as they will
103
- likely interfere with each other.
104
- </div>
105
- </div>
106
- </div>
107
-
108
- <div class="row" ng-if="!$ctrl.command.targetTrackingConfiguration.disableScaleIn">
109
- <div class="col-md-3 sm-label-right">
110
- Scale In Cooldown
111
- <help-field key="titus.autoscaling.scaleIn.cooldown"></help-field>
112
- </div>
113
- <div class="col-md-9 content-fields">
114
- <input
115
- type="number"
116
- style="width: 60px"
117
- class="form-control input-sm"
118
- required
119
- ng-model="$ctrl.command.targetTrackingConfiguration.scaleInCooldown"
120
- />
121
- <span class="input-label"> seconds </span>
122
- </div>
123
- </div>
124
-
125
- <div class="row">
126
- <div class="col-md-3 sm-label-right">
127
- Scale Out Cooldown
128
- <help-field key="titus.autoscaling.scaleOut.cooldown"></help-field>
129
- </div>
130
- <div class="col-md-9 content-fields">
131
- <input
132
- type="number"
133
- style="width: 60px"
134
- class="form-control input-sm"
135
- required
136
- ng-model="$ctrl.command.targetTrackingConfiguration.scaleOutCooldown"
137
- />
138
- <span class="input-label"> seconds </span>
139
- </div>
140
- </div>
141
- </div>
142
- </form>
143
- </div>
144
-
145
- <div class="modal-footer">
146
- <button class="btn btn-default" ng-click="$ctrl.cancel()">Cancel</button>
147
- <submit-button
148
- is-disabled="!form.$valid || $ctrl.taskMonitor.submitting"
149
- submitting="$ctrl.taskMonitor.submitting"
150
- on-click="$ctrl.save()"
151
- is-new="!$ctrl.policy.id"
152
- ></submit-button>
153
- </div>
154
- </div>
@@ -1,188 +0,0 @@
1
- 'use strict';
2
-
3
- import { module } from 'angular';
4
- import { cloneDeep } from 'lodash';
5
-
6
- import { ScalingPolicyWriter } from '@spinnaker/amazon';
7
- import { TaskMonitor } from '@spinnaker/core';
8
-
9
- export const TITUS_SERVERGROUP_DETAILS_SCALINGPOLICY_UPSERT_UPSERTSCALINGPOLICY_CONTROLLER =
10
- 'spinnaker.titus.serverGroup.details.scalingPolicy.upsertScalingPolicy.controller';
11
- export const name = TITUS_SERVERGROUP_DETAILS_SCALINGPOLICY_UPSERT_UPSERTSCALINGPOLICY_CONTROLLER; // for backwards compatibility
12
- module(TITUS_SERVERGROUP_DETAILS_SCALINGPOLICY_UPSERT_UPSERTSCALINGPOLICY_CONTROLLER, []).controller(
13
- 'titusUpsertScalingPolicyCtrl',
14
- [
15
- '$uibModalInstance',
16
- 'alarmServerGroup',
17
- 'serverGroup',
18
- 'application',
19
- 'policy',
20
- function ($uibModalInstance, alarmServerGroup, serverGroup, application, policy) {
21
- this.serverGroup = serverGroup;
22
- // alarmServerGroup is used to trick the chart rendering into using AWS metrics
23
- this.alarmServerGroup = alarmServerGroup;
24
-
25
- this.viewState = {
26
- isNew: !policy.id,
27
- multipleAlarms: policy.alarms.length > 1,
28
- metricsLoaded: false,
29
- namespacesLoaded: false,
30
- };
31
-
32
- function createCommand() {
33
- return {
34
- scalingPolicyID: policy.id,
35
- jobId: serverGroup.id,
36
- serverGroupName: serverGroup.name,
37
- credentials: serverGroup.account,
38
- region: serverGroup.region,
39
- cloudProvider: 'titus',
40
- adjustmentType: policy.adjustmentType,
41
- minAdjustmentMagnitude: policy.minAdjustmentMagnitude || 1,
42
- };
43
- }
44
-
45
- function initializeAlarm(command, policy) {
46
- const alarm = policy.alarms[0];
47
- command.alarm = {
48
- region: serverGroup.region,
49
- comparisonOperator: alarm.comparisonOperator,
50
- dimensions: alarm.dimensions,
51
- disableEditingDimensions: alarm.disableEditingDimensions,
52
- evaluationPeriods: alarm.evaluationPeriods,
53
- period: alarm.period,
54
- threshold: alarm.threshold,
55
- namespace: alarm.namespace,
56
- metricName: alarm.metricName,
57
- statistic: alarm.statistic,
58
- unit: alarm.unit,
59
- };
60
- }
61
-
62
- this.initialize = () => {
63
- const command = createCommand();
64
-
65
- initializeAlarm(command, policy);
66
-
67
- if (command.adjustmentType === 'ExactCapacity') {
68
- this.viewState.operator = 'Set to';
69
- this.viewState.adjustmentType = 'instances';
70
- } else {
71
- let adjustmentBasis = policy.scalingAdjustment;
72
- if (policy.stepAdjustments && policy.stepAdjustments.length) {
73
- adjustmentBasis = policy.stepAdjustments[0].scalingAdjustment;
74
- }
75
- this.viewState.operator = adjustmentBasis > 0 ? 'Add' : 'Remove';
76
- this.viewState.adjustmentType =
77
- policy.adjustmentType === 'ChangeInCapacity' ? 'instances' : 'percent of group';
78
- }
79
-
80
- initializeStepPolicy(command, policy);
81
-
82
- this.command = command;
83
- };
84
-
85
- function initializeStepPolicy(command, policy) {
86
- const threshold = command.alarm.threshold;
87
- command.step = {
88
- cooldown: policy.cooldown || 300,
89
- metricAggregationType: 'Average',
90
- };
91
- command.step.stepAdjustments = policy.stepAdjustments.map((adjustment) => {
92
- const step = {
93
- scalingAdjustment: Math.abs(adjustment.scalingAdjustment),
94
- };
95
- if (adjustment.metricIntervalUpperBound !== undefined) {
96
- step.metricIntervalUpperBound = adjustment.metricIntervalUpperBound + threshold;
97
- }
98
- if (adjustment.metricIntervalLowerBound !== undefined) {
99
- step.metricIntervalLowerBound = adjustment.metricIntervalLowerBound + threshold;
100
- }
101
- return step;
102
- });
103
- }
104
-
105
- this.stepsChanged = (newSteps) => {
106
- this.command.step.stepAdjustments = newSteps;
107
- this.boundsChanged();
108
- };
109
-
110
- this.alarmChanged = (newAlarm) => {
111
- this.command.alarm = newAlarm;
112
- };
113
-
114
- this.adjustmentTypeChanged = (action, type) => {
115
- this.viewState.operator = action;
116
- this.viewState.adjustmentType = type;
117
- const newType =
118
- type !== 'instances' ? 'PercentChangeInCapacity' : action === 'Set to' ? 'ExactCapacity' : 'ChangeInCapacity';
119
- this.command.adjustmentType = newType;
120
- };
121
-
122
- this.boundsChanged = () => {
123
- const source =
124
- this.viewState.comparatorBound === 'min' ? 'metricIntervalLowerBound' : 'metricIntervalUpperBound';
125
- const target = source === 'metricIntervalLowerBound' ? 'metricIntervalUpperBound' : 'metricIntervalLowerBound';
126
-
127
- if (this.command.step) {
128
- const steps = this.command.step.stepAdjustments;
129
- steps.forEach((step, index) => {
130
- if (steps.length > index + 1) {
131
- steps[index + 1][target] = step[source];
132
- }
133
- });
134
- // remove the source boundary from the last step
135
- delete steps[steps.length - 1][source];
136
- }
137
- };
138
-
139
- this.action = this.viewState.isNew ? 'Create' : 'Edit';
140
-
141
- const prepareCommandForSubmit = () => {
142
- const command = cloneDeep(this.command);
143
-
144
- if (command.adjustmentType !== 'PercentChangeInCapacity') {
145
- delete command.minAdjustmentMagnitude;
146
- }
147
-
148
- if (command.step) {
149
- // adjust metricIntervalLowerBound/UpperBound for each step based on alarm threshold
150
- command.step.stepAdjustments.forEach((step) => {
151
- if (this.viewState.operator === 'Remove') {
152
- step.scalingAdjustment = 0 - step.scalingAdjustment;
153
- delete command.step.estimatedInstanceWarmup;
154
- }
155
- if (step.metricIntervalLowerBound !== undefined) {
156
- step.metricIntervalLowerBound -= command.alarm.threshold;
157
- }
158
- if (step.metricIntervalUpperBound !== undefined) {
159
- step.metricIntervalUpperBound -= command.alarm.threshold;
160
- }
161
- });
162
- } else {
163
- if (this.viewState.operator === 'Remove') {
164
- command.simple.scalingAdjustment = 0 - command.simple.scalingAdjustment;
165
- }
166
- }
167
- return command;
168
- };
169
-
170
- this.taskMonitor = new TaskMonitor({
171
- application: application,
172
- title: this.action + ' scaling policy for ' + serverGroup.name,
173
- modalInstance: $uibModalInstance,
174
- });
175
-
176
- this.save = () => {
177
- const command = prepareCommandForSubmit();
178
- const submitMethod = () => ScalingPolicyWriter.upsertScalingPolicy(application, command);
179
-
180
- this.taskMonitor.submit(submitMethod);
181
- };
182
-
183
- this.cancel = $uibModalInstance.dismiss;
184
-
185
- this.initialize();
186
- },
187
- ],
188
- );
@@ -1,88 +0,0 @@
1
- <div modal-page class="scaling-policy-modal form-inline">
2
- <task-monitor monitor="ctrl.taskMonitor"></task-monitor>
3
- <modal-close dismiss="$dismiss()"></modal-close>
4
- <div class="modal-header">
5
- <h4 class="modal-title">{{ctrl.action}} scaling policy</h4>
6
- </div>
7
- <div class="modal-body">
8
- <form name="form" novalidate>
9
- <h4 class="section-heading">Conditions</h4>
10
- <div class="section-body">
11
- <p>
12
- <b>Note:</b> metrics must be sent to Amazon CloudWatch before they can be used in auto scaling. If you do not
13
- see a metric below, click "Configure available metrics" in the server group details to set up forwarding from
14
- Atlas to CloudWatch.
15
- </p>
16
- <alarm-configurer
17
- alarm="ctrl.command.alarm"
18
- multiple-alarms="ctrl.viewState.multipleAlarms"
19
- server-group="ctrl.alarmServerGroup"
20
- step-adjustments="ctrl.command.step.stepAdjustments"
21
- steps-changed="ctrl.stepsChanged"
22
- update-alarm="ctrl.alarmChanged"
23
- ></alarm-configurer>
24
- </div>
25
-
26
- <h4 class="section-heading">Actions</h4>
27
- <div class="section-body" ng-if="!ctrl.command.alarm.metricName && !ctrl.command.alarm.name">
28
- <h4 class="text-center">Select a metric</h4>
29
- </div>
30
- <div class="section-body" ng-if="ctrl.command.alarm.metricName">
31
- <step-policy-action
32
- adjustment-type="ctrl.viewState.adjustmentType"
33
- adjustment-type-changed="ctrl.adjustmentTypeChanged"
34
- alarm="ctrl.command.alarm"
35
- is-min="ctrl.viewState.comparatorBound === 'min'"
36
- operator="ctrl.viewState.operator"
37
- step="ctrl.command.step"
38
- step-adjustments="ctrl.command.step.stepAdjustments"
39
- steps-changed="ctrl.stepsChanged"
40
- ></step-policy-action>
41
- </div>
42
-
43
- <h4 class="section-heading">Additional Settings</h4>
44
- <div class="section-body section-additional-settings">
45
- <div class="row" ng-if="ctrl.viewState.adjustmentType !== 'instances'">
46
- <div class="col-md-2 sm-label-right">Adjustment Step</div>
47
- <div class="col-md-10 content-fields">
48
- <span class="form-control-static select-placeholder">
49
- <span ng-bind="ctrl.viewState.operator"></span>
50
- instances in increments of at least
51
- </span>
52
- <input
53
- type="number"
54
- style="width: 60px"
55
- class="form-control input-sm"
56
- required
57
- ng-model="ctrl.command.minAdjustmentMagnitude"
58
- />
59
- <span class="input-label"> instance(s) </span>
60
- </div>
61
- </div>
62
- <div class="row" ng-if="ctrl.viewState.operator !== 'Remove'">
63
- <div class="col-md-2 sm-label-right">Cooldown <help-field key="titus.autoscaling.cooldown"></help-field></div>
64
- <div class="col-md-10 content-fields">
65
- <input
66
- type="number"
67
- style="width: 60px"
68
- class="form-control input-sm"
69
- required
70
- ng-model="ctrl.command.step.cooldown"
71
- />
72
- <span class="input-label"> seconds </span>
73
- </div>
74
- </div>
75
- </div>
76
- </form>
77
- </div>
78
-
79
- <div class="modal-footer">
80
- <button class="btn btn-default" ng-click="ctrl.cancel()">Cancel</button>
81
- <submit-button
82
- is-disabled="!form.$valid"
83
- submitting="taskMonitor.submitting"
84
- on-click="ctrl.save()"
85
- is-new="ctrl.viewState.isNew"
86
- ></submit-button>
87
- </div>
88
- </div>