Skip to content

Commit

Permalink
UI/Add Elasticsearch DB (#12672)
Browse files Browse the repository at this point in the history
* displays empty state if database is not supported in the UI

* adds elasticsearch db plugin

* adds changelog

* updates elasticsearch attrs

* move tls_server_name to pluginConfig group

* move role setting fields to util

* updates comments and refactors using util function

* adds tests for elasticsearch

* fixes indentation

* when local host needs https

* adds line at bottom of hbs file
  • Loading branch information
hellobontempo committed Oct 7, 2021
1 parent 9b966f4 commit 3400fd3
Show file tree
Hide file tree
Showing 12 changed files with 254 additions and 142 deletions.
3 changes: 3 additions & 0 deletions changelog/12672.txt
@@ -0,0 +1,3 @@
```release-note:feature
**Elasticsearch in the UI**: Elasticsearch DB is now supported by the UI
```
35 changes: 3 additions & 32 deletions ui/app/components/database-role-setting-form.js
Expand Up @@ -14,38 +14,12 @@
*/

import Component from '@glimmer/component';
import { getStatementFields, getRoleFields } from '../utils/database-role-fields';

// Below fields are intended to be dynamic based on type of role and db.
// example of usage: FIELDS[roleType][db]
const ROLE_FIELDS = {
static: ['username', 'rotation_period'],
dynamic: ['ttl', 'max_ttl'],
};

const STATEMENT_FIELDS = {
static: {
default: ['rotation_statements'],
'mongodb-database-plugin': [],
'mssql-database-plugin': [],
'mysql-database-plugin': [],
'mysql-aurora-database-plugin': [],
'mysql-rds-database-plugin': [],
'mysql-legacy-database-plugin': [],
},
dynamic: {
default: ['creation_statements', 'revocation_statements', 'rollback_statements', 'renew_statements'],
'mongodb-database-plugin': ['creation_statement', 'revocation_statement'],
'mssql-database-plugin': ['creation_statements', 'revocation_statements'],
'mysql-database-plugin': ['creation_statements', 'revocation_statements'],
'mysql-aurora-database-plugin': ['creation_statements', 'revocation_statements'],
'mysql-rds-database-plugin': ['creation_statements', 'revocation_statements'],
'mysql-legacy-database-plugin': ['creation_statements', 'revocation_statements'],
},
};
export default class DatabaseRoleSettingForm extends Component {
get settingFields() {
if (!this.args.roleType) return null;
let dbValidFields = ROLE_FIELDS[this.args.roleType];
let dbValidFields = getRoleFields(this.args.roleType);
return this.args.attrs.filter(a => {
return dbValidFields.includes(a.name);
});
Expand All @@ -55,10 +29,7 @@ export default class DatabaseRoleSettingForm extends Component {
const type = this.args.roleType;
const plugin = this.args.dbType;
if (!type) return null;
let dbValidFields = STATEMENT_FIELDS[type].default;
if (STATEMENT_FIELDS[type][plugin]) {
dbValidFields = STATEMENT_FIELDS[type][plugin];
}
let dbValidFields = getStatementFields(type, plugin);
return this.args.attrs.filter(a => {
return dbValidFields.includes(a.name);
});
Expand Down
62 changes: 55 additions & 7 deletions ui/app/models/database/connection.js
Expand Up @@ -121,6 +121,26 @@ const AVAILABLE_PLUGIN_TYPES = [
{ attr: 'root_rotation_statements', group: 'statements' },
],
},
{
value: 'elasticsearch-database-plugin',
displayName: 'Elasticsearch',
fields: [
{ attr: 'plugin_name' },
{ attr: 'name' },
{ attr: 'verify_connection' },
{ attr: 'password_policy' },
{ attr: 'url', group: 'pluginConfig' },
{ attr: 'username', group: 'pluginConfig', show: false },
{ attr: 'password', group: 'pluginConfig', show: false },
{ attr: 'ca_cert', group: 'pluginConfig' },
{ attr: 'ca_path', group: 'pluginConfig' },
{ attr: 'client_cert', group: 'pluginConfig' },
{ attr: 'client_key', group: 'pluginConfig' },
{ attr: 'tls_server_name', group: 'pluginConfig' },
{ attr: 'insecure', group: 'pluginConfig' },
{ attr: 'username_template', group: 'pluginConfig' },
],
},
];

/**
Expand Down Expand Up @@ -149,7 +169,7 @@ export default Model.extend({
}),
// required
name: attr('string', {
label: 'Connection Name',
label: 'Connection name',
}),
plugin_name: attr('string', {
label: 'Database plugin',
Expand Down Expand Up @@ -177,22 +197,38 @@ export default Model.extend({

// common fields
connection_url: attr('string', {
subText: 'The connection string used to connect to the database.',
label: 'Connection URL',
subText:
'The connection string used to connect to the database. This allows for simple templating of username and password of the root user in the {{field_name}} format.',
}),
url: attr('string', {
subText:
'The connection string used to connect to the database. This allows for simple templating of username and password of the root user.',
label: 'URL',
subText: `The URL for Elasticsearch's API ("https://localhost:9200").`,
}),
username: attr('string', {
subText: 'Optional. The name of the user to use as the "root" user when connecting to the database.',
subText: `The name of the user to use as the "root" user when connecting to the database.`,
}),
password: attr('string', {
subText:
'Optional. The password to use when connecting to the database. Typically used in the connection_url field via the templating directive {{password}}.',
subText: 'The password to use when connecting with the above username.',
editType: 'password',
}),

// optional
ca_cert: attr('string', {
label: 'CA certificate',
subText: `The path to a PEM-encoded CA cert file to use to verify the Elasticsearch server's identity.`,
}),
ca_path: attr('string', {
label: 'CA path',
subText: `The path to a directory of PEM-encoded CA cert files to use to verify the Elasticsearch server's identity.`,
}),
client_cert: attr('string', {
label: 'Client certificate',
subText: 'The path to the certificate for the Elasticsearch client to present for communication.',
}),
client_key: attr('string', {
subText: 'The path to the key for the Elasticsearch client to use for communication.',
}),
hosts: attr('string', {}),
host: attr('string', {}),
port: attr('string', {}),
Expand Down Expand Up @@ -220,6 +256,10 @@ export default Model.extend({
max_connection_lifetime: attr('string', {
defaultValue: '0s',
}),
insecure: attr('boolean', {
defaultValue: false,
label: 'Disable SSL verification',
}),
tls: attr('string', {
label: 'TLS Certificate Key',
helpText:
Expand All @@ -232,12 +272,20 @@ export default Model.extend({
'x509 CA file for validating the certificate presented by the MongoDB server. Must be PEM encoded.',
editType: 'file',
}),
tls_server_name: attr('string', {
label: 'TLS server name',
subText: 'If set, this name is used to set the SNI host when connecting via 1TLS.',
}),
root_rotation_statements: attr({
subText: `The database statements to be executed to rotate the root user's credentials. If nothing is entered, Vault will use a reasonable default.`,
editType: 'stringArray',
defaultShown: 'Default',
}),

isAvailablePlugin: computed('plugin_name', function() {
return !!AVAILABLE_PLUGIN_TYPES.find(a => a.value === this.plugin_name);
}),

showAttrs: computed('plugin_name', function() {
const fields = AVAILABLE_PLUGIN_TYPES.find(a => a.value === this.plugin_name)
.fields.filter(f => f.show !== false)
Expand Down
11 changes: 4 additions & 7 deletions ui/app/models/database/role.js
Expand Up @@ -3,6 +3,7 @@ import { computed } from '@ember/object';
import { alias } from '@ember/object/computed';
import lazyCapabilities, { apiPath } from 'vault/macros/lazy-capabilities';
import { expandAttributeMeta } from 'vault/utils/field-to-attrs';
import { getRoleFields } from '../../utils/database-role-fields';

export default Model.extend({
idPrefix: 'role/',
Expand Down Expand Up @@ -90,11 +91,7 @@ export default Model.extend({

get showFields() {
let fields = ['name', 'database', 'type'];
if (this.type === 'dynamic') {
fields = fields.concat(['ttl', 'max_ttl', 'creation_statements', 'revocation_statements']);
} else {
fields = fields.concat(['username', 'rotation_period']);
}
fields = fields.concat(getRoleFields(this.type)).concat(['creation_statements', 'revocation_statements']);
return expandAttributeMeta(this, fields);
},

Expand All @@ -106,9 +103,9 @@ export default Model.extend({
'username',
'rotation_period',
'creation_statements',
'creation_statement', // only for MongoDB (styling difference)
'creation_statement', // for editType: JSON
'revocation_statements',
'revocation_statement', // only for MongoDB (styling difference)
'revocation_statement', // only for MongoDB (editType: JSON)
'rotation_statements',
'rollback_statements',
'renew_statements',
Expand Down
3 changes: 3 additions & 0 deletions ui/app/styles/components/empty-state.scss
Expand Up @@ -42,6 +42,8 @@

.empty-state-actions {
margin-top: $spacing-xs;
display: flex;
justify-content: space-between;

a,
.link,
Expand All @@ -54,6 +56,7 @@

> * + * {
margin-left: $spacing-s;
margin-right: $spacing-s;
}
}

Expand Down

0 comments on commit 3400fd3

Please sign in to comment.