Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ui] Display job plan warnings alongside dry run info when attempting to run a job through the web UI #19225

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
3 changes: 3 additions & 0 deletions .changelog/19225.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
ui: show plan output warnings alongside placement failures and dry-run info when running a job through the web ui
```
18 changes: 18 additions & 0 deletions ui/app/components/job-editor/review.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/

import Component from '@glimmer/component';
import { htmlSafe } from '@ember/template';

export default class JobEditorReviewComponent extends Component {
// Slightly formats the warning string to be more readable
get warnings() {
return htmlSafe(
(this.args.data.planOutput.warnings || '')
.replace(/\n/g, '<br>')
.replace(/\t/g, '&nbsp;&nbsp;&nbsp;&nbsp;')
);
}
}
3 changes: 3 additions & 0 deletions ui/app/models/job-plan.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@ export default class JobPlan extends Model {
@attr() diff;
@fragmentArray('placement-failure', { defaultValue: () => [] })
failedTGAllocs;

@hasMany('allocation') preemptions;

@attr('string') warnings;
}
34 changes: 22 additions & 12 deletions ui/app/templates/components/job-editor/review.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,32 @@
/>
</div>
</div>
<div
class="boxed-section
{{if @data.planOutput.failedTGAllocs 'is-warning' 'is-primary'}}"
data-test-dry-run-message
>
<div class="boxed-section-head" data-test-dry-run-title>Scheduler dry-run</div>
<div class="boxed-section-body" data-test-dry-run-body>

<Hds::Alert @type="inline" @color={{if @data.planOutput.failedTGAllocs "critical" "success"}} data-test-dry-run-message as |A|>
<A.Title data-test-dry-run-title>Scheduler dry-run</A.Title>
<A.Description data-test-dry-run-body>
{{#if @data.planOutput.failedTGAllocs}}
{{#each @data.planOutput.failedTGAllocs as |placementFailure|}}
{{#each @data.planOutput.failedTGAllocs as |placementFailure|}}
<PlacementFailure @failedTGAlloc={{placementFailure}} />
{{/each}}
{{/each}}
{{else}}
All tasks successfully allocated.
All tasks successfully allocated.
{{/if}}
</div>
</div>
</A.Description>
</Hds::Alert>
<br>

{{#if this.warnings}}
<Hds::Alert @type="inline" @color="warning" data-test-dry-run-warnings as |A|>
<A.Description data-test-dry-run-warning-body>
<p>
{{this.warnings}}
</p>
</A.Description>
</Hds::Alert>
<br>
{{/if}}

{{#if
(and
@data.planOutput.preemptions.isFulfilled @data.planOutput.preemptions.length
Expand Down
12 changes: 11 additions & 1 deletion ui/mirage/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,16 @@ export default function () {
const FailedTGAllocs =
body.Job.Unschedulable && generateFailedTGAllocs(body.Job);

const jobPlanWarnings = body.Job.WithWarnings && generateWarnings();

return new Response(
200,
{},
JSON.stringify({ FailedTGAllocs, Diff: generateDiff(req.params.id) })
JSON.stringify({
FailedTGAllocs,
Warnings: jobPlanWarnings,
Diff: generateDiff(req.params.id),
})
);
});

Expand Down Expand Up @@ -1224,3 +1230,7 @@ function generateFailedTGAllocs(job, taskGroups) {
return hash;
}, {});
}

function generateWarnings() {
return '2 warnings:\n\n* Group "yourtask" has warnings: 1 error occurred:\n\t* Task "yourtask" has warnings: 1 error occurred:\n\t* 2 errors occurred:\n\t* Identity[vault_default] identities without an audience are insecure\n\t* Identity[vault_default] identities without an expiration are insecure\n* Task yourtask has an identity called vault_default but no vault block';
}
25 changes: 23 additions & 2 deletions ui/tests/integration/components/job-editor-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import jobEditor from 'nomad-ui/tests/pages/components/job-editor';
import { initialize as fragmentSerializerInitializer } from 'nomad-ui/initializers/fragment-serializer';
import setupCodeMirror from 'nomad-ui/tests/helpers/codemirror';
import { componentA11yAudit } from 'nomad-ui/tests/helpers/a11y-audit';
import percySnapshot from '@percy/ember';

const Editor = create(jobEditor());

Expand Down Expand Up @@ -290,8 +291,8 @@ module('Integration | Component | job-editor', function (hooks) {
await componentA11yAudit(this.element, assert);
});

test('when the scheduler dry-run has warnings, the warnings are shown to the user', async function (assert) {
assert.expect(4);
test('when the scheduler dry-run has errors, the errors are shown to the user', async function (assert) {
assert.expect(5);

const spec = jsonJob({ Unschedulable: true });
const job = await this.store.createRecord('job');
Expand All @@ -312,7 +313,27 @@ module('Integration | Component | job-editor', function (hooks) {
'The scheduler dry-run message includes the warning from send back by the API'
);

assert.notOk(
Editor.warningMessage.isPresent,
'The scheduler dry-run warning block is not present when there is an error but no warnings'
);

await componentA11yAudit(this.element, assert);

await percySnapshot(assert);
});

test('When the scheduler dry-run has warnings, the warnings are shown to the user', async function (assert) {
assert.expect(1);
const spec = jsonJob({ WithWarnings: true });
const job = await this.store.createRecord('job');
await renderNewJob(this, job);
await planJob(spec);
assert.ok(
Editor.warningMessage.isPresent,
'The scheduler dry-run warning block is shown to the user'
);
await percySnapshot(assert);
});

test('when the scheduler dry-run has no warnings, a success message is shown to the user', async function (assert) {
Expand Down
9 changes: 7 additions & 2 deletions ui/tests/pages/components/job-editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,12 @@ export default () => ({
scope: '[data-test-dry-run-message]',
title: text('[data-test-dry-run-title]'),
body: text('[data-test-dry-run-body]'),
errored: hasClass('is-warning'),
succeeded: hasClass('is-primary'),
errored: hasClass('hds-alert--color-critical'),
succeeded: hasClass('hds-alert--color-success'),
},

warningMessage: {
scope: '[data-test-dry-run-warnings]',
body: text('[data-test-dry-run-warning-body]'),
},
});