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

Dynamic OpenAPI UI #6209

Merged
merged 103 commits into from
Feb 14, 2019
Merged
Show file tree
Hide file tree
Changes from 97 commits
Commits
Show all changes
103 commits
Select commit Hold shift + click to select a range
d4667de
ping openapi and grab current model
Jan 15, 2019
0faf738
add debugger statements to figure out order of operations
Jan 16, 2019
64962a3
block in model generation strategy
meirish Jan 18, 2019
f150cee
make sure all form fields appear correctly for pki
Jan 23, 2019
ceed82f
hook up openapi for pki certificates
Jan 23, 2019
3e3ad11
hook up adding new fields for ssh roles
Jan 24, 2019
4abfc3d
combine fields and fieldgroups for aws, pki, ssh
Jan 28, 2019
71e764a
add flag to ignore openAPI if we only want the ones listed in the model
Jan 29, 2019
fe41675
add display names to pki
andaley Jan 29, 2019
196dcff
Add fields to support UI/display uses, along with OpenAPI mappings
Jan 16, 2019
a804c2c
wip - add pki
andaley Jan 29, 2019
1319bda
include new openAPI attributes, fix integer/number attr confusion
Jan 29, 2019
13172fd
add ldap auth
andaley Jan 29, 2019
ef21253
ping openapi and grab current model
Jan 15, 2019
e40df94
add debugger statements to figure out order of operations
Jan 16, 2019
7b10e5c
block in model generation strategy
meirish Jan 18, 2019
312acfa
make sure all form fields appear correctly for pki
Jan 23, 2019
4a11f69
hook up openapi for pki certificates
Jan 23, 2019
c6be8d5
hook up adding new fields for ssh roles
Jan 24, 2019
679a252
combine fields and fieldgroups for aws, pki, ssh
Jan 28, 2019
6e75002
add flag to ignore openAPI if we only want the ones listed in the model
Jan 29, 2019
2d947be
add display names to pki
andaley Jan 29, 2019
7b7fcd3
wip - add pki
andaley Jan 29, 2019
79dd45e
add ldap auth
andaley Jan 29, 2019
1762535
Merge branch 'openapi-models' of https://github.com/hashicorp/vault i…
andaley Jan 29, 2019
cf04a64
fix conflicts
Jan 30, 2019
5adad21
make ssh work without adding in new fields
Jan 30, 2019
82c85aa
remove cruft from role-pki
Jan 30, 2019
f175745
update api fields for pki certs
Jan 30, 2019
0302729
Merge branch 'master' into openapi-models
madalynrose Jan 30, 2019
15a8fad
handle url building for auth configs
andaley Jan 30, 2019
7d4eb59
finish ldap auth and handle url building for auth configs
andaley Jan 30, 2019
87dc76b
Merge branch 'openapi-models' of https://github.com/hashicorp/vault i…
andaley Jan 31, 2019
d222330
Merge branch 'master' into openapi-models
madalynrose Jan 31, 2019
aacf42c
add github auth backend
andaley Jan 31, 2019
9ce5229
create utils for combining fields and fieldGroups to reuse in models
Jan 31, 2019
abbeaaf
merge master
Jan 31, 2019
cbd08f1
fix combineFieldGroups util
andaley Jan 31, 2019
743c1ca
create newModel generator in pathHelp so we minimize duplicated code …
Jan 31, 2019
ebfe43e
use getNewModel for credentials, clean up secret-edit
Jan 31, 2019
91394fc
Merge branch 'master' into openapi-models
madalynrose Jan 31, 2019
66a17e1
add okta auth
andaley Jan 31, 2019
e964604
add okta fields to backend
andaley Feb 1, 2019
e5bdd21
add DisplayName to included TokenFields
andaley Feb 1, 2019
3905b29
Merge branch 'master' into openapi-models
madalynrose Feb 1, 2019
b04ffd5
add radius backend
andaley Feb 1, 2019
a87e2b6
Merge branch 'openapi-models' of https://github.com/hashicorp/vault i…
andaley Feb 1, 2019
22b872b
add certs auth backend
andaley Feb 1, 2019
b5e542b
Merge branch 'master' of https://github.com/hashicorp/vault into open…
andaley Feb 1, 2019
6b2f611
add certs auth backend and fix enabling github
andaley Feb 1, 2019
ad43ac4
start adding gcp auth backend
andaley Feb 1, 2019
7acae32
start adding azure auth backend
andaley Feb 1, 2019
922176d
start adding kubernetes auth backend
andaley Feb 1, 2019
f9b8295
Merge branch 'master' of github.com:hashicorp/vault into openapi-models
Feb 4, 2019
6b0c855
clean up eslint issues, fix useOpenApi usage in models/pathHelp
Feb 4, 2019
22456be
fix openAPI implementation, check for newFields not newFields.length,…
Feb 4, 2019
4b7dcc0
fix stringlist in forms to still include attr.name, adjust path-help …
Feb 4, 2019
37da5c3
fix auth config tests by passing in path instead of backend type
Feb 5, 2019
3a13bb3
redirect to config page after enabling an auth method
andaley Feb 5, 2019
d357a56
fix inverse relationship bug
Feb 5, 2019
6785231
solidify new auth flow
Feb 5, 2019
196b97d
fix ssh field label
andaley Feb 6, 2019
621039d
remove debugger statements
andaley Feb 6, 2019
75e4807
fix auth enable test
andaley Feb 6, 2019
11be1a4
have auth config redirect to list of mounts on successful save
Feb 7, 2019
af0b0f8
redirect when saving method options too
Feb 7, 2019
b0a153e
move redirect functonality back into components instead of the contro…
Feb 7, 2019
1ed2ac7
transition wizard when saving config
Feb 7, 2019
e7ae6a3
fix ssh list route
andaley Feb 7, 2019
452cea2
Merge branch 'openapi-models' of https://github.com/hashicorp/vault i…
andaley Feb 7, 2019
8c85705
fix unit tests
Feb 7, 2019
26e09cf
Merge branch 'openapi-models' of github.com:hashicorp/vault into open…
Feb 7, 2019
254237f
fix broken auth section test
andaley Feb 8, 2019
8d708b7
Merge branch 'openapi-models' of https://github.com/hashicorp/vault i…
andaley Feb 8, 2019
f049bc2
get ssh working
Feb 8, 2019
5e3f6b8
actually make ssh tests pass
Feb 8, 2019
452cf89
fix eslint error for unused variable
Feb 11, 2019
ea2052a
Merge branch 'master' into openapi-models
madalynrose Feb 11, 2019
07b7ad9
pull just frontend commits from openapi-models
Feb 11, 2019
18fa66a
remove debugger statement
Feb 11, 2019
5ed8710
Pull in updated plugins
jefferai Feb 12, 2019
f254246
Bump versions for release
jefferai Feb 12, 2019
85909e3
Cut version 1.0.3
jefferai Feb 12, 2019
04d0589
changelog++
briankassouf Feb 12, 2019
144e200
changelog++
briankassouf Feb 12, 2019
2cc38dd
Update transit docs
vishalnayak Feb 12, 2019
94106d5
add tests for openapi util
Feb 12, 2019
cad1052
Merge branch 'master' into openapi-models-ui
madalynrose Feb 12, 2019
0e741c9
Merge branch '1.1-beta' into openapi-models-ui
madalynrose Feb 12, 2019
6a30cb2
remote pathForType from pki cert adapter, add more test cases for ope…
Feb 12, 2019
7a728fb
Merge branch 'openapi-models-ui' of github.com:hashicorp/vault into o…
Feb 12, 2019
632189d
remove unnecessary lines per Matthew's review
Feb 13, 2019
ca1b124
move openAPI path information into the model so the service doesn't n…
Feb 13, 2019
3584c3e
remove all config from mount backend form
Feb 13, 2019
1785029
use try/catch in tasks instead of promises
Feb 13, 2019
f55e118
clean up roles
Feb 13, 2019
38333de
update openapi helper to use default as a fallback for defaultValue
Feb 14, 2019
656a63e
remove debugger
Feb 14, 2019
7311280
move routing and wizard stuff out of try/catch block for saving auth …
Feb 14, 2019
bc6ad9b
fix string concat in template
Feb 14, 2019
257bb7f
add comment about why we're still setting keyType for ssh role
Feb 14, 2019
132ce02
add a couple more test cases
Feb 14, 2019
b259aa6
grab path dynamically instead of declaring it in models
Feb 14, 2019
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
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## Next
## 1.0.3 (February 12th, 2019)

