UI: Add the wizard to the database secret engine (#10982)

* wizard setup

* cleanup

* add changelog

* fix names from save to create role and create database

* fix missing progress bar
This commit is contained in:
Angel Garbarino 2021-02-23 13:52:39 -07:00 committed by GitHub
parent e60cc11f33
commit af2b9af24e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 292 additions and 201 deletions

3
changelog/10982.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:feature
ui: Adds the wizard to the Database Secret Engine
```

View File

@ -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);

View File

@ -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;

View File

@ -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() {

View File

@ -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'] }],

View File

@ -16,7 +16,7 @@
</PageHeader>
{{#if (eq @mode "show")}}
<Toolbar>
<Toolbar>
<ToolbarActions>
{{#if @model.canDelete}}
<button
@ -77,11 +77,11 @@
</ToolbarSecretLink>
{{/if}}
</ToolbarActions>
</Toolbar>
</Toolbar>
{{/if}}
{{#if (eq @mode 'create')}}
<form {{on 'submit' this.handleCreateConnection}}>
<form {{on 'submit' this.handleCreateConnection}}>
{{#each @model.fieldAttrs as |attr|}}
{{#if (eq attr.name "pluginConfig")}}
{{!-- Plugin Config Section --}}
@ -127,7 +127,7 @@
disabled={{buttonDisabled}}
class="button is-primary"
>
Save
Create database
</button>
</div>
<div class="control">
@ -137,9 +137,9 @@
</div>
</div>
</div>
</form>
</form>
{{else if (eq @mode 'edit')}}
<form {{on 'submit' this.handleUpdateConnection}}>
<form {{on 'submit' this.handleUpdateConnection}}>
{{#each @model.fieldAttrs as |attr|}}
{{#if (eq attr.name "pluginConfig")}}
<div class="form-section">
@ -221,7 +221,7 @@
</div>
</div>
</div>
</form>
</form>
{{else}}
{{#each @model.showAttrs as |attr|}}
{{#let attr.options.defaultDisplay as |defaultDisplay|}}

View File

@ -108,7 +108,11 @@
disabled={{this.loading}}
class="button is-primary {{if this.loading 'is-loading'}}"
>
{{#if (eq @mode 'create')}}
Create role
{{else}}
Save
{{/if}}
</button>
{{else}}
<ToolTip @horizontalPosition="left" as |T|>

View File

@ -1,5 +1,6 @@
<div class="progress-container">
{{#each progressBar as |bar|}}
{{#each @progressBar as |bar|}}
<div class="feature-progress-container">
<span class="progress-bar">
<span class="feature-progress" style={{bar.style}} {{! template-lint-disable }}></span>

View File

@ -6,6 +6,7 @@
actionText=actionText
nextFeature=nextFeature
nextStep=nextStep
needsConnection=needsConnection
needsEncryption=needsEncryption
isSupported=isSupported
onDone=onDone

View File

@ -0,0 +1,8 @@
<WizardSection
@headerText="Create a Role"
@instructions='Click “Add role.”'
>
<p>
Now that we've setup a database let's connect a role.
</p>
</WizardSection>

View File

@ -0,0 +1,8 @@
<WizardSection
@headerText="Connect a database"
@instructions='Enter the details of your database and click “Create database.”'
>
<p>
Here you can specify the details of your database plugin and include any root rotation statements.
</p>
</WizardSection>

View File

@ -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, lets connect a {{@mountSubtype}}.
{{/if}}
</p>
</WizardSection>

View File

@ -0,0 +1,8 @@
<WizardSection
@headerText="Create a Role"
@instructions='Edit the details of your role and click “Create role.”'
>
<p>
Roles are what generate database credentials. They can be static or dynamic.
</p>
</WizardSection>

View File

@ -1,6 +1,6 @@
<WizardSection
@headerText="Adding a role"
@instructions='Enter your role details and click "Save"'
@instructions='Enter your role details and click "Create role"'
>
<p>
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.

View File

@ -93,7 +93,7 @@
{{else}}
{{#if (eq baseKey.id '')}}
<EmptyState
@title="No {{pluralize options.item}} in this backend yet"
@title="No {{pluralize options.item}} in this backend"
@message="Secrets in this backend will be listed here. Add a secret to get started."
>
<SecretLink @mode="create" @secret="" @queryParams={{query-params initialKey=(or filter baseKey.id) itemType=tab}} @class="link">