mirror of
https://github.com/kemko/nomad.git
synced 2026-01-01 16:05:42 +03:00
[ui] Scope selection for Sentinel Policies (#25390)
* An option to select, and column etc. to view, sentinel policy scope * Flake potential: Seed(1) had a couple jobs with the same ModifyIndex * More de-flaking
This commit is contained in:
3
.changelog/25390.txt
Normal file
3
.changelog/25390.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
```release-note:improvement
|
||||||
|
ui: Added a scope selector for sentinel policy page
|
||||||
|
```
|
||||||
@@ -77,6 +77,18 @@
|
|||||||
</Hds::Form::Radio::Group>
|
</Hds::Form::Radio::Group>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Hds::Form::Radio::Group @layout="horizontal" @name="method-demo1" {{on "change" this.updatePolicyScope}} as |G|>
|
||||||
|
<G.Legend>Scope</G.Legend>
|
||||||
|
<G.RadioField @id="submit-job" checked={{eq @policy.scope "submit-job"}} data-test-scope="submit-job" as |F|>
|
||||||
|
<F.Label>Submit Job</F.Label>
|
||||||
|
</G.RadioField>
|
||||||
|
<G.RadioField @id="submit-host-volume" checked={{eq @policy.scope "submit-host-volume"}} data-test-scope="submit-host-volume" as |F|>
|
||||||
|
<F.Label>Submit Host Volume</F.Label>
|
||||||
|
</G.RadioField>
|
||||||
|
</Hds::Form::Radio::Group>
|
||||||
|
</div>
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
{{#if (can "update sentinel-policy")}}
|
{{#if (can "update sentinel-policy")}}
|
||||||
<Hds::Button
|
<Hds::Button
|
||||||
|
|||||||
@@ -30,6 +30,10 @@ export default class SentinelPolicyEditorComponent extends Component {
|
|||||||
this.policy.set('enforcementLevel', id);
|
this.policy.set('enforcementLevel', id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@action updatePolicyScope({ target: { id } }) {
|
||||||
|
this.policy.set('scope', id);
|
||||||
|
}
|
||||||
|
|
||||||
@action async save(e) {
|
@action async save(e) {
|
||||||
if (e instanceof Event) {
|
if (e instanceof Event) {
|
||||||
e.preventDefault(); // code-mirror "command+enter" submits the form, but doesnt have a preventDefault()
|
e.preventDefault(); // code-mirror "command+enter" submits the form, but doesnt have a preventDefault()
|
||||||
|
|||||||
@@ -43,6 +43,11 @@ export default class SentinelPoliciesIndexController extends Controller {
|
|||||||
label: 'Enforcement Level',
|
label: 'Enforcement Level',
|
||||||
isSortable: true,
|
isSortable: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: 'scope',
|
||||||
|
label: 'Scope',
|
||||||
|
isSortable: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: 'delete',
|
key: 'delete',
|
||||||
label: 'Delete',
|
label: 'Delete',
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ SPDX-License-Identifier: BUSL-1.1
|
|||||||
</B.Td>
|
</B.Td>
|
||||||
<B.Td data-test-sentinel-policy-description>{{B.data.description}}</B.Td>
|
<B.Td data-test-sentinel-policy-description>{{B.data.description}}</B.Td>
|
||||||
<B.Td data-test-sentinel-policy-enforcement>{{B.data.enforcementLevel}}</B.Td>
|
<B.Td data-test-sentinel-policy-enforcement>{{B.data.enforcementLevel}}</B.Td>
|
||||||
|
<B.Td data-test-sentinel-policy-scope>{{B.data.scope}}</B.Td>
|
||||||
{{#if (can "destroy sentinel-policy")}}
|
{{#if (can "destroy sentinel-policy")}}
|
||||||
<B.Td>
|
<B.Td>
|
||||||
<TwoStepButton
|
<TwoStepButton
|
||||||
|
|||||||
@@ -22,6 +22,6 @@ export default Factory.extend({
|
|||||||
|
|
||||||
main = rule { false }`,
|
main = rule { false }`,
|
||||||
|
|
||||||
scope: 'submit-job',
|
scope: pickOne(['submit-job', 'submit-host-volume']),
|
||||||
enforcementLevel: pickOne(['advisory', 'soft-mandatory', 'hard-mandatory']),
|
enforcementLevel: pickOne(['advisory', 'soft-mandatory', 'hard-mandatory']),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -685,6 +685,21 @@ function policiesTestCluster(server, options = { sentinel: false }) {
|
|||||||
scope: 'submit-job',
|
scope: 'submit-job',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
server.create('sentinel-policy', {
|
||||||
|
id: 'host-volume-policy',
|
||||||
|
name: 'host-volume-policy',
|
||||||
|
description: 'A sentinel policy generated by Mirage',
|
||||||
|
enforcementLevel: 'soft-mandatory',
|
||||||
|
policy: `
|
||||||
|
has_tag = func() {
|
||||||
|
print("volume is missing tag")
|
||||||
|
tag = volume.parameters["tag"] else 0
|
||||||
|
return tag is not 0
|
||||||
|
}
|
||||||
|
main = rule { has_tag() }
|
||||||
|
`,
|
||||||
|
scope: 'submit-host-volume',
|
||||||
|
});
|
||||||
server.createList('sentinel-policy', 5);
|
server.createList('sentinel-policy', 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -167,7 +167,11 @@ moduleForJobWithClientStatus(
|
|||||||
moduleForJob(
|
moduleForJob(
|
||||||
'Acceptance | job detail (periodic)',
|
'Acceptance | job detail (periodic)',
|
||||||
'children',
|
'children',
|
||||||
() => server.create('job', 'periodic', { shallow: true }),
|
() =>
|
||||||
|
server.create('job', 'periodic', {
|
||||||
|
shallow: true,
|
||||||
|
withPreviousStableVersion: true,
|
||||||
|
}),
|
||||||
{
|
{
|
||||||
'the default sort is submitTime descending': async function (job, assert) {
|
'the default sort is submitTime descending': async function (job, assert) {
|
||||||
const mostRecentLaunch = server.db.jobs
|
const mostRecentLaunch = server.db.jobs
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ module('Acceptance | jobs list', function (hooks) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('/jobs should list the first page of jobs sorted by modify index', async function (assert) {
|
test('/jobs should list the first page of jobs sorted by modify index', async function (assert) {
|
||||||
faker.seed(1);
|
faker.seed(2);
|
||||||
const jobsCount = JobsList.pageSize + 1;
|
const jobsCount = JobsList.pageSize + 1;
|
||||||
server.createList('job', jobsCount, { createAllocations: true });
|
server.createList('job', jobsCount, { createAllocations: true });
|
||||||
|
|
||||||
@@ -2087,6 +2087,7 @@ function testFacet(
|
|||||||
});
|
});
|
||||||
|
|
||||||
test(`selecting multiple options in the ${label} facet results in a broader search`, async function (assert) {
|
test(`selecting multiple options in the ${label} facet results in a broader search`, async function (assert) {
|
||||||
|
faker.seed(2);
|
||||||
const selection = [];
|
const selection = [];
|
||||||
|
|
||||||
await beforeEach();
|
await beforeEach();
|
||||||
|
|||||||
@@ -106,6 +106,30 @@ module('Acceptance | sentinel policies', function (hooks) {
|
|||||||
.hasText('hard-mandatory');
|
.hasText('hard-mandatory');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Edit Sentinel Policy: Scope', async function (assert) {
|
||||||
|
const policy = server.db.sentinelPolicies.findBy(
|
||||||
|
(sp) => sp.name === 'host-volume-policy'
|
||||||
|
);
|
||||||
|
await click('[data-test-sentinel-policy-name="host-volume-policy"]');
|
||||||
|
assert.equal(
|
||||||
|
currentURL(),
|
||||||
|
`/administration/sentinel-policies/${policy.id}`
|
||||||
|
);
|
||||||
|
|
||||||
|
await click('[data-test-scope="submit-host-volume"]');
|
||||||
|
await click('button[data-test-save-policy]');
|
||||||
|
assert.dom('.flash-message.alert-success').exists();
|
||||||
|
|
||||||
|
await Administration.visitSentinelPolicies();
|
||||||
|
const policyRow = find(
|
||||||
|
'[data-test-sentinel-policy-name="host-volume-policy"]'
|
||||||
|
).closest('[data-test-sentinel-policy-row]');
|
||||||
|
assert.dom(policyRow).exists();
|
||||||
|
assert
|
||||||
|
.dom(policyRow.querySelector('[data-test-sentinel-policy-scope]'))
|
||||||
|
.hasText('submit-host-volume');
|
||||||
|
});
|
||||||
|
|
||||||
test('New Sentinel Policy from Scratch', async function (assert) {
|
test('New Sentinel Policy from Scratch', async function (assert) {
|
||||||
await click('[data-test-create-sentinel-policy]');
|
await click('[data-test-create-sentinel-policy]');
|
||||||
assert.equal(currentURL(), '/administration/sentinel-policies/new');
|
assert.equal(currentURL(), '/administration/sentinel-policies/new');
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import a11yAudit from 'nomad-ui/tests/helpers/a11y-audit';
|
|||||||
import Task from 'nomad-ui/tests/pages/allocations/task/detail';
|
import Task from 'nomad-ui/tests/pages/allocations/task/detail';
|
||||||
import Layout from 'nomad-ui/tests/pages/layout';
|
import Layout from 'nomad-ui/tests/pages/layout';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
import faker from 'faker';
|
||||||
let allocation;
|
let allocation;
|
||||||
let task;
|
let task;
|
||||||
|
|
||||||
@@ -213,6 +214,7 @@ module('Acceptance | task detail', function (hooks) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('when a task group has metadata, the metadata table is shown', async function (assert) {
|
test('when a task group has metadata, the metadata table is shown', async function (assert) {
|
||||||
|
faker.seed(2);
|
||||||
const job = server.create('job', {
|
const job = server.create('job', {
|
||||||
createAllocations: false,
|
createAllocations: false,
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user