CHANGES:

Expand All @@ -9,6 +9,11 @@ CHANGES:
entity either by name or by id [GH-6105]
* The Vault UI's navigation and onboarding wizard now only displays items that
are permitted in a users' policy [GH-5980, GH-6094]
* An issue was fixed that caused recovery keys to not work on secondary
clusters when using a different unseal mechanism/key than the primary. This
would be hit if the cluster was rekeyed or initialized after 1.0. We recommend
rekeying the recovery keys on the primary cluster if you meet the above
requirements.

FEATURES:

Expand Down Expand Up @@ -47,6 +52,8 @@ BUG FIXES:
a performance standby very quickly, before an associated entity has been
replicated. If the entity is not found in this scenario, the request will
forward to the active node.
* replication: Fix issue where recovery keys would not work on secondary
clusters if using a different unseal mechanism than the primary.
* replication: Fix a "failed to register lease" error when using performance
standbys
* storage/postgresql: The `Get` method will now return an Entry object with
Expand Down
2 changes: 1 addition & 1 deletion terraform/aws/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//-------------------------------------------------------------------

variable "download-url" {
default = "https://releases.hashicorp.com/vault/1.0.2/vault_1.0.2_linux_amd64.zip"
default = "https://releases.hashicorp.com/vault/1.0.3/vault_1.0.3_linux_amd64.zip"
description = "URL to download Vault"
}

