Skip to content

Commit

Permalink
refactor(titus): Moving constraints from lists to maps (#7069)
Browse files Browse the repository at this point in the history
  • Loading branch information
alanmquach committed Jun 3, 2019
1 parent de67f16 commit 008544f
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

const angular = require('angular');

import { set } from 'lodash';
import { NameUtils } from '@spinnaker/core';
import { TitusProviderSettings } from '../../titus.settings';

Expand Down Expand Up @@ -48,8 +49,10 @@ module.exports = angular
cloudProvider: 'titus',
selectedProvider: 'titus',
iamProfile: defaultIamProfile,
softConstraints: [],
hardConstraints: [],
constraints: {
hard: {},
soft: {},
},
viewState: {
useSimpleCapacity: true,
usePreferredZones: true,
Expand Down Expand Up @@ -99,8 +102,10 @@ module.exports = angular
capacityGroup: serverGroup.capacityGroup,
migrationPolicy: serverGroup.migrationPolicy ? serverGroup.migrationPolicy : { type: 'systemDefault' },
securityGroups: serverGroup.securityGroups || [],
hardConstraints: serverGroup.hardConstraints || [],
softConstraints: serverGroup.softConstraints || [],
constraints: {
hard: (serverGroup.constraints && serverGroup.constraints.hard) || {},
soft: (serverGroup.constraints && serverGroup.constraints.soft) || {},
},
inService: serverGroup.disabled ? false : true,
source: {
account: serverGroup.account,
Expand Down Expand Up @@ -168,8 +173,21 @@ module.exports = angular

return asyncLoader.then(function(asyncData) {
var command = asyncData.command;
command.hardConstraints = command.hardConstraints || [];
command.softConstraints = command.softConstraints || [];

command.constraints = {
hard:
(originalCluster.constraints && originalCluster.constraints.hard) ||
(originalCluster.hardConstraints &&
originalCluster.hardConstraints.reduce((a, c) => set(a, c, 'true'), {})) ||
{},
soft:
(originalCluster.constraints && originalCluster.constraints.soft) ||
(originalCluster.softConstraints &&
originalCluster.softConstraints.reduce((a, c) => set(a, c, 'true'), {})) ||
{},
};
delete pipelineCluster.hardConstraints;
delete pipelineCluster.softConstraints;

var viewState = {
disableImageSelection: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ export const getDefaultJobDisruptionBudgetForApp = (application: Application): I
return budget;
};

export type Constraint = 'ExclusiveHost' | 'UniqueHost' | 'ZoneBalance';
export interface ITitusServerGroupCommand extends IServerGroupCommand {
cluster?: ICluster;
disruptionBudget?: IJobDisruptionBudget;
Expand Down Expand Up @@ -104,8 +103,10 @@ export interface ITitusServerGroupCommand extends IServerGroupCommand {
migrationPolicy: {
type: string;
};
softConstraints: Constraint[];
hardConstraints: Constraint[];
constraints: {
hard: { [key: string]: string };
soft: { [key: string]: string };
};
}

export class TitusServerGroupConfigurationService {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,40 +11,29 @@ import {
Application,
} from '@spinnaker/core';

import { ITitusServerGroupCommand, Constraint } from '../../../configure/serverGroupConfiguration.service';
import { ITitusServerGroupCommand } from '../../../configure/serverGroupConfiguration.service';
import { intersection } from 'lodash';

export interface IServerGroupParametersProps {
app: Application;
formik: FormikProps<ITitusServerGroupCommand>;
}

export interface IServerGroupParametersState {
hardConstraintOptions: Array<Option<Constraint>>;
softConstraintOptions: Array<Option<Constraint>>;
}

const constraintOptions: Array<Option<Constraint>> = [
{ label: 'ExclusiveHost', value: 'ExclusiveHost' },
{ label: 'UniqueHost', value: 'UniqueHost' },
{ label: 'ZoneBalance', value: 'ZoneBalance' },
];

const migrationPolicyOptions = [
{ label: 'System Default', value: 'systemDefault' },
{ label: 'Self Managed', value: 'selfManaged' },
];

export class ServerGroupParameters extends React.Component<IServerGroupParametersProps, IServerGroupParametersState>
export class ServerGroupParameters extends React.Component<IServerGroupParametersProps>
implements IWizardPageComponent<ITitusServerGroupCommand> {
private duplicateKeys: { [name: string]: boolean } = {};

constructor(props: IServerGroupParametersProps) {
super(props);

this.state = this.getConstraints(props.formik.values);
}

public validate(_values: ITitusServerGroupCommand) {
const { soft: softConstraints, hard: hardConstraints } = _values.constraints;
const errors = {} as any;

if (this.duplicateKeys.labels) {
Expand All @@ -57,6 +46,14 @@ export class ServerGroupParameters extends React.Component<IServerGroupParameter
errors.env = 'Environment Variables have duplicate keys.';
}

const duplicateConstraints = intersection(Object.keys(softConstraints), Object.keys(hardConstraints));
if (duplicateConstraints.length > 0) {
errors.constraints = errors.constraints || {};
errors.constraints.soft = errors.constraints.hard = `${duplicateConstraints.join(
',',
)} constraints must be either soft or hard, not both.`;
}

return errors;
}

Expand All @@ -69,24 +66,9 @@ export class ServerGroupParameters extends React.Component<IServerGroupParameter
this.props.formik.setFieldValue('interestingHealthProviderNames', healthNames);
};

private getConstraints = (values: ITitusServerGroupCommand) => {
return {
hardConstraintOptions: constraintOptions.filter(o => !values.softConstraints.includes(o.value as any)),
softConstraintOptions: constraintOptions.filter(o => !values.hardConstraints.includes(o.value as any)),
};
};

private updateConstraints = (name: string, constraints: Constraint[]) => {
const { values, setFieldValue } = this.props.formik;
setFieldValue(name, constraints);
(values as any)[name] = constraints;
this.setState(this.getConstraints(values));
};

public render() {
const { app } = this.props;
const { setFieldValue, values } = this.props.formik;
const { softConstraintOptions, hardConstraintOptions } = this.state;

return (
<>
Expand All @@ -102,38 +84,6 @@ export class ServerGroupParameters extends React.Component<IServerGroupParameter
in <AccountTag account={values.backingData.credentialsKeyedByAccount[values.credentials].awsAccount} />
</div>
</div>
<div className="form-group">
<div className="col-md-4 sm-label-right">
<b>Soft Constraints </b>
<HelpField id="titus.deploy.hardConstraints" />
</div>
<div className="col-md-5">
<Select
multi={true}
value={values.softConstraints}
options={softConstraintOptions}
onChange={(option: Array<Option<Constraint>>) =>
this.updateConstraints('softConstraints', option.map(o => o.value))
}
/>
</div>
</div>
<div className="form-group">
<div className="col-md-4 sm-label-right">
<b>Hard Constraints </b>
<HelpField id="titus.deploy.hardConstraints" />
</div>
<div className="col-md-5">
<Select
multi={true}
value={values.hardConstraints}
options={hardConstraintOptions}
onChange={(option: Array<Option<Constraint>>) =>
this.updateConstraints('hardConstraints', option.map(o => o.value))
}
/>
</div>
</div>
<div className="form-group">
<div className="col-md-4 sm-label-right">
<b>Capacity Group </b>
Expand All @@ -160,6 +110,33 @@ export class ServerGroupParameters extends React.Component<IServerGroupParameter
</div>
</div>
<hr />
<div className="form-group">
<h4 className="col-sm-12">
<b>Soft Constraints </b>
<HelpField id="titus.deploy.softConstraints" />
</h4>
<div className="col-sm-12">
<MapEditor
model={values.constraints.soft}
allowEmpty={true}
onChange={(v: any, d) => this.mapChanged('constraints.soft', v, d)}
/>
</div>
</div>
<div className="form-group">
<h4 className="col-sm-12">
<b>Hard Constraints </b>
<HelpField id="titus.deploy.hardConstraints" />
</h4>
<div className="col-sm-12">
<MapEditor
model={values.constraints.hard}
allowEmpty={true}
onChange={(v: any, d) => this.mapChanged('constraints.hard', v, d)}
/>
</div>
</div>
<hr />
<div className="form-group">
<h4 className="col-sm-12">
<b>Job Attributes</b>
Expand Down

0 comments on commit 008544f

Please sign in to comment.