diff --git a/ui/app/components/keymgmt/distribute.js b/ui/app/components/keymgmt/distribute.js
index 8400670b13..1eaeaccf80 100644
--- a/ui/app/components/keymgmt/distribute.js
+++ b/ui/app/components/keymgmt/distribute.js
@@ -33,6 +33,7 @@ export default class KeymgmtDistribute extends Component {
@service store;
@service flashMessages;
@service router;
+ @service wizard;
@tracked keyModel;
@tracked isNewKey = false;
@@ -53,6 +54,14 @@ export default class KeymgmtDistribute extends Component {
this.getKeyInfo(this.args.key);
}
this.formData.operations = [];
+ this.updateWizard('nextStep');
+ }
+
+ updateWizard(key) {
+ // wizard will pause unless we manually continue it -- verify that keymgmt tutorial is in progress
+ if (this.wizard[key] === 'distribute') {
+ this.wizard.transitionFeatureMachine(this.wizard.featureState, 'CONTINUE', 'keymgmt');
+ }
}
get keyTypes() {
@@ -175,12 +184,15 @@ export default class KeymgmtDistribute extends Component {
return { key, provider, purpose: operations.join(','), protection };
}
- distributeKey(backend, kms, key, data) {
- let adapter = this.store.adapterFor('keymgmt/key');
+ distributeKey(backend, data) {
+ const adapter = this.store.adapterFor('keymgmt/key');
+ const { key, provider, purpose, protection } = data;
return adapter
- .distribute(backend, kms, key, data)
+ .distribute(backend, provider, key, { purpose, protection })
.then(() => {
- this.flashMessages.success(`Successfully distributed key ${key} to ${kms}`);
+ this.flashMessages.success(`Successfully distributed key ${key} to ${provider}`);
+ // move wizard forward if tutorial is in progress
+ this.updateWizard('featureState');
this.args.onClose();
})
.catch((e) => {
@@ -233,15 +245,13 @@ export default class KeymgmtDistribute extends Component {
return;
}
if (this.isNewKey) {
- this.keyModel
- .save()
- .then(() => {
- this.flashMessages.success(`Successfully created key ${this.keyModel.name}`);
- })
- .catch((e) => {
- this.flashMessages.danger(`Error creating new key ${this.keyModel.name}: ${e.errors}`);
- });
+ try {
+ await this.keyModel.save();
+ this.flashMessages.success(`Successfully created key ${this.keyModel.name}`);
+ } catch (e) {
+ this.flashMessages.danger(`Error creating new key ${this.keyModel.name}: ${e.errors}`);
+ }
}
- this.distributeKey(backend, 'example-kms', 'example-key', this.formatData(this.formData));
+ this.distributeKey(backend, data);
}
}
diff --git a/ui/app/components/wizard/secrets-keymgmt.js b/ui/app/components/wizard/secrets-keymgmt.js
new file mode 100644
index 0000000000..7ea5db24bf
--- /dev/null
+++ b/ui/app/components/wizard/secrets-keymgmt.js
@@ -0,0 +1,27 @@
+import Component from '@glimmer/component';
+
+export default class WizardSecretsKeymgmtComponent extends Component {
+ get headerText() {
+ return {
+ provider: 'Creating a provider',
+ displayProvider: 'Distributing a key',
+ distribute: 'Creating a key',
+ }[this.args.featureState];
+ }
+
+ get body() {
+ return {
+ provider: 'This process connects an external provider to Vault. You will need its credentials.',
+ displayProvider: 'A key can now be created and distributed to this destination.',
+ distribute: 'This process creates a key and distributes it to your provider.',
+ }[this.args.featureState];
+ }
+
+ get instructions() {
+ return {
+ provider: 'Enter your provider details and click “Create provider“.',
+ displayProvider: 'Click “Distribute key” in the toolbar.',
+ distribute: 'Enter your key details and click “Distribute key”.',
+ }[this.args.featureState];
+ }
+}
diff --git a/ui/app/controllers/vault/cluster/settings/mount-secret-backend.js b/ui/app/controllers/vault/cluster/settings/mount-secret-backend.js
index a2d7562337..cf18cd432b 100644
--- a/ui/app/controllers/vault/cluster/settings/mount-secret-backend.js
+++ b/ui/app/controllers/vault/cluster/settings/mount-secret-backend.js
@@ -12,6 +12,10 @@ export default Controller.extend({
if (SUPPORTED_BACKENDS.includes(type)) {
if (type === 'kmip') {
transition = this.transitionToRoute('vault.cluster.secrets.backend.kmip.scopes', path);
+ } else if (type === 'keymgmt') {
+ transition = this.transitionToRoute('vault.cluster.secrets.backend.index', path, {
+ queryParams: { tab: 'provider' },
+ });
} else {
transition = this.transitionToRoute('vault.cluster.secrets.backend.index', path);
}
diff --git a/ui/app/helpers/wizard-constants.js b/ui/app/helpers/wizard-constants.js
index 93b070887f..5ac0568978 100644
--- a/ui/app/helpers/wizard-constants.js
+++ b/ui/app/helpers/wizard-constants.js
@@ -48,6 +48,7 @@ export const FEATURE_MACHINE_STEPS = {
secret: 5,
},
role: 7,
+ provider: 8,
},
policies: 5,
replication: 2,
diff --git a/ui/app/machines/secrets-machine.js b/ui/app/machines/secrets-machine.js
index 4a40da87b2..8e399112bf 100644
--- a/ui/app/machines/secrets-machine.js
+++ b/ui/app/machines/secrets-machine.js
@@ -51,6 +51,9 @@ export default {
encryption: {
cond: (type) => type === 'transit',
},
+ provider: {
+ cond: (type) => type === 'keymgmt',
+ },
},
},
},
@@ -126,6 +129,33 @@ export default {
CONTINUE: 'display',
},
},
+ provider: {
+ onEntry: [
+ { type: 'render', level: 'step', component: 'wizard/secrets-keymgmt' },
+ { type: 'render', level: 'feature', component: 'wizard/mounts-wizard' },
+ ],
+ on: {
+ CONTINUE: 'displayProvider',
+ },
+ },
+ displayProvider: {
+ onEntry: [
+ { type: 'render', level: 'step', component: 'wizard/secrets-keymgmt' },
+ { type: 'render', level: 'feature', component: 'wizard/mounts-wizard' },
+ ],
+ on: {
+ CONTINUE: 'distribute',
+ },
+ },
+ distribute: {
+ onEntry: [
+ { type: 'render', level: 'step', component: 'wizard/secrets-keymgmt' },
+ { type: 'render', level: 'feature', component: 'wizard/mounts-wizard' },
+ ],
+ on: {
+ CONTINUE: 'display',
+ },
+ },
display: {
onEntry: [
{ type: 'render', level: 'step', component: 'wizard/secrets-display' },
@@ -149,6 +179,18 @@ export default {
cond: (type) => type === 'transit',
actions: [{ type: 'routeTransition', params: ['vault.cluster.secrets.backend.create-root'] }],
},
+ provider: {
+ cond: (type) => type === 'keymgmt',
+ actions: [
+ {
+ type: 'routeTransition',
+ params: [
+ 'vault.cluster.secrets.backend.create-root',
+ { queryParams: { itemType: 'provider' } },
+ ],
+ },
+ ],
+ },
},
},
},
diff --git a/ui/app/routes/vault/cluster/secrets/backend/create-root.js b/ui/app/routes/vault/cluster/secrets/backend/create-root.js
index 6362d30cc2..368eb359e4 100644
--- a/ui/app/routes/vault/cluster/secrets/backend/create-root.js
+++ b/ui/app/routes/vault/cluster/secrets/backend/create-root.js
@@ -29,6 +29,7 @@ const transformModel = (queryParams) => {
export default EditBase.extend({
wizard: service(),
+
createModel(transition) {
const { backend } = this.paramsFor('vault.cluster.secrets.backend');
let modelType = this.modelType(backend, null, { queryParams: transition.to.queryParams });
@@ -57,6 +58,10 @@ export default EditBase.extend({
},
model(params, transition) {
+ // wizard will pause unless we manually continue it -- verify that keymgmt tutorial is in progress
+ if (params.itemType === 'provider' && this.wizard.nextStep === 'provider') {
+ this.wizard.transitionFeatureMachine(this.wizard.featureState, 'CONTINUE', 'keymgmt');
+ }
return hash({
secret: this.createModel(transition),
capabilities: {},
diff --git a/ui/app/routes/vault/cluster/secrets/backend/secret-edit.js b/ui/app/routes/vault/cluster/secrets/backend/secret-edit.js
index 10f0d9995f..1ccc5bfdbd 100644
--- a/ui/app/routes/vault/cluster/secrets/backend/secret-edit.js
+++ b/ui/app/routes/vault/cluster/secrets/backend/secret-edit.js
@@ -9,6 +9,8 @@ import { encodePath, normalizePath } from 'vault/utils/path-encoding-helpers';
export default Route.extend(UnloadModelRoute, {
pathHelp: service('path-help'),
+ wizard: service(),
+
secretParam() {
let { secret } = this.paramsFor(this.routeName);
return secret ? normalizePath(secret) : '';
@@ -211,8 +213,16 @@ export default Route.extend(UnloadModelRoute, {
let secretModel = this.store.peekRecord(modelType, secretId);
return secretModel;
},
+ // wizard will pause unless we manually continue it
+ updateWizard(params) {
+ // verify that keymgmt tutorial is in progress
+ if (params.itemType === 'provider' && this.wizard.nextStep === 'displayProvider') {
+ this.wizard.transitionFeatureMachine(this.wizard.featureState, 'CONTINUE', 'keymgmt');
+ }
+ },
async model(params, { to: { queryParams } }) {
+ this.updateWizard(params);
let secret = this.secretParam();
let backend = this.enginePathParam();
let modelType = this.modelType(backend, secret, { queryParams });
diff --git a/ui/app/templates/components/keymgmt/key-edit.hbs b/ui/app/templates/components/keymgmt/key-edit.hbs
index f25579855e..e190b3ec13 100644
--- a/ui/app/templates/components/keymgmt/key-edit.hbs
+++ b/ui/app/templates/components/keymgmt/key-edit.hbs
@@ -18,7 +18,7 @@
{{#if this.isDistributing}}
-
+ Key Management is a secrets engine that allows key generation, lifecycle management, and secure distribution of + cryptographic keys into cloud key management services. +
+- {{#if @needsEncryption}} - The Transit Secrets Engine uses encryption keys to provide "encryption as a service". Click on "Create Encryption Key" - at the top to create one. - {{/if}} - {{#if @needsConnection}} - Now that the engine has been mounted, let’s connect a - {{@mountSubtype}}. + {{#if (eq @mountSubtype "keymgmt")}} + This secrets engine manages keys and distributes them to external destinations. We recommend that you create a provider + to which you can distribute keys. + {{else}} + {{#if @needsEncryption}} + The Transit Secrets Engine uses encryption keys to provide "encryption as a service". Click on "Create Encryption + Key" at the top to create one. + {{/if}} + {{#if @needsConnection}} + Now that the engine has been mounted, let’s connect a + {{@mountSubtype}}. + {{/if}} {{/if}}
- {{#if @actionText}} + {{#if (eq @mountSubtype "keymgmt")}} + Your key and your provider have been created and connected. From here, you can click the key name to view the key + You’re now ready to start using the secrets engine. + {{else if @actionText}} Here is your generated credential. As you can see, we can only show the credential once, so you'll want to be sure to save it. If you need another credential in the future, just come back and generate a new one. {{else}} @@ -20,7 +29,7 @@