Skip to content

Commit

Permalink
feat(rrb): Allow for specifying pipelines to run before disable
Browse files Browse the repository at this point in the history
  • Loading branch information
ajordens committed Oct 23, 2017
1 parent 7280c24 commit 2a72cdd
Show file tree
Hide file tree
Showing 5 changed files with 219 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import './strategies/redblack/redblack.strategy';
import './strategies/rollingredblack/rollingredblack.strategy';

import { CUSTOM_STRATEGY_SELECTOR_COMPONENT } from './strategies/custom/customStrategySelector.component';
import { PIPELINE_SELECTOR_COMPONENT } from './strategies/rollingredblack/pipelineSelector.component';
import { DEPLOYMENT_STRATEGY_SELECTOR_COMPONENT } from './deploymentStrategySelector.component';

export const DEPLOYMENT_STRATEGY_MODULE = 'spinnaker.core.deploymentStrategy';
module(DEPLOYMENT_STRATEGY_MODULE, [
CUSTOM_STRATEGY_SELECTOR_COMPONENT,
PIPELINE_SELECTOR_COMPONENT,
DEPLOYMENT_STRATEGY_SELECTOR_COMPONENT,
]);
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
<div class="form-group">
<div class="col-md-6">
<label>
<div class="col-md-6" style="margin-top: 15px">
<h4>
Percentages
<help-field key="strategy.rollingRedBlack.targetPercentages"></help-field>
</label>
</h4>
<number-list model="$ctrl.command.targetPercentages" label="percentage"/>
</div>

<div class="col-md-12" style="margin-top: 15px">
<h4>Before Disable</h4>
</div>

<div class="col-md-12 form-inline">
<label>Wait Before Disable
<label>Wait
<help-field
content="Time to wait before disabling instances in old server group"></help-field>
</label>
Expand All @@ -19,4 +24,11 @@
placeholder="0">
seconds
</div>
<div class="col-md-12" style="margin-top: 5px">
<label>Run a Pipeline
<help-field
content="Pipeline to run before disabling instances in old server group"></help-field>
</label>
<pipeline-selector command="$ctrl.command.pipelineBeforeCleanup"></pipeline-selector>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<div class="form-group">
<div class="form-horizontal">
<div class="form-group">
<label class="col-md-2 col-md-offset-1 sm-label-right">Application</label>
<div class="col-md-6">
<ui-select ng-model="$ctrl.command.application"
class="form-control input-sm"
ng-change="$ctrl.initializePipelines()">
<ui-select-match allow-clear placeholder="None">{{$select.selected}}</ui-select-match>
<ui-select-choices
repeat="application in $ctrl.state.applications | filter: $select.search | limitTo: $ctrl.state.currentApplicationCount"
infinite-scroll="$ctrl.addMoreApplications()"
infinite-scroll-distance="2">
<div ng-bind-html="application | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
</div>
</div>

<div class="form-group" ng-if="$ctrl.command.application && $ctrl.state.pipelinesLoaded">
<label class="col-md-2 col-md-offset-1 sm-label-right">Pipeline</label>
<div class="col-md-6">
<div>
<ui-select class="form-control input-sm"
ng-model="$ctrl.command.pipelineId"
ng-change="$ctrl.updatePipelineConfig()">
<ui-select-match allow-clear placeholder="Select a pipeline...">{{$select.selected.name}}</ui-select-match>
<ui-select-choices
repeat="pipeline.id as pipeline in $ctrl.state.pipelines | filter: $select.search | orderBy: 'index'"><span
ng-bind-html="pipeline.name | highlight: $select.search"></span></ui-select-choices>
</ui-select>
</div>
</div>
</div>

<div class="well well-sm clearfix ng-scope col-md-12" ng-if="$ctrl.state.pipelineParameters.length">
<strong class="text-left">Parameters</strong>
<div class="form-group" ng-repeat="parameter in $ctrl.state.pipelineParameters | orderBy:'name' ">
<div class="col-md-3 sm-label-right">
<span ng-if="!parameter.description">{{parameter.name}}</span>
<help-field content="{{parameter.description}}" label="{{parameter.name}}" ng-if="parameter.description"></help-field>
</div>
<div class="col-md-6">
<input disabled ng-if="$ctrl.state.useDefaultParameters[parameter.name]" type="text" class="form-control input-sm"
value="{{parameter.default}}"/>
<input ng-if="!$ctrl.state.useDefaultParameters[parameter.name] && !parameter.hasOptions" type="text" class="form-control input-sm"
ng-model="$ctrl.state.userSuppliedParameters[parameter.name]" ng-change="$ctrl.updateParam(parameter.name)"/>
<ui-select style="width:100%"
ng-if="!$ctrl.state.useDefaultParameters[parameter.name] && parameter.hasOptions"
ng-model="$ctrl.state.userSuppliedParameters[parameter.name]" ng-change="$ctrl.updateParam(parameter.name)"
class="form-control input-sm">
<ui-select-match>
<strong>{{$select.selected.value}}</strong>
</ui-select-match>
<ui-select-choices repeat="option.value as option in parameter.options">
<div><strong>{{option.value}}</strong></div>
</ui-select-choices>
</ui-select>
</div>
<div class="checkbox col-md-3" ng-if="parameter.default !== null && parameter.default !== undefined">
<label>
<input type="checkbox" ng-model="$ctrl.state.useDefaultParameters[parameter.name]"
ng-change="$ctrl.updateParam(parameter.name)">Use default
</label>
</div>
</div>

