Skip to content

Commit

Permalink
Ui kv v2 redux (hashicorp#4393)
Browse files Browse the repository at this point in the history
* remove header used for backwards compatibility in KV mounts, and use v1 paths for v1, v2 paths for v2

* make the model hook always run

* simplify adapter & serializer code for secrets

* update tests

* fix lease tests

* address review feedback
  • Loading branch information
meirish authored Apr 20, 2018
1 parent 9dd993d commit 9b1923a
Show file tree
Hide file tree
Showing 20 changed files with 159 additions and 272 deletions.
61 changes: 0 additions & 61 deletions ui/app/adapters/secret-cubbyhole.js

This file was deleted.

34 changes: 34 additions & 0 deletions ui/app/adapters/secret-v2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import Ember from 'ember';
import SecretAdapter from './secret';

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}/`;
if (!Ember.isEmpty(id)) {
url = url + id;
}
return url;
},

fetchByQuery(query, methodCall) {
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 => {
resp.id = id;
return resp;
});
},
});
47 changes: 11 additions & 36 deletions ui/app/adapters/secret.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,15 @@
import Ember from 'ember';
import ApplicationAdapter from './application';
const { computed } = Ember;

export default ApplicationAdapter.extend({
namespace: 'v1',

headers: computed(function() {
return {
'X-Vault-Kv-Client': 'v2',
};
}),

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 },
});
return this.ajax(this.urlForSecret(snapshot.attr('backend'), id), 'POST', { data });
},

createRecord() {
Expand All @@ -34,8 +25,8 @@ export default ApplicationAdapter.extend({
return this.ajax(this.urlForSecret(snapshot.attr('backend'), id), 'DELETE');
},

urlForSecret(backend, id, infix = 'data') {
let url = `${this.buildURL()}/${backend}/${infix}/`;
urlForSecret(backend, id) {
let url = `${this.buildURL()}/${backend}/`;
if (!Ember.isEmpty(id)) {
url = url + id;
}
Expand All @@ -52,35 +43,19 @@ export default ApplicationAdapter.extend({
return { data };
},

urlForQuery(query) {
let { id, backend } = query;
return this.urlForSecret(backend, id, 'metadata');
},

urlForQueryRecord(query) {
let { id, backend } = query;
return this.urlForSecret(backend, id);
fetchByQuery(query, action) {
const { id, backend } = query;
return this.ajax(this.urlForSecret(backend, id), 'GET', this.optionsForQuery(id, action)).then(resp => {
resp.id = id;
return resp;
});
},

query(store, type, query) {
return this.ajax(
this.urlForQuery(query, type.modelName),
'GET',
this.optionsForQuery(query.id, 'query')
).then(resp => {
resp.id = query.id;
return resp;
});
return this.fetchByQuery(query, 'query');
},

queryRecord(store, type, query) {
return this.ajax(
this.urlForQueryRecord(query, type.modelName),
'GET',
this.optionsForQuery(query.id, 'queryRecord')
).then(resp => {
resp.id = query.id;
return resp;
});
return this.fetchByQuery(query, 'queryRecord');
},
});
File renamed without changes.
7 changes: 4 additions & 3 deletions ui/app/routes/vault/cluster/secrets/backend/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ var SecretProxy = Ember.Object.extend(KeyMixin, {

createRecord(backend) {
let modelType = 'secret';
if (backend === 'cubbyhole') {
modelType = modelType + '-cubbyhole';
let backendModel = this.store.peekRecord('secret-engine', backend);
if (backendModel.get('type') === 'kv' && backendModel.get('options.version') === 2) {
modelType = 'secret-v2';
}
return this.store.createRecord(modelType, this.toModel());
},
Expand All @@ -25,7 +26,7 @@ export default EditBase.extend({
if (modelType === 'role-ssh') {
return this.store.createRecord(modelType, { keyType: 'ca' });
}
if (modelType !== 'secret' && modelType !== 'secret-cubbyhole') {
if (modelType !== 'secret' && modelType !== 'secret-v2') {
return this.store.createRecord(modelType);
}
const key = transition.queryParams.initialKey || '';
Expand Down
69 changes: 38 additions & 31 deletions ui/app/routes/vault/cluster/secrets/backend/list.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,41 +28,47 @@ export default Ember.Route.extend({
},

getModelType(backend, tab) {
const types = {
let types = {
transit: 'transit-key',
ssh: 'role-ssh',
aws: 'role-aws',
cubbyhole: 'secret-cubbyhole',
pki: tab === 'certs' ? 'pki-certificate' : 'role-pki',
};
const backendModel = this.store.peekRecord('secret-engine', backend);
return types[backendModel.get('type')] || 'secret';
let backendModel = this.store.peekRecord('secret-engine', backend);
let defaultType = 'secret';
if (backendModel.get('type') === 'kv' && backendModel.get('options.version') === 2) {
defaultType = 'secret-v2';
}
return types[backendModel.get('type')] || defaultType;
},

model(params) {
const secret = params.secret ? params.secret : '';
const { backend } = this.paramsFor('vault.cluster.secrets.backend');
const backends = this.modelFor('vault.cluster.secrets').mapBy('id');
return this.store
.lazyPaginatedQuery(this.getModelType(backend, params.tab), {
id: secret,
backend,
responsePath: 'data.keys',
page: params.page,
pageFilter: params.pageFilter,
size: 100,
})
.then(model => {
this.set('has404', false);
return model;
})
.catch(err => {
if (backends.includes(backend) && err.httpStatus === 404 && secret === '') {
return [];
} else {
throw err;
}
});
return Ember.RSVP.hash({
secret,
secrets: this.store
.lazyPaginatedQuery(this.getModelType(backend, params.tab), {
id: secret,
backend,
responsePath: 'data.keys',
page: params.page,
pageFilter: params.pageFilter,
size: 100,
})
.then(model => {
this.set('has404', false);
return model;
})
.catch(err => {
if (backends.includes(backend) && err.httpStatus === 404 && secret === '') {
return [];
} else {
throw err;
}
}),
});
},

afterModel(model) {
Expand Down Expand Up @@ -90,19 +96,20 @@ export default Ember.Route.extend({
);
},

setupController(controller, model) {
const secretParams = this.paramsFor(this.routeName);
const secret = secretParams.secret ? secretParams.secret : '';
const { backend } = this.paramsFor('vault.cluster.secrets.backend');
const backendModel = this.store.peekRecord('secret-engine', backend);
const has404 = this.get('has404');
setupController(controller, resolvedModel) {
let secretParams = this.paramsFor(this.routeName);
let secret = resolvedModel.secret;
let model = resolvedModel.secrets;
let { backend } = this.paramsFor('vault.cluster.secrets.backend');
let backendModel = this.store.peekRecord('secret-engine', backend);
let has404 = this.get('has404');
controller.set('hasModel', true);
controller.setProperties({
model,
baseKey: { id: secret },
has404,
backend,
backendModel,
baseKey: { id: secret },
backendType: backendModel.get('type'),
});
if (!has404) {
Expand Down
10 changes: 7 additions & 3 deletions ui/app/routes/vault/cluster/secrets/backend/secret-edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,18 @@ export default Ember.Route.extend(UnloadModelRoute, {
},

modelType(backend, secret) {
const models = {
let types = {
transit: 'transit-key',
ssh: 'role-ssh',
aws: 'role-aws',
cubbyhole: 'secret-cubbyhole',
pki: secret && secret.startsWith('cert/') ? 'pki-certificate' : 'role-pki',
};
return models[this.backendType(backend)] || 'secret';
let backendModel = this.store.peekRecord('secret-engine', backend);
let defaultType = 'secret';
if (backendModel.get('type') === 'kv' && backendModel.get('options.version') === 2) {
defaultType = 'secret-v2';
}
return types[backendModel.get('type')] || defaultType;
},

model(params) {
Expand Down
2 changes: 1 addition & 1 deletion ui/app/serializers/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default DS.JSONSerializer.extend({
},

normalizeResponse(store, primaryModelClass, payload, id, requestType) {
const responseJSON = this.normalizeItems(payload);
const responseJSON = this.normalizeItems(payload, requestType);
if (id && !responseJSON.id) {
responseJSON.id = id;
}
Expand Down
42 changes: 0 additions & 42 deletions ui/app/serializers/secret-cubbyhole.js

This file was deleted.

5 changes: 5 additions & 0 deletions ui/app/serializers/secret-v2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import SecretSerializer from './secret';

export default SecretSerializer.extend({
secretDataPath: 'data.data',
});
Loading

0 comments on commit 9b1923a

Please sign in to comment.