Expand Down
1 change: 1 addition & 0 deletions ui/app/adapters/auth-config/azure.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
import AuthConfig from './_base';

export default AuthConfig.extend();
1 change: 1 addition & 0 deletions ui/app/adapters/auth-config/gcp.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
import AuthConfig from './_base';

export default AuthConfig.extend();
1 change: 1 addition & 0 deletions ui/app/adapters/auth-config/github.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
import AuthConfig from './_base';

export default AuthConfig.extend();
1 change: 1 addition & 0 deletions ui/app/adapters/auth-config/kubernetes.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
import AuthConfig from './_base';

export default AuthConfig.extend();
1 change: 1 addition & 0 deletions ui/app/adapters/auth-config/ldap.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
import AuthConfig from './_base';

export default AuthConfig.extend();
1 change: 1 addition & 0 deletions ui/app/adapters/auth-config/okta.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
import AuthConfig from './_base';

export default AuthConfig.extend();
1 change: 1 addition & 0 deletions ui/app/adapters/auth-config/radius.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
import AuthConfig from './_base';

export default AuthConfig.extend();
4 changes: 4 additions & 0 deletions ui/app/adapters/pki-certificate-sign.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,8 @@ export default Adapter.extend({
}
return `/v1/${role.backend}/sign/${role.name}`;
},

pathForType() {
return 'sign';
},
});
1 change: 0 additions & 1 deletion ui/app/adapters/pki-certificate.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ export default Adapter.extend({
}
return url;
},