</div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import { IController, IComponentOptions, module } from 'angular';

import { APPLICATION_READ_SERVICE, ApplicationReader } from 'core/application/service/application.read.service';
import { PIPELINE_CONFIG_SERVICE, PipelineConfigService } from 'core/pipeline/config/services/pipelineConfig.service';
import { IParameter, IPipeline } from 'core/domain';

interface IPipelineSelectorState {
pipelinesLoaded: boolean;
applications: string[];
pipelines: IPipeline[];
pipelineParameters?: IParameter[];
useDefaultParameters: { [key: string]: boolean };
userSuppliedParameters: { [key: string]: any };
currentApplicationCount: number;
}

interface IPipelineSelectorCommand {
application?: string;
pipelineId?: string;
pipelineParameters?: { [key: string]: any };
}

class PipelineSelectorController implements IController {

public command: IPipelineSelectorCommand;
public state: IPipelineSelectorState = {
pipelinesLoaded: false,
applications: [],
pipelines: [],
pipelineParameters: [],
useDefaultParameters: {},
userSuppliedParameters: {},
currentApplicationCount: 20,
};

constructor(private applicationReader: ApplicationReader, private pipelineConfigService: PipelineConfigService) {
'ngInject';
}

public $onInit() {
this.applicationReader.listApplications().then((applications) => {
this.state.applications = applications.map(a => a.name).sort();
this.initializePipelines();
});
}

public addMoreApplications(): void {
this.state.currentApplicationCount += 20;
}

public initializePipelines(): void {
if (this.command.application) {
this.pipelineConfigService.getPipelinesForApplication(this.command.application).then((pipelines) => {
this.state.pipelines = pipelines;
console.log(pipelines);
if (pipelines.every(p => p.id !== this.command.pipelineId)) {
this.command.pipelineId = null;
}
this.state.pipelinesLoaded = true;
this.updatePipelineConfig();
});
}
}

public updatePipelineConfig(): void {
if (this.command && this.command.application && this.command.pipelineId) {
const config = this.state.pipelines.find(p => p.id === this.command.pipelineId);
if (config && config.parameterConfig) {
if (!this.command.pipelineParameters) {
this.command.pipelineParameters = {};
}
this.state.pipelineParameters = config.parameterConfig;
this.state.userSuppliedParameters = this.command.pipelineParameters;
this.state.useDefaultParameters = {};
this.configureParamDefaults();
} else {
this.clearParams();
}
} else {
this.clearParams();
}
}

public updateParam(parameter: string): void {
if (this.state.useDefaultParameters[parameter] === true) {
delete this.state.userSuppliedParameters[parameter];
delete this.command.pipelineParameters[parameter];
} else if (this.state.userSuppliedParameters[parameter]) {
this.command.pipelineParameters[parameter] = this.state.userSuppliedParameters[parameter];
}
}

private configureParamDefaults(): void {
this.state.pipelineParameters.forEach((param: any) => {
const defaultValue = param.default;
if (defaultValue !== null && defaultValue !== undefined) {
const configuredParamValue = this.command.pipelineParameters[param.name];
if (configuredParamValue === undefined || configuredParamValue === defaultValue) {
this.state.useDefaultParameters[param.name] = true;
this.command.pipelineParameters[param.name] = defaultValue;
}
}
});
}

private clearParams(): void {
this.state.pipelineParameters = [];
this.state.useDefaultParameters = {};
this.state.userSuppliedParameters = {};
}
}

const pipelineSelectorComponent: IComponentOptions = {
bindings: {
command: '=',
},
templateUrl: require('./pipelineSelector.component.html'),
controller: PipelineSelectorController,
};

export const PIPELINE_SELECTOR_COMPONENT = 'spinnaker.core.deploymentStrategy.rollingredblack.pipelineSelector';
module(PIPELINE_SELECTOR_COMPONENT, [
APPLICATION_READ_SERVICE,
PIPELINE_CONFIG_SERVICE,
]).component('pipelineSelector', pipelineSelectorComponent);
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,11 @@ DeploymentStrategyRegistry.registerStrategy({
if (!command.targetPercentages) {
command.targetPercentages = [50, 100];
}

if (!command.pipelineBeforeCleanup) {
command.beforeCleanupPipeline = {
application: command.application
}
}
}
});

0 comments on commit 2a72cdd

Please sign in to comment.