-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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 add custom metadata to KV2 #12169
Changes from 37 commits
7e39250
975f45a
f311c18
e74a728
83322b1
fed0f56
5f26562
5a0cb94
640f8eb
d5e5ed5
dee6798
8ccea40
83af67b
bea9f2a
c1a256a
49006b2
99f92c6
4925c7c
7eb5ec3
fdd079c
053366d
5e2995c
b561af9
0447232
a9e9703
178d163
1c4da5c
fba9597
25e9d45
e95ef3a
d4ece1d
bb00d9b
5ef69fe
73af76c
be143e1
3523651
5eea7df
d6c7543
cd534e3
408000d
643faed
abff87d
89bc486
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
```release-note:feature | ||
ui: Add custom metadata to KV secret engine and metadata to config | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,10 @@ export default ApplicationAdapter.extend({ | |
return path ? url + '/' + encodePath(path) : url; | ||
}, | ||
|
||
urlForConfig(path) { | ||
return `/v1/${path}/config`; | ||
}, | ||
|
||
internalURL(path) { | ||
let url = `/${this.urlPrefix()}/internal/ui/mounts`; | ||
if (path) { | ||
|
@@ -26,15 +30,43 @@ export default ApplicationAdapter.extend({ | |
|
||
createRecord(store, type, snapshot) { | ||
const serializer = store.serializerFor(type.modelName); | ||
const data = serializer.serialize(snapshot); | ||
let data = serializer.serialize(snapshot); | ||
const path = snapshot.attr('path'); | ||
|
||
return this.ajax(this.url(path), 'POST', { data }).then(() => { | ||
// ember data doesn't like 204s if it's not a DELETE | ||
return { | ||
data: assign({}, data, { path: path + '/', id: path }), | ||
}; | ||
}); | ||
// for kv2 we make two network requests | ||
if (data.type === 'kv' && data.options.version !== 1) { | ||
// data has both data for sys mount and the config, we need to separate them | ||
let configData = (({ max_versions, delete_version_after, cas_required }) => ({ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if we can pull out the splitting logic to a helper method so that we can reuse it in other areas (like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good idea. Let me work on that today. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay, created a new helper called split-object |
||
max_versions, | ||
delete_version_after, | ||
cas_required, | ||
}))(data); | ||
// remove extra params from data | ||
/*eslint no-unused-vars: ["error", { "ignoreRestSiblings": true }]*/ | ||
let { max_versions, delete_version_after, cas_required, ...newData } = data; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If any of these are undefined this will blow up, so we just need to make sure the serializer always returns those values even if they're falsey There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe you could help me on this one. In my testing by trying to set all values to falsey I couldn't get it to blow up, but maybe I'm missing something. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If there's no way for those to be undefined, we should be good! Just wanted to call that out as a thing to test with default values for example |
||
data = newData; | ||
// first create the engine | ||
return this.ajax(this.url(path), 'POST', { data }) | ||
.then(() => { | ||
// second modify config on engine | ||
return this.ajax(this.urlForConfig(path), 'POST', { data: configData }); | ||
}) | ||
.then(() => { | ||
// ember data doesn't like 204s if it's not a DELETE | ||
return { | ||
data: assign({}, data, { path: path + '/', id: path }), | ||
}; | ||
}) | ||
.catch(e => { | ||
console.log(e, 'error'); | ||
}); | ||
} else { | ||
return this.ajax(this.url(path), 'POST', { data }).then(() => { | ||
// ember data doesn't like 204s if it's not a DELETE | ||
return { | ||
data: assign({}, data, { path: path + '/', id: path }), | ||
}; | ||
}); | ||
} | ||
}, | ||
|
||
findRecord(store, type, path, snapshot) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,25 @@ | ||
/** | ||
* @module KvObjectEditor | ||
* KvObjectEditor components are called in FormFields when the editType on the model is kv. They are used to show a key-value input field. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added documentation to an older component. |
||
* | ||
* @example | ||
* ```js | ||
* <KvObjectEditor | ||
* @value={{get model valuePath}} | ||
* @onChange={{action "setAndBroadcast" valuePath }} | ||
* @label="some label" | ||
/> | ||
* ``` | ||
* @param {string} value - the value is captured from the model. | ||
* @param {function} onChange - function that captures the value on change | ||
* @param {string} [label] - label displayed over key value inputs | ||
* @param {string} [warning] - warning that is displayed | ||
* @param {string} [helpText] - helper text. In tooltip. | ||
* @param {string} [subText] - placed under label. | ||
* @param {boolean} [small-label]- change label size. | ||
* @param {boolean} [formSection] - if false the component is meant to live outside of a form, like in the customMetadata which is nested already inside a form-section. | ||
*/ | ||
|
||
import { isNone } from '@ember/utils'; | ||
import { assert } from '@ember/debug'; | ||
import Component from '@ember/component'; | ||
|
@@ -7,12 +29,15 @@ import KVObject from 'vault/lib/kv-object'; | |
|
||
export default Component.extend({ | ||
'data-test-component': 'kv-object-editor', | ||
classNames: ['field', 'form-section'], | ||
classNames: ['field'], | ||
classNameBindings: ['formSection:form-section'], | ||
formSection: true, | ||
// public API | ||
// Ember Object to mutate | ||
value: null, | ||
label: null, | ||
helpText: null, | ||
subText: null, | ||
// onChange will be called with the changed Value | ||
onChange() {}, | ||
|
||
|
@@ -65,5 +90,12 @@ export default Component.extend({ | |
data.removeAt(index); | ||
this.onChange(data.toJSON()); | ||
}, | ||
|
||
handleKeyUp(name, value) { | ||
if (!this.onKeyUp) { | ||
return; | ||
} | ||
this.onKeyUp(name, value); | ||
}, | ||
}, | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -108,14 +108,30 @@ export default Component.extend({ | |
|
||
actions: { | ||
onKeyUp(name, value) { | ||
this.mountModel.set('path', value); | ||
this.mountModel.validations.attrs.path.isValid | ||
? set(this.validationMessages, 'path', '') | ||
: set(this.validationMessages, 'path', this.mountModel.validations.attrs.path.message); | ||
|
||
this.mountModel.validate().then(({ validations }) => { | ||
this.set('isFormInvalid', !validations.isValid); | ||
}); | ||
// validate path | ||
if (name === 'path') { | ||
this.mountModel.set('path', value); | ||
this.mountModel.validations.attrs.path.isValid | ||
? set(this.validationMessages, 'path', '') | ||
: set(this.validationMessages, 'path', this.mountModel.validations.attrs.path.message); | ||
|
||
this.mountModel.validate().then(({ validations }) => { | ||
this.set('isFormInvalid', !validations.isValid); | ||
}); | ||
} | ||
// check maxVersions is a number | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add validations for mounting a secret engine. this is relevant for kv2 specifically as we now show maxVersion on the config screen. (we post to both sys/mount and now secret/config) |
||
if (name === 'maxVersions') { | ||
// checking for value because value which is blank on first load. No keyup event has occurred and default is 10. | ||
if (value) { | ||
let number = Number(value); | ||
this.mountModel.set('maxVersions', number); | ||
} | ||
if (!this.mountModel.validations.attrs.maxVersions.isValid) { | ||
set(this.validationMessages, name, this.mountModel.validations.attrs.maxVersions.message); | ||
} else { | ||
set(this.validationMessages, name, ''); | ||
} | ||
} | ||
}, | ||
onTypeChange(path, value) { | ||
if (path === 'type') { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
turned to let because we redefine data after abstracting the values we need for the endpoint.