Skip to content

Commit

Permalink
feat(dcd): pipeline template boilerplate (#3569)
Browse files Browse the repository at this point in the history
  • Loading branch information
danielpeach committed Apr 25, 2017
1 parent bf626e9 commit 6ad1517
Show file tree
Hide file tree
Showing 8 changed files with 304 additions and 1 deletion.
4 changes: 3 additions & 1 deletion app/scripts/modules/core/api/api.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ export class Api {
}

const API_SERVICE_NAME = 'API';
export let api: Api;
export const API_SERVICE = 'spinnaker.core.api.provider';
module(API_SERVICE, [AUTHENTICATION_INITIALIZER_SERVICE])
.service(API_SERVICE_NAME, Api);
.service(API_SERVICE_NAME, Api)
.run(($injector: any) => api = <Api>$injector.get('API'));
1 change: 1 addition & 0 deletions app/scripts/modules/core/config/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export interface IFeatures {
jobs?: boolean;
snapshots?: boolean;
dockerBake?: boolean;
pipelineTemplates?: boolean;
[key: string]: any;
}

Expand Down
2 changes: 2 additions & 0 deletions app/scripts/modules/core/core.module.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {UNMATCHED_STAGE_TYPE_STAGE} from './pipeline/config/stages/unmatchedStag
import {SETTINGS} from 'core/config/settings';
import {INSIGHT_NGMODULE} from './insight/insight.module';
import {REPLACE_FILTER} from './filter/replace.filter';
import {CONFIGURE_PIPELINE_TEMPLATE_MODAL} from './pipeline/config/templates/configurePipelineTemplateModal.component';

require('../../../fonts/spinnaker/icons.css');

Expand Down Expand Up @@ -68,6 +69,7 @@ module.exports = angular
require('./cache/caches.module.js'),
CANCEL_MODAL_SERVICE,
CLOUD_PROVIDER_LOGO,
CONFIGURE_PIPELINE_TEMPLATE_MODAL,
CORE_DIFF_MODULE,
require('./cloudProvider/cloudProviderLabel.directive.js'),
require('./cloudProvider/serviceDelegate.service.js'),
Expand Down
3 changes: 3 additions & 0 deletions app/scripts/modules/core/delivery/executions/executions.html
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,7 @@ <h4>There was an error loading executions. We'll try again shortly.</h4>
application="vm.application"
ng-if="!vm.viewState.loading && (vm.application.executions.data.length || vm.application.pipelineConfigs.data.length)"></execution-groups>
</div>
<render-if-feature feature="pipelineTemplates">
<configure-pipeline-template-modal show="true"></configure-pipeline-template-modal>
</render-if-feature>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import * as React from 'react';
import {Modal, Button} from 'react-bootstrap';
import {IPipelineTemplate} from './pipelineTemplate.service';

interface IState {}

interface IProps {
template: IPipelineTemplate
show: boolean;
showCallback: (show: boolean) => null;
}

export class ConfigurePipelineTemplateModal extends React.Component<IProps, IState> {

private close = (): void => {
this.props.showCallback(false);
};

public render() {
return (
<Modal show={this.props.show} onHide={this.close}>
<Modal.Body>
<pre>{JSON.stringify(this.props.template || {}, null, 2)}</pre>
</Modal.Body>
<Modal.Footer>
<Button onClick={this.close}>Cancel</Button>
</Modal.Footer>
</Modal>
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import {module} from 'angular';
import {react2angular} from 'react2angular';
import {ConfigurePipelineTemplateModal} from './ConfigurePipelineTemplateModal';

export const CONFIGURE_PIPELINE_TEMPLATE_MODAL = 'spinnaker.core.pipeline.configureTemplate.modal';
module(CONFIGURE_PIPELINE_TEMPLATE_MODAL, [])
.component('configurePipelineTemplateModal', react2angular(ConfigurePipelineTemplateModal, ['show', 'template']));
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import {module, IPromise} from 'angular';
import {$q} from 'ngimport'; // Remove once Gate endpoint has been created.
// import {api} from 'core/api/api.service'; // Uncomment once Gate endpoint has been created.

const resolvedTemplate = require('./template.json');

export interface IPipelineTemplate {
id: string;
metadata: IPipelineTemplateMetadata;
protect: boolean;
schema: string;
source: string;
stages: IPipelineTemplateStage[];
variables: IPipelineTemplateVariable[];
}

export interface IPipelineTemplateMetadata {
description: string;
name: string;
owner: string;
}

export interface IPipelineTemplateVariable {
defaultValue: any;
description: string;
example: string;
group: string;
name: string;
type: 'int' | 'float' | 'list' | 'object' | 'string';
}

export interface IPipelineTemplateStage {
dependsOn: string[];
id: string;
name: string;
type: string;
}

export class PipelineTemplateService {
public getPipelineTemplateFromSourceUrl(/* source: string */): IPromise<IPipelineTemplate> {
// Uncomment when the Gate endpoint has been created:
// return api.one('pipelineTemplates').withParams({source}).get();
return $q.resolve(resolvedTemplate); // Remove once Gate endpoint has been created.
}
}

export let pipelineTemplateService: PipelineTemplateService;
export const PIPELINE_TEMPLATE_SERVICE = 'spinnaker.core.pipelineTemplate.service';
module(PIPELINE_TEMPLATE_SERVICE, [])
.service('pipelineTemplateService', PipelineTemplateService)
.run(($injector: any) => pipelineTemplateService = <PipelineTemplateService>$injector.get('pipelineTemplateService'));
206 changes: 206 additions & 0 deletions app/scripts/modules/core/pipeline/config/templates/template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
{
"schema": "1",
"id": "mergedTemplate",
"source": "https://raw.githubusercontent.com/robzienert/pipeline-templates/master/netflix/spinnaker/deployToEnvRoot.yml",
"metadata": {
"name": "Deploy to Target Env from Image Tags",
"description": "Defines a deploy pipeline to a target account, sourcing the deployment\nartifact from an find image from tags stage.",
"owner": "example@example.com"
},
"protect": false,
"variables": [
{
"name": "targetCredentials",
"group": "Basic Settings",
"description": "The account credentials where the application will be deployed to",
"type": "string",
"defaultValue": "mgmt",
"example": null
},
{
"name": "clusters",
"group": "Basic Settings",
"description": "A list of cluster-specific configuration options",
"type": "object",
"defaultValue": null,
"example": "- name: orca-test\n region: us-west-2\n availabilityZones: [] # Omitted from example\n capacity: 1\n keyPair: example-keypair\n loadBalancers:\n - orca-test\n securityGroups: [] # Omitted from example\n strategy: highlander\n instanceType: m3.xlarge\n"
},
{
"name": "deployToFailover",
"group": "Not Basic Settings",
"description": "Whether or not to deploy into the failover region.",
"type": "string",
"defaultValue": false,
"example": null
},
{
"name": "findImageRegion",
"group": "Ungrouped",
"description": "The region to find the AMI in",
"type": "string",
"defaultValue": null,
"example": null
}
],
"configuration": {
"concurrentExecutions": {
"parallel": true,
"limitConcurrent": true
},
"triggers": null,
"parameters": null,
"notifications": null
},
"stages": [
{
"id": "manualJudgment",
"name": "Approve {{ targetCredentials }}",
"inject": null,
"dependsOn": [],
"type": "manualJudgment",
"config": {
"failPipeline": true,
"instructions": "Do you approve of this pipeline, which will push {{ application }} to {{ targetCredentials }}?",
"judgmentInputs": [],
"notifications": [
{
"address": "spinnaker",
"level": "stage",
"type": "slack",
"when": [
"manualJudgment"
]
}
],
"propagateAuthenticationContext": true,
"sendNotifications": true
},
"notifications": null,
"comments": null,
"when": null,
"inheritanceControl": null,
"requisiteStageRefIds": []
},
{
"id": "deploy",
"name": "Deploy",
"inject": null,
"dependsOn": [
"manualJudgment"
],
"type": "deploy",
"config": {
"clusters": "{% for c in clusters %}\n- {% module deployCluster \n account=targetCredentials,\n cluster=c.name,\n region=c.region,\n availabilityZones=c.availabilityZones,\n capacity=c.capacity,\n keyPair=c.keyPair,\n loadBalancers=c.loadBalancers,\n securityGroups=c.securityGroups,\n strategy=c.strategy,\n instanceType=c.instanceType %}\n{% endfor %}\n"
},
"notifications": null,
"comments": null,
"when": null,
"inheritanceControl": null,
"requisiteStageRefIds": []
},
{
"id": "findImages",
"name": "Find Image from Tags",
"inject": {
"first": true,
"last": false,
"before": null,
"after": null
},
"dependsOn": [],
"type": "findImageFromTags",
"config": {
"cloudProvider": "aws",
"cloudProviderType": "aws",
"packageName": "{{ application }}",
"regions": [
"{{ findImageRegion }}"
],
"tags": {
"stack": "test"
}
},
"notifications": null,
"comments": null,
"when": null,
"inheritanceControl": null,
"requisiteStageRefIds": []
}
],
"modules": [
{
"id": "deployCluster",
"usage": null,
"variables": [
{
"name": "account"
},
{
"name": "cluster"
},
{
"name": "region"
},
{
"name": "availabilityZones",
"type": "list"
},
{
"name": "capacity"
},
{
"name": "keyPair"
},
{
"name": "loadBalancers",
"type": "list"
},
{
"name": "securityGroups",
"type": "list"
},
{
"name": "strategy"
},
{
"name": "instanceType"
}
],
"definition": {
"account": "{{ account }}",
"application": "{{ application }}",
"availabilityZones": "{{ region }}:\n{% for az in availabilityZones %}\n- {{ az }}\n{% endfor %}\n",
"capacity": {
"desired": "{{ capacity }}",
"max": "{{ capacity }}",
"min": "{{ capacity }}"
},
"cloudProvider": "aws",
"cooldown": 300,
"ebsOptimized": false,
"freeFormDetails": "{{ cluster|frigga('detail') }}",
"healthCheckGracePeriod": 0,
"healthCheckType": "EC2",
"iamRole": "{{ application }}ExampleRole",
"instanceMonitoring": true,
"instanceType": "{{ instanceType }}",
"keyPair": "{{ keyPair }}",
"loadBalancers": "{% for lb in loadBalancers %}\n- {{ lb }}\n{% endfor %}\n",
"maxRemainingAsgs": "{% if application == 'orca' %}3{% else %}1{% endif %}",
"provider": "aws",
"securityGroups": "{% for sg in securityGroups %}\n- {{ sg }}\n{% endfor %}\n",
"stack": "{{ cluster|frigga('stack') }}",
"strategy": "{{ strategy }}",
"subnetType": "example",
"suspendedProcesses": [],
"tags": {},
"targetHealthyDeployPercentage": 100,
"terminationPolicies": [
"Default"
],
"useSourceCapacity": false
}
}
],
"schemaVersion": "1"
}

0 comments on commit 6ad1517

Please sign in to comment.