diff --git a/changelog/10982.txt b/changelog/10982.txt new file mode 100644 index 000000000000..7102478440bc --- /dev/null +++ b/changelog/10982.txt @@ -0,0 +1,3 @@ +```release-note:feature +ui: Adds the wizard to the Database Secret Engine +``` diff --git a/ui/app/components/database-connection.js b/ui/app/components/database-connection.js index 9eae92aca86b..efb13943c23d 100644 --- a/ui/app/components/database-connection.js +++ b/ui/app/components/database-connection.js @@ -19,6 +19,7 @@ export default class DatabaseConnectionEdit extends Component { @service store; @service router; @service flashMessages; + @service wizard; @tracked showPasswordField = false; // used for edit mode @@ -26,6 +27,13 @@ export default class DatabaseConnectionEdit extends Component { @tracked showSaveModal = false; // used for create mode + constructor() { + super(...arguments); + if (this.wizard.featureState === 'details' || this.wizard.featureState === 'connection') { + this.wizard.transitionFeatureMachine(this.wizard.featureState, 'CONTINUE', 'database'); + } + } + rotateCredentials(backend, name) { let adapter = this.store.adapterFor('database/connection'); return adapter.rotateRootCredentials(backend, name); diff --git a/ui/app/components/database-role-edit.js b/ui/app/components/database-role-edit.js index cc3319bc57c0..fe87bebfb710 100644 --- a/ui/app/components/database-role-edit.js +++ b/ui/app/components/database-role-edit.js @@ -9,6 +9,18 @@ const SHOW_ROUTE = 'vault.cluster.secrets.backend.show'; export default class DatabaseRoleEdit extends Component { @service router; @service flashMessages; + @service wizard; + + constructor() { + super(...arguments); + console.log(this.wizard.featureState, 'featureSTate'); + if ( + this.wizard.featureState === 'displayConnection' || + this.wizard.featureState === 'displayRoleDatabase' + ) { + this.wizard.transitionFeatureMachine(this.wizard.featureState, 'CONTINUE', 'database'); + } + } @tracked loading = false; diff --git a/ui/app/components/wizard/mounts-wizard.js b/ui/app/components/wizard/mounts-wizard.js index 1a2fa74afc7a..657ade04e12b 100644 --- a/ui/app/components/wizard/mounts-wizard.js +++ b/ui/app/components/wizard/mounts-wizard.js @@ -20,6 +20,7 @@ export default Component.extend({ nextStep: computed('fullNextStep', function() { return this.fullNextStep.split('.').lastObject; }), + needsConnection: equal('mountSubtype', 'database'), needsEncryption: equal('mountSubtype', 'transit'), stepComponent: alias('wizard.stepComponent'), detailsComponent: computed('currentMachine', 'mountSubtype', function() { diff --git a/ui/app/machines/secrets-machine.js b/ui/app/machines/secrets-machine.js index 1a75282b5f27..e50f405f5e6e 100644 --- a/ui/app/machines/secrets-machine.js +++ b/ui/app/machines/secrets-machine.js @@ -39,6 +39,9 @@ export default { ], on: { CONTINUE: { + connection: { + cond: type => type === 'database', + }, role: { cond: type => ['pki', 'aws', 'ssh'].includes(type), }, @@ -51,6 +54,15 @@ export default { }, }, }, + connection: { + onEntry: [ + { type: 'render', level: 'step', component: 'wizard/secrets-connection' }, + { type: 'render', level: 'feature', component: 'wizard/mounts-wizard' }, + ], + on: { + CONTINUE: 'displayConnection', + }, + }, encryption: { onEntry: [ { type: 'render', level: 'feature', component: 'wizard/mounts-wizard' }, @@ -87,6 +99,24 @@ export default { CONTINUE: 'credentials', }, }, + displayConnection: { + onEntry: [ + { type: 'render', level: 'step', component: 'wizard/secrets-connection-show' }, + { type: 'render', level: 'feature', component: 'wizard/mounts-wizard' }, + ], + on: { + CONTINUE: 'displayRoleDatabase', + }, + }, + displayRoleDatabase: { + onEntry: [ + { type: 'render', level: 'step', component: 'wizard/secrets-display-database-role' }, + { type: 'render', level: 'feature', component: 'wizard/mounts-wizard' }, + ], + on: { + CONTINUE: 'display', + }, + }, secret: { onEntry: [ { type: 'render', level: 'step', component: 'wizard/secrets-secret' }, @@ -103,6 +133,10 @@ export default { ], on: { REPEAT: { + connection: { + cond: type => type === 'database', + actions: [{ type: 'routeTransition', params: ['vault.cluster.secrets.backend.create-root'] }], + }, role: { cond: type => ['pki', 'aws', 'ssh'].includes(type), actions: [{ type: 'routeTransition', params: ['vault.cluster.secrets.backend.create-root'] }], diff --git a/ui/app/templates/components/database-connection.hbs b/ui/app/templates/components/database-connection.hbs index d4ec905b9907..0ecf92af4373 100644 --- a/ui/app/templates/components/database-connection.hbs +++ b/ui/app/templates/components/database-connection.hbs @@ -16,212 +16,212 @@ {{#if (eq @mode "show")}} - - - {{#if @model.canDelete}} - - {{/if}} - {{#if @model.canReset}} - - Reset connection - - {{/if}} - {{#if (and @model.canReset @model.canDelete)}} -
- {{/if}} - {{#if @model.canRotate }} - - Rotate root credentials - - {{/if}} - {{#if @model.canAddRole}} - - Add role - - {{/if}} - {{#if @model.canEdit}} - - Edit configuration - - {{/if}} - - + + + {{#if @model.canDelete}} + + {{/if}} + {{#if @model.canReset}} + + Reset connection + + {{/if}} + {{#if (and @model.canReset @model.canDelete)}} +
+ {{/if}} + {{#if @model.canRotate }} + + Rotate root credentials + + {{/if}} + {{#if @model.canAddRole}} + + Add role + + {{/if}} + {{#if @model.canEdit}} + + Edit configuration + + {{/if}} + + {{/if}} {{#if (eq @mode 'create')}} -
- {{#each @model.fieldAttrs as |attr|}} - {{#if (eq attr.name "pluginConfig")}} - {{!-- Plugin Config Section --}} -
-

Plugin config

- {{#unless @model.pluginFieldGroups}} - - {{else}} - {{#each @model.pluginFieldGroups as |fieldGroup|}} - {{#each-in fieldGroup as |group fields|}} - {{#if (eq group "default")}} - {{#each fields as |attr|}} - {{form-field data-test-field attr=attr model=@model}} - {{/each}} - {{else}} - - {{#if (get this (concat "show" (camelize group)))}} -
- {{#each fields as |attr|}} - {{form-field data-test-field attr=attr model=@model}} - {{/each}} -
+ + {{#each @model.fieldAttrs as |attr|}} + {{#if (eq attr.name "pluginConfig")}} + {{!-- Plugin Config Section --}} +
+

Plugin config

+ {{#unless @model.pluginFieldGroups}} + + {{else}} + {{#each @model.pluginFieldGroups as |fieldGroup|}} + {{#each-in fieldGroup as |group fields|}} + {{#if (eq group "default")}} + {{#each fields as |attr|}} + {{form-field data-test-field attr=attr model=@model}} + {{/each}} + {{else}} + + {{#if (get this (concat "show" (camelize group)))}} +
+ {{#each fields as |attr|}} + {{form-field data-test-field attr=attr model=@model}} + {{/each}} +
+ {{/if}} {{/if}} - {{/if}} - {{/each-in}} - {{/each}} - {{/unless}} -
- {{else if (not-eq attr.options.readOnly true)}} - {{form-field data-test-field attr=attr model=@model}} - {{/if}} - {{/each}} + {{/each-in}} + {{/each}} + {{/unless}} +
+ {{else if (not-eq attr.options.readOnly true)}} + {{form-field data-test-field attr=attr model=@model}} + {{/if}} + {{/each}} -
-
-
- -
-
- - Cancel - +
+
+
+ +
+
+ + Cancel + +
-
- + {{else if (eq @mode 'edit')}} -
- {{#each @model.fieldAttrs as |attr|}} - {{#if (eq attr.name "pluginConfig")}} -
-

Plugin config

- {{#each @model.pluginFieldGroups as |fieldGroup|}} - {{#each-in fieldGroup as |group fields|}} - {{#if (eq group "default")}} - {{#each fields as |attr|}} - {{#if (eq attr.name "password")}} - -
- - Update password
-
- {{if this.showPasswordField 'The new password that will be used when connecting to the database' 'Vault will use the existing password'}} -
- {{#if this.showPasswordField}} - - {{/if}} -
+ + {{#each @model.fieldAttrs as |attr|}} + {{#if (eq attr.name "pluginConfig")}} +
+

Plugin config

+ {{#each @model.pluginFieldGroups as |fieldGroup|}} + {{#each-in fieldGroup as |group fields|}} + {{#if (eq group "default")}} + {{#each fields as |attr|}} + {{#if (eq attr.name "password")}} + +
+ + Update password
+
+ {{if this.showPasswordField 'The new password that will be used when connecting to the database' 'Vault will use the existing password'}} +
+ {{#if this.showPasswordField}} + + {{/if}} +
+
+ {{else}} + {{form-field data-test-field attr=attr model=@model}} + {{/if}} + {{/each}} + {{else}} + + {{#if (get this (concat "show" (camelize group)))}} +
+ {{#each fields as |attr|}} + {{form-field data-test-field attr=attr model=@model}} + {{/each}}
- {{else}} - {{form-field data-test-field attr=attr model=@model}} {{/if}} - {{/each}} - {{else}} - - {{#if (get this (concat "show" (camelize group)))}} -
- {{#each fields as |attr|}} - {{form-field data-test-field attr=attr model=@model}} - {{/each}} -
{{/if}} - {{/if}} - {{/each-in}} - {{/each}} -
- {{else if (or (eq attr.name 'name') (eq attr.name 'plugin_name'))}} - - {{else if (not-eq attr.options.readOnly true)}} - {{form-field data-test-field attr=attr model=@model}} - {{/if}} - {{/each}} + {{/each-in}} + {{/each}} +
+ {{else if (or (eq attr.name 'name') (eq attr.name 'plugin_name'))}} + + {{else if (not-eq attr.options.readOnly true)}} + {{form-field data-test-field attr=attr model=@model}} + {{/if}} + {{/each}} -
-
-
- -
-
- - Cancel - +
+
+
+ +
+
+ + Cancel + +
-
- + {{else}} {{#each @model.showAttrs as |attr|}} {{#let attr.options.defaultDisplay as |defaultDisplay|}} diff --git a/ui/app/templates/components/database-role-edit.hbs b/ui/app/templates/components/database-role-edit.hbs index 4e56ee8df855..4dd25ed2e5fc 100644 --- a/ui/app/templates/components/database-role-edit.hbs +++ b/ui/app/templates/components/database-role-edit.hbs @@ -108,7 +108,11 @@ disabled={{this.loading}} class="button is-primary {{if this.loading 'is-loading'}}" > - Save + {{#if (eq @mode 'create')}} + Create role + {{else}} + Save + {{/if}} {{else}} diff --git a/ui/app/templates/components/wizard-progress.hbs b/ui/app/templates/components/wizard-progress.hbs index c658aa527db2..e4de36e03433 100644 --- a/ui/app/templates/components/wizard-progress.hbs +++ b/ui/app/templates/components/wizard-progress.hbs @@ -1,5 +1,6 @@ +
- {{#each progressBar as |bar|}} + {{#each @progressBar as |bar|}}
diff --git a/ui/app/templates/components/wizard/mounts-wizard.hbs b/ui/app/templates/components/wizard/mounts-wizard.hbs index 74229973d817..f3e38ca725a4 100644 --- a/ui/app/templates/components/wizard/mounts-wizard.hbs +++ b/ui/app/templates/components/wizard/mounts-wizard.hbs @@ -6,6 +6,7 @@ actionText=actionText nextFeature=nextFeature nextStep=nextStep + needsConnection=needsConnection needsEncryption=needsEncryption isSupported=isSupported onDone=onDone diff --git a/ui/app/templates/components/wizard/secrets-connection-show.hbs b/ui/app/templates/components/wizard/secrets-connection-show.hbs new file mode 100644 index 000000000000..102e3d3740a6 --- /dev/null +++ b/ui/app/templates/components/wizard/secrets-connection-show.hbs @@ -0,0 +1,8 @@ + +

+ Now that we've setup a database let's connect a role. +

+
diff --git a/ui/app/templates/components/wizard/secrets-connection.hbs b/ui/app/templates/components/wizard/secrets-connection.hbs new file mode 100644 index 000000000000..bf48a09058a9 --- /dev/null +++ b/ui/app/templates/components/wizard/secrets-connection.hbs @@ -0,0 +1,8 @@ + +

+ Here you can specify the details of your database plugin and include any root rotation statements. +

+
diff --git a/ui/app/templates/components/wizard/secrets-details.hbs b/ui/app/templates/components/wizard/secrets-details.hbs index b32b1752e1ba..9520ea37e181 100644 --- a/ui/app/templates/components/wizard/secrets-details.hbs +++ b/ui/app/templates/components/wizard/secrets-details.hbs @@ -6,5 +6,8 @@ {{#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}}

diff --git a/ui/app/templates/components/wizard/secrets-display-database-role.hbs b/ui/app/templates/components/wizard/secrets-display-database-role.hbs new file mode 100644 index 000000000000..771e2090292f --- /dev/null +++ b/ui/app/templates/components/wizard/secrets-display-database-role.hbs @@ -0,0 +1,8 @@ + +

+ Roles are what generate database credentials. They can be static or dynamic. +

+
diff --git a/ui/app/templates/components/wizard/secrets-role.hbs b/ui/app/templates/components/wizard/secrets-role.hbs index c533949ac02e..96efbfefd983 100644 --- a/ui/app/templates/components/wizard/secrets-role.hbs +++ b/ui/app/templates/components/wizard/secrets-role.hbs @@ -1,6 +1,6 @@

A role grants permissions that specify what an identity can and cannot do. A role is typically shared among many users who are then granted credentials with that are granted the policy permissions. diff --git a/ui/app/templates/vault/cluster/secrets/backend/roles.hbs b/ui/app/templates/vault/cluster/secrets/backend/roles.hbs index 9d8e65b87ac6..b5ba04e6b5e3 100644 --- a/ui/app/templates/vault/cluster/secrets/backend/roles.hbs +++ b/ui/app/templates/vault/cluster/secrets/backend/roles.hbs @@ -93,7 +93,7 @@ {{else}} {{#if (eq baseKey.id '')}}