Skip to content
This repository was archived by the owner on Dec 20, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/core/src/config/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export interface IFeatures {
functions?: boolean;
kubernetesRawResources?: boolean;
renderPipelineStageThreshold?: number;
deployManifestStageAdvancedConfiguration?: boolean;
}

export interface IDockerInsightSettings {
Expand Down
4 changes: 4 additions & 0 deletions packages/kubernetes/src/help/kubernetes.help.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,10 @@ const helpContents: { [key: string]: string } = {
'<p>Skip SpEL expression evaluation of the manifest artifact in this stage. Can be paired with the "Evaluate SpEL expressions in overrides at bake time" option in the Bake Manifest stage when baking a third-party manifest artifact with expressions not meant for Spinnaker to evaluate as SpEL.</p>',
'kubernetes.manifest.skipSpecTemplateLabels': `
<p>Skip applying the <a href="https://spinnaker.io/docs/reference/providers/kubernetes-v2/#reserved-labels" target="_blank">Reserved labels</a> to the manifest's <b><i>.spec.template.metadata.labels.</i></b></p>`,
'kubernetes.manifest.deployLabelSelectors': `
<p>Via Label Selectors, Spinnaker can deploy a subset of manifests satisfying the Label Selectors. See <a href="https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors" target="_blank">Kubernetes Label Selectors</a> for more details. Multiple selectors combine with AND (All must be satisfied).</p>`,
'kubernetes.manifest.deployLabelSelectors.allowNothingSelected': `
<p>When unchecked an error is thrown if none of the provided manifests satisfy the Label Selectors</p>`,
'kubernetes.manifest.undoRollout.revisionsBack': `
<p>How many revisions to rollback from the current active revision. This is not a hard-coded revision to rollout.</p>
<p>For example: If you specify "1", and this stage executes, the prior revision will be active upon success.</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
ArtifactTypePatterns,
CheckboxInput,
RadioButtonInput,
SETTINGS,
StageArtifactSelectorDelegate,
StageConfigField,
yamlDocumentsToString,
Expand All @@ -25,15 +26,23 @@ import { ManifestBindArtifactsSelector } from './ManifestBindArtifactsSelector';
import { ManifestDeploymentOptions } from './ManifestDeploymentOptions';
import { NamespaceSelector } from './NamespaceSelector';
import { ManifestSource } from '../../../manifest/ManifestSource';
import type { IManifestLabelSelector } from '../../../manifest/selector/IManifestLabelSelector';
import type { IManifestSelector } from '../../../manifest/selector/IManifestSelector';
import { SelectorMode } from '../../../manifest/selector/IManifestSelector';
import LabelEditor from '../../../manifest/selector/labelEditor/LabelEditor';
import { ManifestBasicSettings } from '../../../manifest/wizard/BasicSettings';

interface IDeployManifestStageConfigFormProps {
accounts: IAccountDetails[];
selector?: IManifestSelector;
modes?: SelectorMode.Label;
}

interface IDeployManifestStageConfigFormState {
rawManifest: string;
overrideNamespace: boolean;
selector: IManifestSelector;
labelSelectors: IManifestLabelSelector[];
}

export class DeployManifestStageForm extends React.Component<
Expand All @@ -55,6 +64,13 @@ export class DeployManifestStageForm extends React.Component<
this.state = {
rawManifest: !isEmpty(manifests) && isTextManifest ? yamlDocumentsToString(manifests) : '',
overrideNamespace: get(stage, 'namespaceOverride', '') !== '',
selector: {
account: '',
location: '',
mode: SelectorMode.Label,
labelSelectors: { selectors: [] },
},
labelSelectors: [],
};
}

Expand Down Expand Up @@ -186,14 +202,51 @@ export class DeployManifestStageForm extends React.Component<
stage={stage}
/>
</StageConfigField>
<hr />
<h4>Deploy Configuration</h4>
<StageConfigField label="Skip Spec Template Labels" helpKey="kubernetes.manifest.skipSpecTemplateLabels">
<CheckboxInput
checked={stage.skipSpecTemplateLabels === true}
onChange={(e: any) => this.props.formik.setFieldValue('skipSpecTemplateLabels', e.target.checked)}
/>
</StageConfigField>
{SETTINGS.feature.deployManifestStageAdvancedConfiguration && (
<>
<hr />
<h4>Deploy Configuration</h4>
<StageConfigField label="Skip Spec Template Labels" helpKey="kubernetes.manifest.skipSpecTemplateLabels">
<CheckboxInput
checked={stage.skipSpecTemplateLabels === true}
onChange={(e: any) => this.props.formik.setFieldValue('skipSpecTemplateLabels', e.target.checked)}
/>
</StageConfigField>
<StageConfigField label="Label Selectors" helpKey="kubernetes.manifest.deployLabelSelectors">
<CheckboxInput
checked={stage.labelSelectors != null}
onChange={(e: any) => {
if (e.target.checked) {
this.props.formik.setFieldValue('labelSelectors', { selectors: [] });
this.props.formik.setFieldValue('allowNothingSelected', false);
} else {
this.props.formik.setFieldValue('labelSelectors', null);
this.props.formik.setFieldValue('allowNothingSelected', null);
}
}}
/>
</StageConfigField>
{stage.labelSelectors && stage.labelSelectors.selectors && (
<>
<StageConfigField label="Labels">
<LabelEditor
labelSelectors={this.props.formik.values.labelSelectors.selectors}
onLabelSelectorsChange={this.handleLabelSelectorsChange}
/>
</StageConfigField>
<StageConfigField
label="Allow nothing selected"
helpKey="kubernetes.manifest.deployLabelSelectors.allowNothingSelected"
>
<CheckboxInput
checked={stage.allowNothingSelected === true}
onChange={(e: any) => this.props.formik.setFieldValue('allowNothingSelected', e.target.checked)}
/>
</StageConfigField>
</>
)}
</>
)}
<hr />
<ManifestDeploymentOptions
accounts={this.props.accounts}
Expand All @@ -204,4 +257,9 @@ export class DeployManifestStageForm extends React.Component<
</div>
);
}

private handleLabelSelectorsChange = (labelSelectors: IManifestLabelSelector[]): void => {
this.setState({ labelSelectors });
this.props.formik.setFieldValue('labelSelectors.selectors', labelSelectors);
};
}