open-vault/ui/app/components/mount-backend-form.js
Jordan Reimer 5c2a08de6d
Ember Upgrade to 3.24 (#13443)
* Update browserslist

* Add browserslistrc

* ember-cli-update --to 3.26, fix conflicts

* Run codemodes that start with ember-*

* More codemods - before cp*

* More codemods (curly data-test-*)

* WIP ember-basic-dropdown template errors

* updates ember-basic-dropdown and related deps to fix build issues

* updates basic dropdown instances to new version API

* updates more deps -- ember-template-lint is working again

* runs no-implicit-this codemod

* creates and runs no-quoteless-attributes codemod

* runs angle brackets codemod

* updates lint:hbs globs to only touch hbs files

* removes yield only templates

* creates and runs deprecated args transform

* supresses lint error for invokeAction on LinkTo component

* resolves remaining ambiguous path lint errors

* resolves simple-unless lint errors

* adds warnings for deprecated tagName arg on LinkTo components

* adds warnings for remaining curly component invocation

* updates global template lint rules

* resolves remaining template lint errors

* disables some ember specfic lint rules that target pre octane patterns

* js lint fix run

* resolves remaining js lint errors

* fixes test run

* adds npm-run-all dep

* fixes test attribute issues

* fixes console acceptance tests

* fixes tests

* adds yield only wizard/tutorial-active template

* fixes more tests

* attempts to fix more flaky tests

* removes commented out settled in transit test

* updates deprecations workflow and adds initializer to filter by version

* updates flaky policies acl old test

* updates to flaky transit test

* bumps ember deps down to LTS version

* runs linters after main merge

* fixes client count tests after bad merge conflict fixes

* fixes client count history test

* more updates to lint config

* another round of hbs lint fixes after extending stylistic rule

* updates lint-staged commands

* removes indent eslint rule since it seems to break things

* fixes bad attribute in transform-edit-form template

* test fixes

* fixes enterprise tests

* adds changelog

* removes deprecated ember-concurrency-test-waiters dep and adds @ember/test-waiters

* flaky test fix

Co-authored-by: hashishaw <cshaw@hashicorp.com>
2021-12-16 20:44:29 -07:00

191 lines
5.8 KiB
JavaScript

import Ember from 'ember';
import { inject as service } from '@ember/service';
import { computed, set } from '@ember/object';
import Component from '@ember/component';
import { task } from 'ember-concurrency';
import { methods } from 'vault/helpers/mountable-auth-methods';
import { engines, KMIP, TRANSFORM } from 'vault/helpers/mountable-secret-engines';
import { waitFor } from '@ember/test-waiters';
const METHODS = methods();
const ENGINES = engines();
export default Component.extend({
store: service(),
wizard: service(),
flashMessages: service(),
version: service(),
/*
* @param Function
* @public
*
* Optional param to call a function upon successfully mounting a backend
*
*/
onMountSuccess() {},
/*
* @param String
* @public
* the type of backend we want to mount
* defaults to `auth`
*
*/
mountType: 'auth',
/*
*
* @param DS.Model
* @private
* Ember Data model corresponding to the `mountType`.
* Created and set during `init`
*
*/
mountModel: null,
showEnable: false,
// cp-validation related properties
validationMessages: null,
isFormInvalid: false,
mountIssue: false,
init() {
this._super(...arguments);
const type = this.mountType;
const modelType = type === 'secret' ? 'secret-engine' : 'auth-method';
const model = this.store.createRecord(modelType);
this.set('mountModel', model);
this.set('validationMessages', {
path: '',
});
},
mountTypes: computed('engines', 'mountType', function () {
return this.mountType === 'secret' ? this.engines : METHODS;
}),
engines: computed('version.{features[],isEnterprise}', function () {
if (this.version.isEnterprise) {
return ENGINES.concat([KMIP, TRANSFORM]);
}
return ENGINES;
}),
willDestroy() {
this._super(...arguments);
// if unsaved, we want to unload so it doesn't show up in the auth mount list
this.mountModel.rollbackAttributes();
},
checkPathChange(type) {
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);
if (!currentPath || isUnchanged) {
mount.set('path', type);
}
},
mountBackend: task(
waitFor(function* () {
const mountModel = this.mountModel;
const { type, path } = mountModel;
let capabilities = null;
try {
capabilities = yield this.store.findRecord('capabilities', `${path}/config`);
} catch (err) {
if (Ember.testing) {
//captures mount-backend-form component test
yield mountModel.save();
let mountType = this.mountType;
mountType = mountType === 'secret' ? `${mountType}s engine` : `${mountType} method`;
this.flashMessages.success(`Successfully mounted the ${type} ${mountType} at ${path}.`);
yield this.onMountSuccess(type, path);
return;
} else {
throw err;
}
}
if (!capabilities.get('canUpdate')) {
// if there is no sys/mount issue then error is config endpoint.
this.flashMessages.warning(
'You do not have access to the config endpoint. The secret engine was mounted, but the configuration settings were not saved.'
);
// remove the config data from the model otherwise it will save it even if the network request failed.
[this.mountModel.maxVersions, this.mountModel.casRequired, this.mountModel.deleteVersionAfter] = [
0,
false,
0,
];
}
try {
yield mountModel.save();
} catch (err) {
if (err.message === 'mountIssue') {
this.mountIssue = true;
this.set('isFormInvalid', this.mountIssue);
this.flashMessages.danger(
'You do not have access to the sys/mounts endpoint. The secret engine was not mounted.'
);
return;
}
this.set('errorMessage', 'This mount path already exist.');
return;
}
let mountType = this.mountType;
mountType = mountType === 'secret' ? `${mountType}s engine` : `${mountType} method`;
this.flashMessages.success(`Successfully mounted the ${type} ${mountType} at ${path}.`);
yield this.onMountSuccess(type, path);
return;
})
).drop(),
actions: {
onKeyUp(name, value) {
// 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);
}
// check maxVersions is a number
if (name === 'maxVersions') {
this.mountModel.set('maxVersions', value);
this.mountModel.validations.attrs.maxVersions.isValid
? set(this.validationMessages, 'maxVersions', '')
: set(
this.validationMessages,
'maxVersions',
this.mountModel.validations.attrs.maxVersions.message
);
}
this.mountModel.validate().then(({ validations }) => {
this.set('isFormInvalid', !validations.isValid);
});
},
onTypeChange(path, value) {
if (path === 'type') {
this.wizard.set('componentState', value);
this.checkPathChange(value);
}
},
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.wizard.transitionFeatureMachine(this.wizard.featureState, 'RESET', this.mountModel.type);
}
},
},
});