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

Kubernetes Roles Acceptance Tests #18360

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
2 changes: 1 addition & 1 deletion ui/app/routes/vault/cluster/secrets/backend/list.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export default Route.extend({
const { tab } = this.paramsFor('vault.cluster.secrets.backend.list-root');
const secretEngine = this.store.peekRecord('secret-engine', backend);
const type = secretEngine && secretEngine.get('engineType');
const { engineRoute } = allEngines().findBy('type', type);
const engineRoute = allEngines().findBy('type', type)?.engineRoute;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉


if (!type || !SUPPORTED_BACKENDS.includes(type)) {
return this.router.transitionTo('vault.cluster.secrets');
Expand Down
6 changes: 3 additions & 3 deletions ui/lib/kubernetes/addon/components/page/credentials.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<span class="sep">/</span>
<LinkTo @route="roles">roles</LinkTo>
</li>
<li>
<li data-test-crumb="details">
<span class="sep">/</span>
<LinkTo @route="roles.role.details">{{@roleName}}</LinkTo>
</li>
Expand Down Expand Up @@ -62,7 +62,7 @@
</div>

<div class="has-top-margin-l">
<button class="button is-primary" type="button" {{on "click" this.cancel}}>
<button class="button is-primary" type="button" data-test-generate-credentials-done {{on "click" this.cancel}}>
Done
</button>
</div>
Expand Down Expand Up @@ -106,7 +106,7 @@
</Toggle>
</div>

<TtlPicker2
<TtlPicker
class="has-top-margin-l has-bottom-margin-m"
@initialEnabled={{false}}
@label="Time-to-Live (TTL)"
Expand Down
2 changes: 1 addition & 1 deletion ui/lib/kubernetes/addon/components/page/roles.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<ListItem @linkPrefix={{this.mountPoint}} @linkParams={{array "roles.role.details" role.name}} as |Item|>
<Item.content>
<Icon @name="user" />
{{role.name}}
<span data-test-role={{role.name}}>{{role.name}}</span>
</Item.content>
<Item.menu as |Menu|>
{{#if role.rolesPath.isLoading}}
Expand Down
11 changes: 10 additions & 1 deletion ui/mirage/handlers/kubernetes.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ export default function (server) {
return new Response(204);
};
const deleteRecord = (schema, req, dbKey) => {
const record = getRecord(schema, req, dbKey);
const { name } = req.params;
const record = schema.db[dbKey].findBy({ name });
if (record) {
schema.db[dbKey].remove(record.id);
}
Expand Down Expand Up @@ -86,4 +87,12 @@ export default function (server) {
},
};
});

server.get('/sys/internal/ui/mounts/kubernetes', () => ({
data: {
accessor: 'kubernetes_9f846a87',
path: 'kubernetes/',
type: 'kubernetes',
},
}));
}
6 changes: 2 additions & 4 deletions ui/mirage/scenarios/default.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import ENV from 'vault/config/environment';
const { handler } = ENV['ember-cli-mirage'];
import kubernetesScenario from './kubernetes';

export default function (server) {
server.create('clients/config');
server.create('feature', { feature_flags: ['SOME_FLAG', 'VAULT_CLOUD_ADMIN_NAMESPACE'] });

if (handler === 'kubernetes') {
server.create('kubernetes-config', { path: 'kubernetes' });
server.create('kubernetes-role');
server.create('kubernetes-role', 'withRoleName');
server.create('kubernetes-role', 'withRoleRules');
kubernetesScenario(server);
}
}
6 changes: 6 additions & 0 deletions ui/mirage/scenarios/kubernetes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default function (server) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for putting this in its own file!

server.create('kubernetes-config', { path: 'kubernetes' });
server.create('kubernetes-role');
server.create('kubernetes-role', 'withRoleName');
server.create('kubernetes-role', 'withRoleRules');
}
123 changes: 123 additions & 0 deletions ui/tests/acceptance/secrets/backend/kubernetes/roles-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { setupMirage } from 'ember-cli-mirage/test-support';
import kubernetesScenario from 'vault/mirage/scenarios/kubernetes';
import ENV from 'vault/config/environment';
import authPage from 'vault/tests/pages/auth';
import { fillIn, visit, currentURL, click, currentRouteName } from '@ember/test-helpers';

module('Acceptance | kubernetes | roles', function (hooks) {
setupApplicationTest(hooks);
setupMirage(hooks);

hooks.before(function () {
ENV['ember-cli-mirage'].handler = 'kubernetes';
});
hooks.beforeEach(function () {
kubernetesScenario(this.server);
this.visitRoles = () => {
return visit('/vault/secrets/kubernetes/kubernetes/roles');
};
this.validateRoute = (assert, route, message) => {
assert.strictEqual(currentRouteName(), `vault.cluster.secrets.backend.kubernetes.${route}`, message);
};
return authPage.login();
});
hooks.after(function () {
ENV['ember-cli-mirage'].handler = null;
});

test('it should filter roles', async function (assert) {
await this.visitRoles();
assert.dom('[data-test-list-item-link]').exists({ count: 3 }, 'Roles list renders');
await fillIn('[data-test-comoponent="navigate-input"]', '1');
assert.dom('[data-test-list-item-link]').exists({ count: 1 }, 'Filtered roles list renders');
assert.ok(currentURL().includes('pageFilter=1'), 'pageFilter query param value is set');
});

test('it should link to role details on list item click', async function (assert) {
assert.expect(1);
await this.visitRoles();
await click('[data-test-list-item-link]');
this.validateRoute(assert, 'roles.role.details', 'Transitions to details route on list item click');
});

test('it should have correct breadcrumb links in role details view', async function (assert) {
assert.expect(2);
await this.visitRoles();
await click('[data-test-list-item-link]');
await click('[data-test-crumb="roles"] a');
this.validateRoute(assert, 'roles.index', 'Transitions to roles route on breadcrumb click');
await click('[data-test-list-item-link]');
await click('[data-test-crumb="overview"] a');
this.validateRoute(assert, 'overview', 'Transitions to overview route on breadcrumb click');
});

test('it should have functional list item menu', async function (assert) {
assert.expect(3);
await this.visitRoles();
for (const action of ['details', 'edit', 'delete']) {
await click('[data-test-list-item-popup] button');
await click(`[data-test-${action}]`);
if (action === 'delete') {
await click('[data-test-confirm-button]');
assert.dom('[data-test-list-item-link]').exists({ count: 2 }, 'Deleted role removed from list');
} else {
this.validateRoute(
assert,
`roles.role.${action}`,
`Transitions to ${action} route on menu action click`
);
const selector = action === 'details' ? '[data-test-crumb="roles"] a' : '[data-test-cancel]';
await click(selector);
}
}
});

test('it should create role', async function (assert) {
assert.expect(2);
await this.visitRoles();
await click('[data-test-toolbar-roles-action]');
await click('[data-test-radio-card="basic"]');
await fillIn('[data-test-input="name"]', 'new-test-role');
await fillIn('[data-test-input="serviceAccountName"]', 'default');
await fillIn('[data-test-input="allowedKubernetesNamespaces"]', '*');
await click('[data-test-save]');
this.validateRoute(assert, 'roles.role.details', 'Transitions to details route on save success');
await click('[data-test-crumb="roles"] a');
assert.dom('[data-test-role="new-test-role"]').exists('New role renders in list');
});

test('it should have functional toolbar actions in details view', async function (assert) {
assert.expect(3);
await this.visitRoles();
await click('[data-test-list-item-link]');
await click('[data-test-generate-credentials]');
this.validateRoute(assert, 'roles.role.credentials', 'Transitions to credentials route');
await click('[data-test-crumb="details"] a');
await click('[data-test-edit]');
this.validateRoute(assert, 'roles.role.edit', 'Transitions to edit route');
await click('[data-test-cancel]');
await click('[data-test-list-item-link]');
await click('[data-test-delete] button');
await click('[data-test-confirm-button]');
assert
.dom('[data-test-list-item-link]')
.exists({ count: 2 }, 'Transitions to roles route and deleted role removed from list');
});

test('it should generate credentials for role', async function (assert) {
assert.expect(1);
await this.visitRoles();
await click('[data-test-list-item-link]');
await click('[data-test-generate-credentials]');
await fillIn('[data-test-kubernetes-namespace]', 'test-namespace');
await click('[data-test-generate-credentials-button]');
await click('[data-test-generate-credentials-done]');
this.validateRoute(
assert,
'roles.role.details',
'Transitions to details route when done generating credentials'
);
});
});