mirror of
https://github.com/hashicorp/vault.git
synced 2025-11-28 14:11:10 +01:00
new model things for secret-v2 and secret-v2 versions: get list, queryRecord, and version find working
This commit is contained in:
parent
89c6ab6dd6
commit
cae9f6fffe
23
ui/app/adapters/secret-v2-version.js
Normal file
23
ui/app/adapters/secret-v2-version.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { isEmpty } from '@ember/utils';
|
||||||
|
import ApplicationAdapter from './application';
|
||||||
|
|
||||||
|
export default ApplicationAdapter.extend({
|
||||||
|
namespace: 'v1',
|
||||||
|
_url(backend, id) {
|
||||||
|
let url = `${this.buildURL()}/${backend}/data/`;
|
||||||
|
if (!isEmpty(id)) {
|
||||||
|
url = url + id;
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
},
|
||||||
|
|
||||||
|
urlForFindRecord(id) {
|
||||||
|
let [backend, path, version] = JSON.parse(id);
|
||||||
|
return this._url(backend, path) + `?version=${version}`;
|
||||||
|
},
|
||||||
|
|
||||||
|
deleteRecord(store, type, snapshot) {
|
||||||
|
// use adapterOptions to determine if it's delete or destroy for the version
|
||||||
|
return this._super(...arguments);
|
||||||
|
},
|
||||||
|
});
|
||||||
@ -1,34 +1,41 @@
|
|||||||
|
/* eslint-disable */
|
||||||
import { isEmpty } from '@ember/utils';
|
import { isEmpty } from '@ember/utils';
|
||||||
import SecretAdapter from './secret';
|
import ApplicationAdapter from './application';
|
||||||
|
|
||||||
export default SecretAdapter.extend({
|
export default ApplicationAdapter.extend({
|
||||||
createOrUpdate(store, type, snapshot) {
|
namespace: 'v1',
|
||||||
const serializer = store.serializerFor(type.modelName);
|
_url(backend, id) {
|
||||||
const data = serializer.serialize(snapshot);
|
let url = `${this.buildURL()}/${backend}/metadata/`;
|
||||||
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}/`;
|
|
||||||
if (!isEmpty(id)) {
|
if (!isEmpty(id)) {
|
||||||
url = url + id;
|
url = url + id;
|
||||||
}
|
}
|
||||||
return url;
|
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 } });
|
||||||
|
},
|
||||||
|
|
||||||
|
urlForQueryRecord(query) {
|
||||||
let { id, backend } = query;
|
let { id, backend } = query;
|
||||||
let args = [backend, id];
|
return this._url(backend) + id;
|
||||||
if (methodCall === 'query') {
|
},
|
||||||
args.push('metadata');
|
|
||||||
}
|
queryRecord(store, type, query) {
|
||||||
return this.ajax(this.urlForSecret(...args), 'GET', this.optionsForQuery(id, methodCall)).then(resp => {
|
let { backend, id } = query;
|
||||||
|
return this._super(...arguments).then(resp => {
|
||||||
resp.id = id;
|
resp.id = id;
|
||||||
|
resp.backend = backend;
|
||||||
return resp;
|
return resp;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
urlForDeleteRecord(store, type, snapshot) {
|
||||||
|
let backend = snapshot.belongsTo('secret-engine', { id: true });
|
||||||
|
let { id } = snapshot;
|
||||||
|
return this.urlForQueryRecord({ id, backend });
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
8
ui/app/models/secret-v2-version.js
Normal file
8
ui/app/models/secret-v2-version.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import Secret from './secret';
|
||||||
|
import DS from 'ember-data';
|
||||||
|
|
||||||
|
const { attr } = DS;
|
||||||
|
|
||||||
|
export default Secret.extend({
|
||||||
|
version: attr('number'),
|
||||||
|
});
|
||||||
@ -1,3 +1,15 @@
|
|||||||
import Secret from './secret';
|
import Secret from './secret';
|
||||||
|
import DS from 'ember-data';
|
||||||
|
|
||||||
export default Secret.extend();
|
const { attr, hasMany, belongsTo, Model } = DS;
|
||||||
|
|
||||||
|
export default Model.extend({
|
||||||
|
engine: belongsTo('secret-engine'),
|
||||||
|
versions: hasMany('secret-v2-version', { async: false }),
|
||||||
|
createdTime: attr(),
|
||||||
|
updatedTime: attr(),
|
||||||
|
currentVersion: attr('number'),
|
||||||
|
oldestVersion: attr('number'),
|
||||||
|
maxVersions: attr('number'),
|
||||||
|
casRequired: attr('boolean'),
|
||||||
|
});
|
||||||
|
|||||||
@ -72,7 +72,14 @@ export default Route.extend(UnloadModelRoute, {
|
|||||||
secret = secret.replace('cert/', '');
|
secret = secret.replace('cert/', '');
|
||||||
}
|
}
|
||||||
return hash({
|
return hash({
|
||||||
secret: this.store.queryRecord(modelType, { id: secret, backend }),
|
secret: this.store.queryRecord(modelType, { id: secret, backend }).then(resp => {
|
||||||
|
if (modelType === 'secret-v2') {
|
||||||
|
// TODO, find by query param to enable viewing versions
|
||||||
|
let version = resp.versions.findBy('version', resp.currentVersion);
|
||||||
|
version.reload();
|
||||||
|
}
|
||||||
|
return resp;
|
||||||
|
}),
|
||||||
capabilities: this.capabilities(secret),
|
capabilities: this.capabilities(secret),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
25
ui/app/serializers/secret-v2-version.js
Normal file
25
ui/app/serializers/secret-v2-version.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { get } from '@ember/object';
|
||||||
|
import ApplicationSerializer from './application';
|
||||||
|
|
||||||
|
export default ApplicationSerializer.extend({
|
||||||
|
secretDataPath: 'data.data',
|
||||||
|
normalizeItems(payload, requestType) {
|
||||||
|
let path = this.secretDataPath;
|
||||||
|
// move response that is the contents of the secret from the dataPath
|
||||||
|
// to `secret_data` so it will be `secretData` in the model
|
||||||
|
payload.secret_data = get(payload, path);
|
||||||
|
payload = Object.assign({}, payload, payload.data.metadata);
|
||||||
|
delete payload.data;
|
||||||
|
// return the payload if it's expecting a single object or wrap
|
||||||
|
// it as an array if not
|
||||||
|
return payload;
|
||||||
|
},
|
||||||
|
serialize(snapshot) {
|
||||||
|
return {
|
||||||
|
data: snapshot.attr('secretData'),
|
||||||
|
options: {
|
||||||
|
cas: snapshot.attr('currentVerion'),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
@ -1,5 +1,40 @@
|
|||||||
import SecretSerializer from './secret';
|
import ApplicationSerializer from './application';
|
||||||
|
import DS from 'ember-data';
|
||||||
|
|
||||||
export default SecretSerializer.extend({
|
export default ApplicationSerializer.extend(DS.EmbeddedRecordsMixin, {
|
||||||
secretDataPath: 'data.data',
|
attrs: {
|
||||||
|
versions: { embedded: 'always' },
|
||||||
|
},
|
||||||
|
secretDataPath: 'data',
|
||||||
|
normalizeItems(payload, requestType) {
|
||||||
|
if (payload.data.keys && Array.isArray(payload.data.keys)) {
|
||||||
|
// if we have data.keys, it's a list of ids, so we map over that
|
||||||
|
// and create objects with id's
|
||||||
|
return payload.data.keys.map(secret => {
|
||||||
|
// secrets don't have an id in the response, so we need to concat the full
|
||||||
|
// path of the secret here - the id in the payload is added
|
||||||
|
// in the adapter after making the request
|
||||||
|
let fullSecretPath = payload.id ? payload.id + secret : secret;
|
||||||
|
|
||||||
|
// if there is no path, it's a "top level" secret, so add
|
||||||
|
// a unicode space for the id
|
||||||
|
// https://github.com/hashicorp/vault/issues/3348
|
||||||
|
if (!fullSecretPath) {
|
||||||
|
fullSecretPath = '\u0020';
|
||||||
|
}
|
||||||
|
return { id: fullSecretPath };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (payload.data.versions) {
|
||||||
|
payload.data.versions = Object.keys(payload.data.versions).map(version => {
|
||||||
|
let body = payload.data.versions[version];
|
||||||
|
body.version = version;
|
||||||
|
body.id = JSON.stringify([payload.backend, payload.id, version]);
|
||||||
|
return body;
|
||||||
|
});
|
||||||
|
console.log(payload);
|
||||||
|
}
|
||||||
|
payload.data.id = payload.id;
|
||||||
|
return requestType === 'queryRecord' ? payload.data : [payload.data];
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user