optionsForQuery(id) {
let data = {};
if (!id) {
Expand Down
14 changes: 9 additions & 5 deletions ui/app/adapters/secret-engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,20 @@ export default ApplicationAdapter.extend({
return path ? url + '/' + path : url;
},

internalURL(path) {
let url = `/${this.urlPrefix()}/internal/ui/mounts`;
if (path) {
url = `${url}/${path}`;
}
return url;
},

pathForType() {
return 'mounts';
},

query(store, type, query) {
let url = `/${this.urlPrefix()}/internal/ui/mounts`;
if (query.path) {
url = `${url}/${query.path}`;
}
return this.ajax(url, 'GET');
return this.ajax(this.internalURL(query.path), 'GET');
},

createRecord(store, type, snapshot) {
Expand Down
4 changes: 4 additions & 0 deletions ui/app/adapters/secret.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ export default ApplicationAdapter.extend({
return url;
},

pathForType() {
return 'mounts';
},

optionsForQuery(id, action, wrapTTL) {
let data = {};
if (action === 'query') {
Expand Down
11 changes: 8 additions & 3 deletions ui/app/components/auth-config-form/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,16 @@ const AuthConfigBase = Component.extend({
model: null,

flashMessages: service(),

router: service(),
wizard: service(),
saveModel: task(function*() {
try {
yield this.get('model').save();
yield this.model.save();
if (this.wizard.currentMachine === 'authentication' && this.wizard.featureState === 'config') {
madalynrose marked this conversation as resolved.
Show resolved Hide resolved
this.wizard.transitionFeatureMachine(this.wizard.featureState, 'CONTINUE');
}
this.router.transitionTo('vault.cluster.access.methods').followRedirects();
this.flashMessages.success('The configuration was saved successfully.');
} catch (err) {
// AdapterErrors are handled by the error-message component
// in the form
Expand All @@ -20,7 +26,6 @@ const AuthConfigBase = Component.extend({
}
return;
}
this.get('flashMessages').success('The configuration was saved successfully.');
}),
});

Expand Down
16 changes: 11 additions & 5 deletions ui/app/components/auth-config-form/options.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import AuthConfigComponent from './config';
import { inject as service } from '@ember/service';
import { task } from 'ember-concurrency';
import DS from 'ember-data';

export default AuthConfigComponent.extend({
router: service(),
wizard: service(),
saveModel: task(function*() {
const model = this.get('model');
let data = model.get('config').serialize();
data.description = model.get('description');
let data = this.model.config.serialize();
data.description = this.model.description;
try {
yield model.tune(data);
yield this.model.tune(data);
if (this.wizard.currentMachine === 'authentication' && this.wizard.featureState === 'config') {
this.wizard.transitionFeatureMachine(this.wizard.featureState, 'CONTINUE');
}
this.router.transitionTo('vault.cluster.access.methods').followRedirects();
this.flashMessages.success('The configuration was saved successfully.');
} catch (err) {
// AdapterErrors are handled by the error-message component
// in the form
Expand All @@ -17,6 +24,5 @@ export default AuthConfigComponent.extend({
}
return;
}
this.get('flashMessages').success('The configuration options were saved successfully.');
}),
});
118 changes: 18 additions & 100 deletions ui/app/components/mount-backend-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ export default Component.extend({
*
*/
onMountSuccess() {},
onConfigError() {},
/*
* @param String
* @public
Expand All @@ -41,63 +40,29 @@ export default Component.extend({
*/
mountModel: null,

showConfig: false,
showEnable: false,

init() {
this._super(...arguments);
const type = this.get('mountType');
const type = this.mountType;
const modelType = type === 'secret' ? 'secret-engine' : 'auth-method';
const model = this.get('store').createRecord(modelType);
const model = this.store.createRecord(modelType);
this.set('mountModel', model);
},

mountTypes: computed('mountType', function() {
return this.get('mountType') === 'secret' ? ENGINES : METHODS;
return this.mountType === 'secret' ? ENGINES : METHODS;
}),

willDestroy() {
// if unsaved, we want to unload so it doesn't show up in the auth mount list
this.get('mountModel').rollbackAttributes();
},

getConfigModelType(methodType) {
let mountType = this.get('mountType');
// will be something like secret-aws
// or auth-azure
let key = `${mountType}-${methodType}`;
let noConfig = ['auth-approle', 'auth-alicloud'];
if (mountType === 'secret' || noConfig.includes(key)) {
return;
}
if (methodType === 'aws') {
return 'auth-config/aws/client';
}
return `auth-config/${methodType}`;
},

changeConfigModel(methodType) {
madalynrose marked this conversation as resolved.
Show resolved Hide resolved
let mount = this.get('mountModel');
if (this.get('mountType') === 'secret') {
return;
}
let configRef = mount.hasMany('authConfigs').value();
let currentConfig = configRef && configRef.get('firstObject');
if (currentConfig) {
// rollbackAttributes here will remove the the config model from the store
// because `isNew` will be true
currentConfig.rollbackAttributes();
currentConfig.unloadRecord();
}
let configType = this.getConfigModelType(methodType);
if (!configType) return;
let config = this.get('store').createRecord(configType);
config.set('backend', mount);
},

checkPathChange(type) {
let mount = this.get('mountModel');
let currentPath = mount.get('path');
let list = this.get('mountTypes');
let mount = this.mountModel;
let currentPath = mount.path;
let list = this.mountTypes;
// if the current path matches a type (meaning the user hasn't altered it),
// change it here to match the new type
let isUnchanged = list.findBy('type', currentPath);
Expand All @@ -107,7 +72,7 @@ export default Component.extend({
},

mountBackend: task(function*() {
const mountModel = this.get('mountModel');
const mountModel = this.mountModel;
const { type, path } = mountModel.getProperties('type', 'path');
try {
yield mountModel.save();
Expand All @@ -116,74 +81,27 @@ export default Component.extend({
return;
}

let mountType = this.get('mountType');
let mountType = this.mountType;
mountType = mountType === 'secret' ? `${mountType}s engine` : `${mountType} method`;
this.get('flashMessages').success(`Successfully mounted the ${type} ${mountType} at ${path}.`);
if (this.get('mountType') === 'secret') {
yield this.get('onMountSuccess')(type, path);
return;
}
yield this.get('saveConfig').perform(mountModel);
}).drop(),

advanceWizard() {
this.get('wizard').transitionFeatureMachine(
this.get('wizard.featureState'),
'CONTINUE',
this.get('mountModel').get('type')
);
},
saveConfig: task(function*(mountModel) {
const configRef = mountModel.hasMany('authConfigs').value();
const { type, path } = mountModel.getProperties('type', 'path');
if (!configRef) {
this.advanceWizard();
yield this.get('onMountSuccess')(type, path);
return;
}
const config = configRef.get('firstObject');
try {
if (config && Object.keys(config.changedAttributes()).length) {
yield config.save();
this.advanceWizard();
this.get('flashMessages').success(
`The config for ${type} ${this.get('mountType')} method at ${path} was saved successfully.`
);
}
yield this.get('onMountSuccess')(type, path);
} catch (err) {
this.get('flashMessages').danger(
`There was an error saving the configuration for ${type} ${this.get(
'mountType'
)} method at ${path}. ${err.errors.join(' ')}`
);
yield this.get('onConfigError')(mountModel.id);
}
this.flashMessages.success(`Successfully mounted the ${type} ${mountType} at ${path}.`);
yield this.onMountSuccess(type, path);
return;
}).drop(),

actions: {
onTypeChange(path, value) {
if (path === 'type') {
this.get('wizard').set('componentState', value);
this.changeConfigModel(value);
this.wizard.set('componentState', value);
this.checkPathChange(value);
}
},

toggleShowConfig(value) {
this.set('showConfig', value);
if (value === true && this.get('wizard.featureState') === 'idle') {
this.get('wizard').transitionFeatureMachine(
this.get('wizard.featureState'),
'CONTINUE',
this.get('mountModel').get('type')
);
toggleShowEnable(value) {
this.set('showEnable', value);
if (value === true && this.wizard.featureState === 'idle') {
this.wizard.transitionFeatureMachine(this.wizard.featureState, 'CONTINUE', this.mountModel.type);
} else {
this.get('wizard').transitionFeatureMachine(
this.get('wizard.featureState'),
'RESET',
this.get('mountModel').get('type')
);
this.wizard.transitionFeatureMachine(this.wizard.featureState, 'RESET', this.mountModel.type);
}
},
},
Expand Down
12 changes: 4 additions & 8 deletions ui/app/controllers/vault/cluster/settings/auth/enable.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,10 @@ import Controller from '@ember/controller';
export default Controller.extend({
wizard: service(),
actions: {
onMountSuccess: function(type) {
let transition = this.transitionToRoute('vault.cluster.access.methods');
return transition.followRedirects().then(() => {
this.get('wizard').transitionFeatureMachine(this.get('wizard.featureState'), 'CONTINUE', type);
});
},
onConfigError: function(modelId) {
return this.transitionToRoute('vault.cluster.settings.auth.configure', modelId);
onMountSuccess: function(type, path) {
this.wizard.transitionFeatureMachine(this.wizard.featureState, 'CONTINUE', type);
let transition = this.transitionToRoute('vault.cluster.settings.auth.configure', path);
return transition.followRedirects();
},
},
});
8 changes: 4 additions & 4 deletions ui/app/machines/auth-machine.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,16 @@ export default {
{ type: 'render', level: 'step', component: 'wizard/auth-enable' },
],
on: {
CONTINUE: 'list',
CONTINUE: 'config',
},
},
list: {
config: {
onEntry: [
{ type: 'render', level: 'step', component: 'wizard/auth-list' },
{ type: 'render', level: 'feature', component: 'wizard/mounts-wizard' },
{ type: 'render', level: 'step', component: 'wizard/auth-config' },
],
on: {
DETAILS: 'details',
CONTINUE: 'details',
},
},
details: {
Expand Down
Loading