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 - support for kv v2 #5547

Merged
merged 40 commits into from
Oct 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
89c6ab6
don't leave new lines on the end of files
meirish Oct 4, 2018
cae9f6f
new model things for secret-v2 and secret-v2 versions: get list, quer…
meirish Oct 4, 2018
3bd0250
get rid of v2 incomplete warning
meirish Oct 4, 2018
7e09c69
move to es5 getter usage for csp service
meirish Oct 6, 2018
f31b7f9
user correct rule for eol
meirish Oct 6, 2018
14a410e
fix navigate component
meirish Oct 6, 2018
7e295b9
finish v2 model layer and add some unit tests for adapters
meirish Oct 6, 2018
33d1f32
move secret creation to always be at the root level, and simplify mod…
meirish Oct 6, 2018
4dce167
adjust secret-edit component and associated templates to work for v1 …
meirish Oct 6, 2018
564942d
fix linting
meirish Oct 8, 2018
988e017
less get in secret-edit
meirish Oct 8, 2018
8df0b99
blue toggle switch
meirish Oct 9, 2018
d057ba1
move capabilities into the secret-edit component
meirish Oct 9, 2018
69c8a12
use new local capabilities, move secret-edit-display partial to a com…
meirish Oct 9, 2018
15bf566
add new icon
meirish Oct 10, 2018
7652427
add block-error and block-empty components to centralize some bulma m…
meirish Oct 10, 2018
66a4c26
extract list-header css component to match header from namespace-picker
meirish Oct 10, 2018
5d3c576
make delete, destory, undelete work via the ui
meirish Oct 10, 2018
ffee108
fix padding on masked-input and web cli
meirish Oct 10, 2018
f36b9da
fix error with namespaces by reloading, new switch styles
meirish Oct 10, 2018
32b19ad
load and view different secret versions
meirish Oct 11, 2018
aa1859f
fix styling and only focus input type=text
meirish Oct 11, 2018
e5ff929
create version from old versions uses that data in the edit page
meirish Oct 11, 2018
077f366
use model dirty tracking to track changes
meirish Oct 15, 2018
59280ef
use cas when saving secret version
meirish Oct 15, 2018
712e3e7
add secret metadata editing and fix v1 links
meirish Oct 15, 2018
f7643a5
add in secret metadata form for create
meirish Oct 16, 2018
5c8a71b
fix metadata save on creation and use autocomplete=off for inputs
meirish Oct 17, 2018
940b69b
move key mixin to the mixin dir and update imports - also use it in s…
meirish Oct 17, 2018
5d44827
special case backend attr on the secret v1 model
meirish Oct 17, 2018
963c863
fix tests
meirish Oct 17, 2018
3ffaf53
add warning if you're creating a new version with old versions data
meirish Oct 17, 2018
59eb616
use maybeQueryRecord in lazyCapabilities macro and only continue if p…
meirish Oct 18, 2018
69c5df8
use backend / secretId in models created on list responses for secret…
meirish Oct 18, 2018
d02fcd0
add necessary computed macros and template for contextual menus for v…
meirish Oct 18, 2018
d827f26
redirect to list-root after deleting a secret from the list page
meirish Oct 18, 2018
fff6639
also send reload in case we're on the root already
meirish Oct 18, 2018
24b0e2d
check capabilities for version actions
meirish Oct 18, 2018
0d91d85
more 'not allowed' messaging
meirish Oct 18, 2018
e01d050
isPending not isLoading
meirish Oct 18, 2018
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 ui/app/adapters/capabilities.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ export default ApplicationAdapter.extend({

queryRecord(store, type, query) {
const { id } = query;
if (!id) {
return;
}
return this.findRecord(store, type, id).then(resp => {
resp.path = id;
return resp;
Expand Down
72 changes: 72 additions & 0 deletions ui/app/adapters/secret-v2-version.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/* eslint-disable */
import { isEmpty } from '@ember/utils';
import { get } from '@ember/object';
import ApplicationAdapter from './application';
import DS from 'ember-data';

export default ApplicationAdapter.extend({
namespace: 'v1',
_url(backend, id, infix = 'data') {
let url = `${this.buildURL()}/${backend}/${infix}/`;
if (!isEmpty(id)) {
url = url + id;
}
return url;
},

urlForFindRecord(id) {
let [backend, path, version] = JSON.parse(id);
return this._url(backend, path) + `?version=${version}`;
},

findRecord() {
return this._super(...arguments).catch(errorOrModel => {
// if it's a real 404, this will be an error, if not
// it will be the body of a deleted / destroyed version
if (errorOrModel instanceof DS.AdapterError) {
throw errorOrModel;
}
return errorOrModel;
});
},

urlForCreateRecord(modelName, snapshot) {
let backend = snapshot.belongsTo('secret').belongsTo('engine').id;
let path = snapshot.attr('path');
return this._url(backend, path);
},

createRecord(store, modelName, snapshot) {
let backend = snapshot.belongsTo('secret').belongsTo('engine').id;
let path = snapshot.attr('path');
return this._super(...arguments).then(resp => {
resp.id = JSON.stringify([backend, path, resp.version]);
return resp;
});
},

urlForUpdateRecord(id) {
let [backend, path] = JSON.parse(id);
return this._url(backend, path);
},

v2DeleteOperation(store, id, deleteType = 'delete') {
let [backend, path, version] = JSON.parse(id);

// deleteType should be 'delete', 'destroy', 'undelete'
return this.ajax(this._url(backend, path, deleteType), 'POST', { data: { versions: [version] } }).then(
() => {
let model = store.peekRecord('secret-v2-version', id);
return model && model.reload();
}
);
},

handleResponse(status, headers, payload, requestData) {
// the body of the 404 will have some relevant information
if (status === 404 && get(payload, 'data.metadata')) {
return this._super(200, headers, payload, requestData);
}
return this._super(...arguments);
},
});
61 changes: 41 additions & 20 deletions ui/app/adapters/secret-v2.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,55 @@
/* eslint-disable */
import { isEmpty } from '@ember/utils';
import SecretAdapter from './secret';
import ApplicationAdapter from './application';

export default SecretAdapter.extend({
createOrUpdate(store, type, snapshot) {
const serializer = store.serializerFor(type.modelName);
const data = serializer.serialize(snapshot);
const { id } = snapshot;

return this.ajax(this.urlForSecret(snapshot.attr('backend'), id), 'POST', {
data: { data },
});
},

urlForSecret(backend, id, infix = 'data') {
let url = `${this.buildURL()}/${backend}/${infix}/`;
export default ApplicationAdapter.extend({
namespace: 'v1',
_url(backend, id) {
let url = `${this.buildURL()}/${backend}/metadata/`;
if (!isEmpty(id)) {
url = url + id;
}
return url;
},

fetchByQuery(query, methodCall) {
// we override query here because the query object has a bunch of client-side
// concerns and we only want to send "list" to the server
query(store, type, query) {
let { backend, id } = query;
return this.ajax(this._url(backend, id), 'GET', { data: { list: true } }).then(resp => {
resp.id = id;
resp.backend = backend;
return resp;
});
},

urlForQueryRecord(query) {
let { id, backend } = query;
let args = [backend, id];
if (methodCall === 'query') {
args.push('metadata');
}
return this.ajax(this.urlForSecret(...args), 'GET', this.optionsForQuery(id, methodCall)).then(resp => {
return this._url(backend, id);
},

queryRecord(store, type, query) {
let { backend, id } = query;
return this.ajax(this._url(backend, id), 'GET').then(resp => {
resp.id = id;
resp.backend = backend;
return resp;
});
},

detailURL(snapshot) {
let backend = snapshot.belongsTo('engine', { id: true }) || snapshot.attr('engineId');
let { id } = snapshot;
return this._url(backend, id);
},

urlForUpdateRecord(store, type, snapshot) {
return this.detailURL(snapshot);
},
urlForCreateRecord(modelName, snapshot) {
return this.detailURL(snapshot);
},
urlForDeleteRecord(store, type, snapshot) {
return this.detailURL(snapshot);
},
});
1 change: 1 addition & 0 deletions ui/app/adapters/secret.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export default ApplicationAdapter.extend({
const { id, backend } = query;
return this.ajax(this.urlForSecret(backend, id), 'GET', this.optionsForQuery(id, action)).then(resp => {
resp.id = id;
resp.backend = backend;
return resp;
});
},
Expand Down
2 changes: 2 additions & 0 deletions ui/app/components/block-empty.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import OuterHTML from './outer-html';
export default OuterHTML.extend();
2 changes: 2 additions & 0 deletions ui/app/components/block-error.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import OuterHTML from './outer-html';
export default OuterHTML.extend();
1 change: 1 addition & 0 deletions ui/app/components/i-con.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const GLYPHS_WITH_SVG_TAG = [
'edition-oss',
'check-plain',
'check-circle-fill',
'cancel-square-outline',
];

export default Component.extend({
Expand Down
3 changes: 2 additions & 1 deletion ui/app/components/namespace-picker.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ export default Component.extend({
fetchListCapability: task(function*() {
try {
if (this.listCapability) {
this.listCapability.unloadRecord();
yield this.listCapability.reload();
return;
}
let capability = yield this.store.findRecord('capabilities', 'sys/namespaces/');
this.set('listCapability', capability);
Expand Down
8 changes: 4 additions & 4 deletions ui/app/components/navigate-input.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,7 @@ export default Component.extend(FocusOnInsertMixin, {
},

actions: {
handleInput: function(event) {
var filter = event.target.value;
handleInput: function(filter) {
this.get('filterDidChange')(filter);
debounce(this, 'filterUpdated', filter, 200);
},
Expand All @@ -173,14 +172,15 @@ export default Component.extend(FocusOnInsertMixin, {
this.get('filterFocusDidChange')(isFocused);
},

handleKeyPress: function(val, event) {
handleKeyPress: function(event) {
if (event.keyCode === keys.TAB) {
this.onTab(event);
}
},

handleKeyUp: function(val, event) {
handleKeyUp: function(event) {
var keyCode = event.keyCode;
let val = event.target.value;
if (keyCode === keys.ENTER) {
this.onEnter(val);
}
Expand Down
Loading