From 478e326aae8c7e731985883a6c212df961a6b90f Mon Sep 17 00:00:00 2001 From: Maggie Neterval Date: Fri, 12 Apr 2019 09:52:53 -0400 Subject: [PATCH] feat(kubernetes): add rollout strategies to deploy manifest stage (#6841) --- .../kubernetes/src/help/kubernetes.help.ts | 3 ++ .../ManifestDeploymentOptions.spec.tsx | 14 ++++++-- .../ManifestDeploymentOptions.tsx | 34 ++++++++++++++++++- .../deployManifest.validator.ts | 18 ++++++++++ .../deployManifest/deployManifestStage.ts | 3 +- .../v2/rolloutStrategy/highlander.strategy.ts | 7 ++++ .../src/v2/rolloutStrategy/index.ts | 5 +++ .../src/v2/rolloutStrategy/none.strategy.ts | 8 +++++ .../v2/rolloutStrategy/redblack.strategy.ts | 7 ++++ 9 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 app/scripts/modules/kubernetes/src/v2/pipelines/stages/deployManifest/deployManifest.validator.ts create mode 100644 app/scripts/modules/kubernetes/src/v2/rolloutStrategy/highlander.strategy.ts create mode 100644 app/scripts/modules/kubernetes/src/v2/rolloutStrategy/index.ts create mode 100644 app/scripts/modules/kubernetes/src/v2/rolloutStrategy/none.strategy.ts create mode 100644 app/scripts/modules/kubernetes/src/v2/rolloutStrategy/redblack.strategy.ts diff --git a/app/scripts/modules/kubernetes/src/help/kubernetes.help.ts b/app/scripts/modules/kubernetes/src/help/kubernetes.help.ts index 1fe2830eea4..a118a97a4aa 100644 --- a/app/scripts/modules/kubernetes/src/help/kubernetes.help.ts +++ b/app/scripts/modules/kubernetes/src/help/kubernetes.help.ts @@ -205,6 +205,9 @@ const helpContents: { [key: string]: string } = { 'kubernetes.manifest.rolloutStrategyOptions': `

Allow Spinnaker to associate your workload with one or more Services and manage traffic based on your selected rollout strategy options. Valid for ReplicaSets only.

`, + 'kubernetes.manifest.rolloutStrategy': ` +

The rollout strategy tells Spinnaker what to do with the previous version(s) of the ReplicaSet in the cluster.

+ `, 'kubernetes.manifest.expectedArtifact': 'The artifact that is to be applied to the Kubernetes account for this stage. The artifact should represent a valid Kubernetes manifest.', 'kubernetes.manifest.requiredArtifactsToBind': diff --git a/app/scripts/modules/kubernetes/src/v2/pipelines/stages/deployManifest/ManifestDeploymentOptions.spec.tsx b/app/scripts/modules/kubernetes/src/v2/pipelines/stages/deployManifest/ManifestDeploymentOptions.spec.tsx index ad128b5d83b..ed8c86139fe 100644 --- a/app/scripts/modules/kubernetes/src/v2/pipelines/stages/deployManifest/ManifestDeploymentOptions.spec.tsx +++ b/app/scripts/modules/kubernetes/src/v2/pipelines/stages/deployManifest/ManifestDeploymentOptions.spec.tsx @@ -29,10 +29,10 @@ describe('', () => { expect(wrapper.find(StageConfigField).length).toEqual(1); expect(wrapper.find('input[type="checkbox"]').length).toEqual(1); }); - it('renders config fields for `namespace`, `services`, and `enableTraffic` when config is enabled', () => { + it('renders config fields for `namespace`, `services`, `enableTraffic`, and `strategy` when config is enabled', () => { props.config.enabled = true; wrapper = shallow(); - expect(wrapper.find(StageConfigField).length).toEqual(4); + expect(wrapper.find(StageConfigField).length).toEqual(5); }); }); @@ -47,5 +47,15 @@ describe('', () => { enabled: true, }); }); + it('disables the traffic checkbox when a non-None rollout strategy is selected', () => { + props.config.options.strategy = 'redblack'; + wrapper = shallow(); + expect( + wrapper + .find('input[type="checkbox"]') + .at(1) + .props().disabled, + ).toEqual(true); + }); }); }); diff --git a/app/scripts/modules/kubernetes/src/v2/pipelines/stages/deployManifest/ManifestDeploymentOptions.tsx b/app/scripts/modules/kubernetes/src/v2/pipelines/stages/deployManifest/ManifestDeploymentOptions.tsx index 96bf03503fc..2b1728739da 100644 --- a/app/scripts/modules/kubernetes/src/v2/pipelines/stages/deployManifest/ManifestDeploymentOptions.tsx +++ b/app/scripts/modules/kubernetes/src/v2/pipelines/stages/deployManifest/ManifestDeploymentOptions.tsx @@ -1,12 +1,14 @@ import { module } from 'angular'; +import * as DOMPurify from 'dompurify'; import * as React from 'react'; import { react2angular } from 'react2angular'; import { cloneDeep, find, get, map, set, split } from 'lodash'; import Select, { Option } from 'react-select'; -import { IAccountDetails, StageConfigField } from '@spinnaker/core'; +import { IAccountDetails, IDeploymentStrategy, StageConfigField } from '@spinnaker/core'; import { ManifestKindSearchService } from 'kubernetes/v2/manifest/ManifestKindSearch'; +import { rolloutStrategies } from 'kubernetes/v2/rolloutStrategy'; export interface ITrafficManagementConfig { enabled: boolean; @@ -73,6 +75,19 @@ export class ManifestDeploymentOptions extends React.Component< return map(namespaces, n => ({ label: n, value: n })); }; + private strategyOptionRenderer = (option: IDeploymentStrategy) => { + return ( +
+ + + +
+ +
+
+ ); + }; + public componentDidMount() { this.fetchServices(); } @@ -86,6 +101,10 @@ export class ManifestDeploymentOptions extends React.Component< this.onConfigChange('options.services', null); this.fetchServices(); } + + if (!this.props.config.options.enableTraffic && !!this.props.config.options.strategy) { + this.onConfigChange('options.enableTraffic', true); + } } public render() { @@ -130,6 +149,7 @@ export class ManifestDeploymentOptions extends React.Component< + +