Skip to content

Commit

Permalink
Add button to fail running deployments
Browse files Browse the repository at this point in the history
As suggested in #9826. The placement is currently ridiculous.
  • Loading branch information
backspace committed Jan 15, 2021
1 parent 289a7e8 commit 61cca85
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 0 deletions.
10 changes: 10 additions & 0 deletions ui/app/adapters/deployment.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
import Watchable from './watchable';

export default class DeploymentAdapter extends Watchable {
fail(deployment) {
const id = deployment.get('id');
const url = urlForAction(this.urlForFindRecord(id, 'deployment'), '/fail');
return this.ajax(url, 'POST', {
data: {
DeploymentId: id,
},
});
}

promote(deployment) {
const id = deployment.get('id');
const url = urlForAction(this.urlForFindRecord(id, 'deployment'), '/promote');
Expand Down
24 changes: 24 additions & 0 deletions ui/app/components/job-deployment.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,34 @@
import Component from '@ember/component';
import { classNames } from '@ember-decorators/component';
import classic from 'ember-classic-decorator';
import { task } from 'ember-concurrency';
import { ForbiddenError } from '@ember-data/adapter/error';
import messageFromAdapterError from 'nomad-ui/utils/message-from-adapter-error';

@classic
@classNames('job-deployment', 'boxed-section')
export default class JobDeployment extends Component {
deployment = null;
isOpen = false;

handleError() {}

@task(function*() {
try {
yield this.deployment.fail();
} catch (err) {
console.log('err?', err);
let message = messageFromAdapterError(err);

if (err instanceof ForbiddenError) {
message = 'Your ACL token does not grant permission to fail deployments.';
}

this.handleError({
title: 'Could Not Fail Deployment',
description: message,
});
}
})
fail;
}
5 changes: 5 additions & 0 deletions ui/app/models/deployment.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,9 @@ export default class Deployment extends Model {
assert('A deployment needs to requirePromotion to be promoted', this.requiresPromotion);
return this.store.adapterFor('deployment').promote(this);
}

fail() {
assert('A deployment must be running to be failed', this.isRunning);
return this.store.adapterFor('deployment').fail(this);
}
}
8 changes: 8 additions & 0 deletions ui/app/templates/components/job-deployment.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@
{{#if this.deployment.requiresPromotion}}
<span data-test-promotion-required class="bumper-left badge is-warning is-hollow">Requires Promotion</span>
{{/if}}
{{#if this.deployment.isRunning}}
<button
data-test-fail-deployment
type="button"
class="button is-warning is-small pull-right {{if this.fail.isRunning "is-loading"}}"
disabled={{this.fail.isRunning}}
onclick={{perform this.fail}}>Fail Deployment</button>
{{/if}}
<span class="pull-right">
<span class="pair is-faded">
<span class="term">Version</span>
Expand Down
5 changes: 5 additions & 0 deletions ui/mirage/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,11 @@ export default function() {
});

this.get('/deployment/:id');

this.post('/deployment/fail/:id', function() {
return new Response(200, {}, '');
});

this.post('/deployment/promote/:id', function() {
return new Response(204, {}, '');
});
Expand Down
26 changes: 26 additions & 0 deletions ui/tests/acceptance/job-deployments-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ module('Acceptance | job deployments', function(hooks) {
deploymentRow.submitTime.includes(moment(version.submitTime / 1000000).fromNow()),
'Submit time ago'
);

if (deployment.status === 'running') {
assert.ok(deploymentRow.failButton.isPresent, 'a runnning deployment can be failed');
} else {
assert.ok(deploymentRow.failButton.isHidden, 'a deploymentn that is not running cannot be failed');
}
});

test('when the deployment is running and needs promotion, the deployment item says so', async function(assert) {
Expand All @@ -97,6 +103,26 @@ module('Acceptance | job deployments', function(hooks) {
assert.ok(deploymentRow.promotionIsRequired, 'Requires Promotion badge found');
});

test('when the deployment is running, it can be caused to fail', async function(assert) {
// Ensure the deployment needs deployment
const deployment = sortedDeployments.models[0];

deployment.update('status', 'running');
deployment.save();

await Deployments.visit({ id: job.id });

const deploymentRow = Deployments.deployments[0];

await deploymentRow.failButton.click();

assert.equal(
server.pretender.handledRequests.findBy('method', 'POST').url,
`/v1/deployment/fail/${deployment.id}`,
'Stop request is made for the allocation'
);
});

test('each deployment item can be opened to show details', async function(assert) {
await Deployments.visit({ id: job.id });

Expand Down
4 changes: 4 additions & 0 deletions ui/tests/pages/jobs/job/deployments.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ export default create({

toggle: clickable('[data-test-deployment-toggle-details]'),

failButton: {
scope: '[data-test-fail-deployment]',
},

hasDetails: isPresent('[data-test-deployment-details]'),

metrics: collection('[data-test-deployment-metric]', {
Expand Down
14 changes: 14 additions & 0 deletions ui/tests/unit/adapters/deployment-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,13 @@ module('Unit | Adapter | Deployment', function(hooks) {
{
variation: '',
region: null,
fail: id => `POST /v1/deployment/fail/${id}`,
promote: id => `POST /v1/deployment/promote/${id}`,
},
{
variation: 'with non-default region',
region: 'region-2',
fail: id => `POST /v1/deployment/fail/${id}?region=region-2`,
promote: id => `POST /v1/deployment/promote/${id}?region=region-2`,
},
];
Expand All @@ -64,5 +66,17 @@ module('Unit | Adapter | Deployment', function(hooks) {
All: true,
});
});

test(`fail makes the correct API call ${testCase.variation}`, async function(assert) {
const deployment = await this.initialize({ region: testCase.region });
await this.subject().fail(deployment);

const request = this.server.pretender.handledRequests[0];

assert.equal(`${request.method} ${request.url}`, testCase.fail(deployment.id));
assert.deepEqual(JSON.parse(request.requestBody), {
DeploymentId: deployment.id,
});
})
});
});

0 comments on commit 61cca85

Please sign in to comment.