Merge pull request #639 from hashicorp/feature-credential-store-crud-read

Add first iteration of list credential store
This commit is contained in:
Susmitha Girumala authored and GitHub committed 2021-07-12 14:49:48 -04:00
commit 0f73cd5faf
16 files changed
+234 -1

No files matched your search

+8
View File
@@ -456,6 +456,14 @@ export default function () {
return new Response(200);
});
// credential-stores
this.get(
'/credential-stores',
({ credentialStores }, { queryParams: { scope_id: scopeId } }) =>
credentialStores.where({ scopeId })
);
/* Uncomment the following line and the Response import above
* Then change the response code to simulate error responses.
* this.get('/scopes', () => new Response(505));
@@ -267,4 +267,7 @@ target:
add:
title: Add Host Sets
description: Select host sets to assign to this target.
secret: ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■
credential-store:
title: Credential Store
title_plural: Credential Stores
description: A credential stores is a collection of credentials and credential libraries.
@@ -0,0 +1,17 @@
import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
export default class ScopesScopeCredentialStoresController extends Controller {
// =services
@service intl;
// = attributes
/**
* Translated breadcrumb
* @type {string}
*/
get breadCrumb() {
return this.intl.t('resources.credential-store.title_plural');
}
}
+3
View File
@@ -86,6 +86,9 @@ Router.map(function () {
});
});
});
this.route('credential-stores', function () {
this.route('credential-store', { path: ':credential_store_id' });
});
});
});
@@ -0,0 +1,12 @@
import Route from '@ember/routing/route';
export default class ScopesScopeCredentialStoresRoute extends Route {
/**
* Load all credential stores under current scope
* @returns {Promise[CredentialStoreModel]}
*/
async model() {
const { id: scope_id } = this.modelFor('scopes.scope');
return this.store.query('credential-store', { scope_id });
}
}
@@ -0,0 +1,11 @@
import Route from '@ember/routing/route';
export default class ScopesScopeCredentialStoresCredentialStoreRoute extends Route {
/**
* Load a specific credential store in current scope
* @return {Promise[CredentialStoreModel]}
*/
async model({ credential_store_id }) {
return this.route.findRecord('credential-store', credential_store_id);
}
}
@@ -0,0 +1,3 @@
import Route from '@ember/routing/route';
export default class ScopesScopeCredentialStoresIndexRoute extends Route {}
+6
View File
@@ -83,6 +83,12 @@
<Rose::Icon @name='app-icons/host-catalogs' @size='medium' />
{{t 'resources.host-catalog.title_plural'}}
</nav.link>
{{#if (feature-flag 'credential-store')}}
<nav.link @route='scopes.scope.credential-stores'>
<Rose::Icon @name='app-icons/credential' @size='medium' />
{{t 'resources.credential-store.title_plural'}}
</nav.link>
{{/if}}
</Rose::Nav::Sidebar>
{{/if}}
@@ -0,0 +1,3 @@
{{page-title (t 'resources.credential-store.title_plural')}}
{{outlet}}
@@ -0,0 +1,2 @@
{{page-title 'CredentialStore'}}
{{outlet}}
@@ -0,0 +1,65 @@
<Rose::Layout::Page as |page|>
<page.breadcrumbs>
<BreadCrumbs />
</page.breadcrumbs>
<page.header>
<h2>
{{t 'resources.credential-store.title_plural'}}
</h2>
{{t 'resources.credential-store.description'}}
</page.header>
{{!-- <page.actions>
{{#if @model}}
<Rose::LinkButton
@route='scopes.scope.credential-stores.new'
@style='primary'
>
{{t 'titles.new'}}
</Rose::LinkButton>
{{/if}}
</page.actions> --}}
<page.body>
{{#if @model}}
<Rose::Table as |table|>
<table.header as |header|>
<header.row as |row|>
<row.headerCell>{{t 'form.name.label'}}</row.headerCell>
<row.headerCell>{{t 'form.type.label'}}</row.headerCell>
<row.headerCell>{{t 'form.id.label'}}</row.headerCell>
</header.row>
</table.header>
<table.body as |body|>
{{#each @model as |credentialStore|}}
<body.row as |row|>
<row.headerCell>
<LinkTo
@route='scopes.scope.credential-stores.credential-store'
@model={{credentialStore.id}}
>
{{credentialStore.displayName}}
</LinkTo>
<p>{{credentialStore.description}}</p>
</row.headerCell>
<row.cell>
<Rose::Badge>{{credentialStore.type}}</Rose::Badge>
</row.cell>
<row.cell>
<Copyable
@text={{credentialStore.id}}
@buttonText={{t 'actions.copy-to-clipboard'}}
@acknowledgeText={{t 'states.copied'}}
>
<code>{{credentialStore.id}}</code>
</Copyable>
</row.cell>
</body.row>
{{/each}}
</table.body>
</Rose::Table>
{{/if}}
</page.body>
</Rose::Layout::Page>
@@ -0,0 +1,48 @@
import { module, test } from 'qunit';
import { visit, currentURL } from '@ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit';
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
import a11yAudit from 'ember-a11y-testing/test-support/audit';
module('Acceptance | credential-stores', function (hooks) {
setupApplicationTest(hooks);
setupMirage(hooks);
const instances = {
scopes: {
global: null,
org: null,
project: null,
},
};
const urls = {
globalScope: null,
credentialStores: null,
};
hooks.beforeEach(function () {
// Generate resources
instances.scopes.global = this.server.create('scope', { id: 'global' });
instances.scopes.org = this.server.create('scope', {
type: 'org',
scope: { id: 'global', type: 'global' },
});
instances.scopes.project = this.server.create('scope', {
type: 'project',
scope: { id: instances.scopes.org.id, type: 'org' },
});
// Generate route URLs for resources
urls.globalScope = `/scopes/global/scopes`;
urls.orgScope = `/scopes/${instances.scopes.org.id}/scopes`;
urls.projectScope = `/scopes/${instances.scopes.project.id}`;
urls.credentialStores = `${urls.projectScope}/credential-stores`;
});
test('visiting /credential-stores', async function (assert) {
assert.expect(1);
await visit(urls.credentialStores);
await a11yAudit();
assert.equal(currentURL(), urls.credentialStores);
});
});
@@ -0,0 +1,14 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Controller | scopes/scope/credential-stores', function (hooks) {
setupTest(hooks);
// TODO: Replace this with your real tests.
test('it exists', function (assert) {
let controller = this.owner.lookup(
'controller:scopes/scope/credential-stores'
);
assert.ok(controller);
});
});
@@ -0,0 +1,11 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Route | scopes/scope/credential-stores', function (hooks) {
setupTest(hooks);
test('it exists', function (assert) {
let route = this.owner.lookup('route:scopes/scope/credential-stores');
assert.ok(route);
});
});
@@ -0,0 +1,16 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module(
'Unit | Route | scopes/scope/credential-stores/credential-store',
function (hooks) {
setupTest(hooks);
test('it exists', function (assert) {
let route = this.owner.lookup(
'route:scopes/scope/credential-stores/credential-store'
);
assert.ok(route);
});
}
);
@@ -0,0 +1,11 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Route | scopes/scope/credential-stores/index', function (hooks) {
setupTest(hooks);
test('it exists', function (assert) {
let route = this.owner.lookup('route:scopes/scope/credential-stores/index');
assert.ok(route);
});
});