backport of commit 7ab7edf9cdec6ceab92e47c1472a43d802de0486 (#19240)
Co-authored-by: Phil Renaud <phil.renaud@hashicorp.com>
This commit is contained in:
parent
b62e524bbb
commit
655b6fa97f
|
@ -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
|
||||
```
|
|
@ -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, ' ')
|
||||
);
|
||||
}
|
||||
}
|
|
@ -12,5 +12,8 @@ export default class JobPlan extends Model {
|
|||
@attr() diff;
|
||||
@fragmentArray('placement-failure', { defaultValue: () => [] })
|
||||
failedTGAllocs;
|
||||
|
||||
@hasMany('allocation') preemptions;
|
||||
|
||||
@attr('string') warnings;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -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';
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
@ -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');
|
||||
|
@ -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) {
|
||||
|
|
|
@ -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]'),
|
||||
},
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue