Merge branch 'feature/design' of github.com:elastic/kibana into selectable_list_directive
This commit is contained in:
commit
1dc9a18de7
|
@ -128,7 +128,7 @@ Runs both server and browser tests, but skips linting
|
|||
Run only the server tests
|
||||
|
||||
`npm run test:browser`
|
||||
Run only the browser tests
|
||||
Run only the browser tests. Coverage reports are available for browser tests by running `npm run test:coverage`. You can find the results under the `coverage/` directory that will be created upon completion.
|
||||
|
||||
`npm run test:dev`
|
||||
Initializes an environment for debugging the browser tests. Includes an dedicated instance of the kibana server for building the test bundle, and a karma server. When running this task the build is optimized for the first time and then a karma-owned instance of the browser is opened. Click the "debug" button to open a new tab that executes the unit tests.
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
[[kibana-settings-reference]]
|
||||
|
||||
WARNING: Modifying the following settings can signficantly affect Kibana's performance and cause problems that are difficult to diagnose. Setting a property's value to a blank field will revert to the default behavior, which may not be compatible with other configuration settings. Deleting a custom setting removes it from Kibana permanently.
|
||||
WARNING: Modifying the following settings can signficantly affect Kibana's performance and cause problems that are
|
||||
difficult to diagnose. Setting a property's value to a blank field will revert to the default behavior, which may not be
|
||||
compatible with other configuration settings. Deleting a custom setting removes it from Kibana permanently.
|
||||
|
||||
.Kibana Settings Reference
|
||||
[horizontal]
|
||||
|
@ -8,30 +10,43 @@ WARNING: Modifying the following settings can signficantly affect Kibana's perfo
|
|||
`sort:options`:: Options for the Elasticsearch https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-sort.html[sort] parameter.
|
||||
`dateFormat`:: The format to use for displaying pretty-formatted dates.
|
||||
`dateFormat:tz`:: The timezone that Kibana uses. The default value of `Browser` uses the timezone detected by the browser.
|
||||
`dateFormat:scaled`:: These values define the format used to render ordered time-based data. Formatted timestamps must adapt to the interval between measurements. Keys are http://en.wikipedia.org/wiki/ISO_8601#Time_intervals[ISO8601 intervals].
|
||||
`dateFormat:scaled`:: These values define the format used to render ordered time-based data. Formatted timestamps must
|
||||
adapt to the interval between measurements. Keys are http://en.wikipedia.org/wiki/ISO_8601#Time_intervals[ISO8601 intervals].
|
||||
`defaultIndex`:: Default is `null`. This property specifies the default index.
|
||||
`metaFields`:: An array of fields outside of `_source`. Kibana merges these fields into the document when displaying the document.
|
||||
`metaFields`:: An array of fields outside of `_source`. Kibana merges these fields into the document when displaying the
|
||||
document.
|
||||
`discover:sampleSize`:: The number of rows to show in the Discover table.
|
||||
`doc_table:highlight`:: Highlight results in Discover and Saved Searches Dashboard. Highlighing makes request slow when working on big documents. Set this property to `false` to disable highlighting.
|
||||
`courier:maxSegmentCount`:: Kibana splits requests in the Discover app into segments to limit the size of requests sent to the Elasticsearch cluster. This setting constrains the length of the segment list. Long segment lists can significantly increase request processing time.
|
||||
`doc_table:highlight`:: Highlight results in Discover and Saved Searches Dashboard. Highlighing makes request slow when
|
||||
working on big documents. Set this property to `false` to disable highlighting.
|
||||
`courier:maxSegmentCount`:: Kibana splits requests in the Discover app into segments to limit the size of requests sent to
|
||||
the Elasticsearch cluster. This setting constrains the length of the segment list. Long segment lists can significantly
|
||||
increase request processing time.
|
||||
`fields:popularLimit`:: This setting governs how many of the top most popular fields are shown.
|
||||
`histogram:barTarget`:: When date histograms use the `auto` interval, Kibana attempts to generate this number of bars.
|
||||
`histogram:maxBars`:: Date histograms are not generated with more bars than the value of this property, scaling values when necessary.
|
||||
`visualization:tileMap:maxPrecision`:: The maximum geoHash precision displayed on tile maps: 7 is high, 10 is very high, 12 is the maximum. http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-geohashgrid-aggregation.html#_cell_dimensions_at_the_equator[Explanation of cell dimensions].
|
||||
`histogram:maxBars`:: Date histograms are not generated with more bars than the value of this property, scaling values
|
||||
when necessary.
|
||||
`visualization:tileMap:maxPrecision`:: The maximum geoHash precision displayed on tile maps: 7 is high, 10 is very high,
|
||||
12 is the maximum. http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-geohashgrid-aggregation.html#_cell_dimensions_at_the_equator[Explanation of cell dimensions].
|
||||
`visualization:tileMap:WMSdefaults`:: Default properties for the WMS map server support in the tile map.
|
||||
`visualization:colorMapping`:: Maps values to specified colors within visualizations.
|
||||
`visualization:loadingDelay`:: Time to wait before dimming visualizations during query.
|
||||
`csv:separator`:: A string that serves as the separator for exported values.
|
||||
`csv:quoteValues`:: Set this property to `true` to quote exported values.
|
||||
`history:limit`:: In fields that have history, such as query inputs, the value of this property limits how many recent values are shown.
|
||||
`shortDots:enable`:: Set this property to `true` to shorten long field names in visualizations. For example, instead of `foo.bar.baz`, show `f.b.baz`.
|
||||
`truncate:maxHeight`:: This property specifies the maximum height that a cell occupies in a table. A value of 0 disables truncation.
|
||||
`indexPattern:fieldMapping:lookBack`:: The value of this property sets the number of recent matching patterns to query the field mapping for index patterns with names that contain timestamps.
|
||||
`format:defaultTypeMap`:: A map of the default format name for each field type. Field types that are not explicitly mentioned use "_default_".
|
||||
`history:limit`:: In fields that have history, such as query inputs, the value of this property limits how many recent
|
||||
values are shown.
|
||||
`shortDots:enable`:: Set this property to `true` to shorten long field names in visualizations. For example, instead of
|
||||
`foo.bar.baz`, show `f.b.baz`.
|
||||
`truncate:maxHeight`:: This property specifies the maximum height that a cell occupies in a table. A value of 0 disables
|
||||
truncation.
|
||||
`indexPattern:fieldMapping:lookBack`:: The value of this property sets the number of recent matching patterns to query the
|
||||
field mapping for index patterns with names that contain timestamps.
|
||||
`format:defaultTypeMap`:: A map of the default format name for each field type. Field types that are not explicitly
|
||||
mentioned use "_default_".
|
||||
`format:number:defaultPattern`:: Default numeral format for the "number" format.
|
||||
`format:bytes:defaultPattern`:: Default numeral format for the "bytes" format.
|
||||
`format:percent:defaultPattern`:: Default numeral format for the "percent" format.
|
||||
`format:currency:defaultPattern`:: Default numeral format for the "currency" format.
|
||||
`savedObjects:perPage`:: The number of objects shown on each page of the list of saved objects. The default value is 5.
|
||||
`timepicker:timeDefaults`:: The default time filter selection.
|
||||
`timepicker:refreshIntervalDefaults`:: The time filter's default refresh interval.
|
||||
`dashboard:defaultDarkTheme`:: Set this property to `true` to make new dashboards use the dark theme by default.
|
||||
`dashboard:defaultDarkTheme`:: Set this property to `true` to make new dashboards use the dark theme by default.
|
||||
|
|
|
@ -45,6 +45,8 @@ sub-aggregation from the list of types.
|
|||
|
||||
You can use the up or down arrows to the right of the aggregation's type to change the aggregation's priority.
|
||||
|
||||
Enter a string in the *Custom Label* field to change the display label.
|
||||
|
||||
You can click the *Advanced* link to display more customization options for your metrics or bucket aggregation:
|
||||
|
||||
*Exclude Pattern*:: Specify a pattern in this field to exclude from the results.
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
A metric visualization displays a single number for each aggregation you select:
|
||||
|
||||
include::y-axis-aggs.asciidoc[]
|
||||
|
||||
You can click the *Advanced* link to display more customization options:
|
||||
|
||||
*JSON Input*:: A text field where you can add specific JSON-formatted properties to merge with the aggregation
|
||||
|
@ -17,7 +18,7 @@ NOTE: In Elasticsearch releases 1.4.3 and later, this functionality requires you
|
|||
|
||||
The availability of these options varies depending on the aggregation you choose.
|
||||
|
||||
Click the *Options* tab to change the font used to display the metrics.
|
||||
Click the *Options* tab to display the font size slider.
|
||||
|
||||
[float]
|
||||
[[metric-viewing-detailed-information]]
|
||||
|
|
|
@ -11,6 +11,8 @@ field. Select a field from the drop-down.
|
|||
*Unique Count*:: The {ref}search-aggregations-metrics-cardinality-aggregation.html[_cardinality_] aggregation returns
|
||||
the number of unique values in a field. Select a field from the drop-down.
|
||||
|
||||
Enter a string in the *Custom Label* field to change the display label.
|
||||
|
||||
The _buckets_ aggregations determine what information is being retrieved from your data set.
|
||||
|
||||
Before you choose a buckets aggregation, specify if you are splitting slices within a single chart or splitting into
|
||||
|
@ -57,6 +59,8 @@ aggregation's type to change the aggregation's priority.
|
|||
|
||||
include::color-picker.asciidoc[]
|
||||
|
||||
Enter a string in the *Custom Label* field to change the display label.
|
||||
|
||||
You can click the *Advanced* link to display more customization options for your metrics or bucket aggregation:
|
||||
|
||||
*Exclude Pattern*:: Specify a pattern in this field to exclude from the results.
|
||||
|
|
|
@ -65,6 +65,11 @@ bin/kibana plugin --remove marvel
|
|||
|
||||
You can also remove a plugin manually by deleting the plugin's subdirectory under the `installedPlugins` directory.
|
||||
|
||||
[float]
|
||||
=== Listing Installed Plugins
|
||||
|
||||
Use `--list` or `-l` option to list the currently installed plugins.
|
||||
|
||||
[float]
|
||||
=== Updating Plugins
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@ numeric field. Select a field from the drop-down.
|
|||
*Unique Count*:: The {ref}search-aggregations-metrics-cardinality-aggregation.html[_cardinality_] aggregation returns
|
||||
the number of unique values in a field. Select a field from the drop-down.
|
||||
|
||||
Enter a string in the *Custom Label* field to change the display label.
|
||||
|
||||
The _buckets_ aggregations determine what information is being retrieved from your data set.
|
||||
|
||||
Before you choose a buckets aggregation, specify if you are splitting the chart or displaying the buckets as *Geo
|
||||
|
@ -71,6 +73,8 @@ based on the geohash coordinates.
|
|||
|
||||
NOTE: By default, the *Change precision on map zoom* box is checked. Uncheck the box to disable this behavior.
|
||||
|
||||
Enter a string in the *Custom Label* field to change the display label.
|
||||
|
||||
You can click the *Advanced* link to display more customization options for your metrics or bucket aggregation:
|
||||
|
||||
*Exclude Pattern*:: Specify a pattern in this field to exclude from the results.
|
||||
|
|
|
@ -26,6 +26,8 @@ values field. Click *+Add* to add a values field.
|
|||
|
||||
You can add an aggregation by clicking the *+ Add Aggregation* button.
|
||||
|
||||
Enter a string in the *Custom Label* field to change the display label.
|
||||
|
||||
The _buckets_ aggregations determine what information is being retrieved from your data set.
|
||||
|
||||
Before you choose a buckets aggregation, specify if you are splitting slices within a single chart or splitting into
|
||||
|
@ -36,6 +38,8 @@ include::x-axis-aggs.asciidoc[]
|
|||
|
||||
include::color-picker.asciidoc[]
|
||||
|
||||
Enter a string in the *Custom Label* field to change the display label.
|
||||
|
||||
You can click the *Advanced* link to display more customization options for your metrics or bucket aggregation:
|
||||
|
||||
*Exclude Pattern*:: Specify a pattern in this field to exclude from the results.
|
||||
|
|
|
@ -28,8 +28,8 @@ remove a range.
|
|||
or bottom _n_ elements of a given field to display, ordered by count or a custom metric.
|
||||
*Filters*:: You can specify a set of {ref}/search-aggregations-bucket-filters-aggregation.html[_filters_] for the data.
|
||||
You can specify a filter as a query string or in JSON format, just as in the Discover search bar. Click *Add Filter* to
|
||||
add another filter. Click the image:images/labelbutton.png[] *label* button to open the label field, where you can type in a
|
||||
name to display on the visualization.
|
||||
add another filter. Click the image:images/labelbutton.png[Label button icon] *label* button to open the label field, where
|
||||
you can type in a name to display on the visualization.
|
||||
*Significant Terms*:: Displays the results of the experimental
|
||||
{ref}/search-aggregations-bucket-significantterms-aggregation.html[_significant terms_] aggregation.
|
||||
|
||||
|
@ -39,3 +39,5 @@ from the list of types.
|
|||
|
||||
When multiple aggregations are defined on a chart's axis, you can use the up or down arrows to the right of the
|
||||
aggregation's type to change the aggregation's priority.
|
||||
|
||||
Enter a string in the *Custom Label* field to change the display label.
|
||||
|
|
|
@ -22,3 +22,5 @@ from the drop-down, then specify one or more percentile rank values in the *Valu
|
|||
values field. Click *+Add* to add a values field.
|
||||
|
||||
You can add an aggregation by clicking the *+ Add Aggregation* button.
|
||||
|
||||
Enter a string in the *Custom Label* field to change the display label.
|
||||
|
|
|
@ -156,7 +156,7 @@
|
|||
"grunt-cli": "0.1.13",
|
||||
"grunt-contrib-clean": "0.6.0",
|
||||
"grunt-contrib-copy": "0.8.1",
|
||||
"grunt-esvm": "3.0.3",
|
||||
"grunt-esvm": "3.0.4",
|
||||
"grunt-karma": "0.12.0",
|
||||
"grunt-run": "0.5.0",
|
||||
"grunt-s3": "0.2.0-alpha.3",
|
||||
|
|
|
@ -33,6 +33,16 @@ module.exports = function ({ Plugin }) {
|
|||
}).default();
|
||||
},
|
||||
|
||||
uiExports: {
|
||||
injectDefaultVars(server, options) {
|
||||
return {
|
||||
esRequestTimeout: options.requestTimeout,
|
||||
esShardTimeout: options.shardTimeout,
|
||||
esApiVersion: options.apiVersion,
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
init(server, options) {
|
||||
const kibanaIndex = server.config().get('kibana.index');
|
||||
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import expect from 'expect.js';
|
||||
import util from 'util';
|
||||
import { format } from 'util';
|
||||
|
||||
import * as kbnTestServer from '../../../../../test/utils/kbn_server';
|
||||
|
||||
const format = util.format;
|
||||
|
||||
import fromRoot from '../../../../utils/from_root';
|
||||
|
||||
describe('plugins/elasticsearch', function () {
|
||||
describe('routes', function () {
|
||||
|
@ -13,7 +12,13 @@ describe('plugins/elasticsearch', function () {
|
|||
before(function () {
|
||||
this.timeout(60000); // sometimes waiting for server takes longer than 10
|
||||
|
||||
kbnServer = kbnTestServer.createServer();
|
||||
kbnServer = kbnTestServer.createServer({
|
||||
plugins: {
|
||||
scanDirs: [
|
||||
fromRoot('src/plugins')
|
||||
]
|
||||
}
|
||||
});
|
||||
return kbnServer.ready()
|
||||
.then(() => kbnServer.server.plugins.elasticsearch.waitUntilReady());
|
||||
});
|
||||
|
|
|
@ -67,7 +67,12 @@ module.exports = function (kibana) {
|
|||
description: 'define index patterns, change config, and more',
|
||||
icon: 'plugins/kibana/assets/settings.svg',
|
||||
}
|
||||
]
|
||||
],
|
||||
injectDefaultVars(server, options) {
|
||||
return {
|
||||
kbnIndex: options.index
|
||||
};
|
||||
},
|
||||
},
|
||||
|
||||
init: function (server, options) {
|
||||
|
|
|
@ -156,21 +156,3 @@ dashboard-grid {
|
|||
.dashboard-panel-picker > .list-group-item {
|
||||
border-top: 0;
|
||||
}
|
||||
|
||||
.dashboard-load {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.dashboard {
|
||||
&-info {
|
||||
line-height: 30px;
|
||||
padding: 0px 10px;
|
||||
border-bottom-left-radius: @border-radius-base;
|
||||
|
||||
|
||||
&-title {
|
||||
font-weight: bold;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,21 +39,21 @@ describe('createMappingsFromPatternFields', function () {
|
|||
let mappings = createMappingsFromPatternFields(testFields);
|
||||
|
||||
_.forEach(mappings, function (mapping) {
|
||||
if (mapping.type !== 'string') {
|
||||
if (mapping.type !== 'text') {
|
||||
expect(_.isEqual(mapping, {
|
||||
type: mapping.type,
|
||||
index: 'not_analyzed',
|
||||
index: true,
|
||||
doc_values: true
|
||||
})).to.be.ok();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should give strings a multi-field mapping', function () {
|
||||
it('should give strings a multi-field mapping with a "text" base type', function () {
|
||||
let mappings = createMappingsFromPatternFields(testFields);
|
||||
|
||||
_.forEach(mappings, function (mapping) {
|
||||
if (mapping.type === 'string') {
|
||||
if (mapping.type === 'text') {
|
||||
expect(mapping).to.have.property('fields');
|
||||
}
|
||||
});
|
||||
|
@ -68,7 +68,7 @@ describe('createMappingsFromPatternFields', function () {
|
|||
expect(mappings.geo.properties).to.have.property('coordinates');
|
||||
expect(_.isEqual(mappings.geo.properties.coordinates, {
|
||||
type: 'geo_point',
|
||||
index: 'not_analyzed',
|
||||
index: true,
|
||||
doc_values: true
|
||||
})).to.be.ok();
|
||||
});
|
||||
|
|
|
@ -13,10 +13,9 @@ module.exports = function createMappingsFromPatternFields(fields) {
|
|||
|
||||
if (field.type === 'string') {
|
||||
mapping = {
|
||||
type: 'string',
|
||||
index: 'analyzed',
|
||||
type: 'text',
|
||||
fields: {
|
||||
raw: {type: 'string', index: 'not_analyzed', doc_values: true, ignore_above: 256}
|
||||
raw: {type: 'keyword', ignore_above: 256}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -24,7 +23,7 @@ module.exports = function createMappingsFromPatternFields(fields) {
|
|||
const fieldType = field.type === 'number' ? 'double' : field.type;
|
||||
mapping = {
|
||||
type: fieldType,
|
||||
index: 'not_analyzed',
|
||||
index: true,
|
||||
doc_values: true
|
||||
};
|
||||
}
|
||||
|
|
|
@ -58,10 +58,9 @@ module.exports = function registerPost(server) {
|
|||
match: '*',
|
||||
match_mapping_type: 'string',
|
||||
mapping: {
|
||||
type: 'string',
|
||||
index: 'analyzed',
|
||||
type: 'text',
|
||||
fields: {
|
||||
raw: {type: 'string', index: 'not_analyzed', doc_values: true, ignore_above: 256}
|
||||
raw: {type: 'keyword', ignore_above: 256}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import _ from 'lodash';
|
||||
import Joi from 'joi';
|
||||
import { attempt, fromNode } from 'bluebird';
|
||||
import Bluebird, { attempt, fromNode } from 'bluebird';
|
||||
import { basename, resolve } from 'path';
|
||||
import { inherits } from 'util';
|
||||
|
||||
const extendInitFns = Symbol('extend plugin initialization');
|
||||
|
||||
const defaultConfigSchema = Joi.object({
|
||||
enabled: Joi.boolean().default(true)
|
||||
}).default();
|
||||
|
@ -57,6 +59,7 @@ module.exports = class Plugin {
|
|||
this.externalInit = opts.init || _.noop;
|
||||
this.getConfigSchema = opts.config || _.noop;
|
||||
this.init = _.once(this.init);
|
||||
this[extendInitFns] = [];
|
||||
|
||||
if (opts.publicDir === false) {
|
||||
this.publicDir = null;
|
||||
|
@ -98,14 +101,12 @@ module.exports = class Plugin {
|
|||
let { config } = kbnServer;
|
||||
|
||||
// setup the hapi register function and get on with it
|
||||
let register = (server, options, next) => {
|
||||
const asyncRegister = async (server, options) => {
|
||||
this.server = server;
|
||||
|
||||
// bind the server and options to all
|
||||
// apps created by this plugin
|
||||
for (let app of this.apps) {
|
||||
app.getInjectedVars = _.partial(app.getInjectedVars, server, options);
|
||||
}
|
||||
await Promise.all(this[extendInitFns].map(async fn => {
|
||||
await fn.call(this, server, options);
|
||||
}));
|
||||
|
||||
server.log(['plugins', 'debug'], {
|
||||
tmpl: 'Initializing plugin <%= plugin.id %>',
|
||||
|
@ -119,7 +120,11 @@ module.exports = class Plugin {
|
|||
this.status = kbnServer.status.create(`plugin:${this.id}`);
|
||||
server.expose('status', this.status);
|
||||
|
||||
attempt(this.externalInit, [server, options], this).nodeify(next);
|
||||
return await attempt(this.externalInit, [server, options], this);
|
||||
};
|
||||
|
||||
const register = (server, options, next) => {
|
||||
Bluebird.resolve(asyncRegister(server, options)).nodeify(next);
|
||||
};
|
||||
|
||||
register.attributes = { name: id, version: version };
|
||||
|
@ -138,6 +143,10 @@ module.exports = class Plugin {
|
|||
}
|
||||
}
|
||||
|
||||
extendInit(fn) {
|
||||
this[extendInitFns].push(fn);
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return this.pkg;
|
||||
}
|
||||
|
|
18
src/ui/__tests__/fixtures/plugin_async_foo/index.js
Normal file
18
src/ui/__tests__/fixtures/plugin_async_foo/index.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
import Bluebird from 'bluebird';
|
||||
|
||||
export default kibana => new kibana.Plugin({
|
||||
config(Joi) {
|
||||
return Joi.object().keys({
|
||||
enabled: Joi.boolean().default(true),
|
||||
delay: Joi.number().required(),
|
||||
shared: Joi.string(),
|
||||
}).default();
|
||||
},
|
||||
|
||||
uiExports: {
|
||||
async injectDefaultVars(server, options) {
|
||||
await Bluebird.delay(options.delay);
|
||||
return { shared: options.shared };
|
||||
}
|
||||
}
|
||||
});
|
4
src/ui/__tests__/fixtures/plugin_async_foo/package.json
Normal file
4
src/ui/__tests__/fixtures/plugin_async_foo/package.json
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "plugin_async_foo",
|
||||
"version": "0.0.0"
|
||||
}
|
14
src/ui/__tests__/fixtures/plugin_bar/index.js
Normal file
14
src/ui/__tests__/fixtures/plugin_bar/index.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
export default kibana => new kibana.Plugin({
|
||||
config(Joi) {
|
||||
return Joi.object().keys({
|
||||
enabled: Joi.boolean().default(true),
|
||||
shared: Joi.string()
|
||||
}).default();
|
||||
},
|
||||
|
||||
uiExports: {
|
||||
injectDefaultVars(server, options) {
|
||||
return { shared: options.shared };
|
||||
}
|
||||
}
|
||||
});
|
4
src/ui/__tests__/fixtures/plugin_bar/package.json
Normal file
4
src/ui/__tests__/fixtures/plugin_bar/package.json
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "plugin_bar",
|
||||
"version": "0.0.0"
|
||||
}
|
14
src/ui/__tests__/fixtures/plugin_foo/index.js
Normal file
14
src/ui/__tests__/fixtures/plugin_foo/index.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
export default kibana => new kibana.Plugin({
|
||||
config(Joi) {
|
||||
return Joi.object().keys({
|
||||
enabled: Joi.boolean().default(true),
|
||||
shared: Joi.string()
|
||||
}).default();
|
||||
},
|
||||
|
||||
uiExports: {
|
||||
injectDefaultVars(server, options) {
|
||||
return { shared: options.shared };
|
||||
}
|
||||
}
|
||||
});
|
4
src/ui/__tests__/fixtures/plugin_foo/package.json
Normal file
4
src/ui/__tests__/fixtures/plugin_foo/package.json
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "plugin_foo",
|
||||
"version": "0.0.0"
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
import expect from 'expect.js';
|
||||
import { resolve } from 'path';
|
||||
|
||||
import UiExports from '../ui_exports';
|
||||
import * as kbnTestServer from '../../../test/utils/kbn_server';
|
||||
|
||||
describe('UiExports', function () {
|
||||
describe('#find()', function () {
|
||||
|
@ -23,4 +25,83 @@ describe('UiExports', function () {
|
|||
expect(uiExports.find(['foo', 'bar'])).to.eql(['a', 'b', 'c']);
|
||||
});
|
||||
});
|
||||
//
|
||||
describe('#defaultInjectedVars', function () {
|
||||
context('two plugins, two sync', function () {
|
||||
this.slow(10000);
|
||||
this.timeout(60000);
|
||||
|
||||
let kbnServer;
|
||||
before(async function () {
|
||||
kbnServer = kbnTestServer.createServer({
|
||||
plugins: {
|
||||
paths: [
|
||||
resolve(__dirname, 'fixtures/plugin_bar'),
|
||||
resolve(__dirname, 'fixtures/plugin_foo')
|
||||
]
|
||||
},
|
||||
|
||||
plugin_foo: {
|
||||
shared: 'foo'
|
||||
},
|
||||
|
||||
plugin_bar: {
|
||||
shared: 'bar'
|
||||
}
|
||||
});
|
||||
|
||||
await kbnServer.ready();
|
||||
});
|
||||
|
||||
after(async function () {
|
||||
await kbnServer.close();
|
||||
});
|
||||
|
||||
it('merges the two plugins in the order they are loaded', function () {
|
||||
expect(kbnServer.uiExports.defaultInjectedVars).to.eql({
|
||||
shared: 'foo'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context('two plugins, one async', function () {
|
||||
this.slow(10000);
|
||||
this.timeout(60000);
|
||||
|
||||
let kbnServer;
|
||||
before(async function () {
|
||||
kbnServer = kbnTestServer.createServer({
|
||||
plugins: {
|
||||
scanDirs: [],
|
||||
paths: [
|
||||
resolve(__dirname, 'fixtures/plugin_async_foo'),
|
||||
resolve(__dirname, 'fixtures/plugin_foo')
|
||||
]
|
||||
},
|
||||
|
||||
plugin_async_foo: {
|
||||
delay: 500,
|
||||
shared: 'foo'
|
||||
},
|
||||
|
||||
plugin_bar: {
|
||||
shared: 'bar'
|
||||
}
|
||||
});
|
||||
|
||||
await kbnServer.ready();
|
||||
});
|
||||
|
||||
after(async function () {
|
||||
await kbnServer.close();
|
||||
});
|
||||
|
||||
it('merges the two plugins in the order they are loaded', function () {
|
||||
// even though plugin_async_foo loads 500ms later, it is still "first" to merge
|
||||
expect(kbnServer.uiExports.defaultInjectedVars).to.eql({
|
||||
shared: 'foo'
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -59,16 +59,6 @@ module.exports = async (kbnServer, server, config) => {
|
|||
}
|
||||
});
|
||||
|
||||
const defaultInjectedVars = {};
|
||||
if (config.has('kibana')) {
|
||||
defaultInjectedVars.kbnIndex = config.get('kibana.index');
|
||||
}
|
||||
if (config.has('elasticsearch')) {
|
||||
defaultInjectedVars.esRequestTimeout = config.get('elasticsearch.requestTimeout');
|
||||
defaultInjectedVars.esShardTimeout = config.get('elasticsearch.shardTimeout');
|
||||
defaultInjectedVars.esApiVersion = config.get('elasticsearch.apiVersion');
|
||||
}
|
||||
|
||||
server.decorate('reply', 'renderApp', function (app) {
|
||||
const payload = {
|
||||
app: app,
|
||||
|
@ -77,7 +67,7 @@ module.exports = async (kbnServer, server, config) => {
|
|||
buildNum: config.get('pkg.buildNum'),
|
||||
buildSha: config.get('pkg.buildSha'),
|
||||
basePath: config.get('server.basePath'),
|
||||
vars: defaults(app.getInjectedVars() || {}, defaultInjectedVars),
|
||||
vars: defaults(app.getInjectedVars() || {}, uiExports.defaultInjectedVars),
|
||||
};
|
||||
|
||||
return this.view(app.templateName, {
|
||||
|
|
|
@ -37,6 +37,11 @@ export default function AggTypeMetricPercentileRanksProvider(Private) {
|
|||
name: 'values',
|
||||
editor: valuesEditor,
|
||||
default: []
|
||||
},
|
||||
{
|
||||
write(agg, output) {
|
||||
output.params.keyed = false;
|
||||
}
|
||||
}
|
||||
],
|
||||
getResponseAggs: function (agg) {
|
||||
|
|
|
@ -35,6 +35,11 @@ export default function AggTypeMetricPercentilesProvider(Private) {
|
|||
name: 'percents',
|
||||
editor: percentsEditor,
|
||||
default: [1, 5, 25, 50, 75, 95, 99]
|
||||
},
|
||||
{
|
||||
write(agg, output) {
|
||||
output.params.keyed = false;
|
||||
}
|
||||
}
|
||||
],
|
||||
getResponseAggs: function (agg) {
|
||||
|
|
|
@ -85,8 +85,8 @@ describe('FieldFormat class', function () {
|
|||
var text = f.getConverterFor('text');
|
||||
var html = f.getConverterFor('html');
|
||||
expect(text).to.not.be(html);
|
||||
expect(text()).to.be('formatted');
|
||||
expect(html()).to.be('formatted');
|
||||
expect(text('formatted')).to.be('formatted');
|
||||
expect(html('formatted')).to.be('formatted');
|
||||
});
|
||||
|
||||
it('can be an object, with seperate text and html converter', function () {
|
||||
|
@ -99,8 +99,8 @@ describe('FieldFormat class', function () {
|
|||
var text = f.getConverterFor('text');
|
||||
var html = f.getConverterFor('html');
|
||||
expect(text).to.not.be(html);
|
||||
expect(text()).to.be('formatted text');
|
||||
expect(html()).to.be('formatted html');
|
||||
expect(text('formatted text')).to.be('formatted text');
|
||||
expect(html('formatted html')).to.be('formatted html');
|
||||
});
|
||||
|
||||
it('does not escape the output of the text converter', function () {
|
||||
|
@ -147,6 +147,11 @@ describe('FieldFormat class', function () {
|
|||
var f = new TestFormat();
|
||||
expect(f.convert('val', 'html')).to.be('html');
|
||||
});
|
||||
|
||||
it('formats a value as " - " when no value is specified', function () {
|
||||
var f = new TestFormat();
|
||||
expect(f.convert()).to.be(' - ');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -6,6 +6,10 @@ export default function contentTypesProvider(highlightFilter) {
|
|||
var types = {
|
||||
html: function (format, convert) {
|
||||
return function recurse(value, field, hit) {
|
||||
if (value == null) {
|
||||
return _.asPrettyString(value);
|
||||
}
|
||||
|
||||
if (!value || typeof value.map !== 'function') {
|
||||
return convert.call(format, value, field, hit);
|
||||
}
|
||||
|
|
|
@ -17,4 +17,14 @@ describe('String Format', function () {
|
|||
expect(string.convert('Zm9vYmFy')).to.be('foobar');
|
||||
});
|
||||
|
||||
it('convert a string to title case', function () {
|
||||
var StringFormat = fieldFormats.getType('string');
|
||||
var string = new StringFormat({
|
||||
transform: 'title'
|
||||
});
|
||||
expect(string.convert('PLEASE DO NOT SHOUT')).to.be('Please Do Not Shout');
|
||||
expect(string.convert('Mean, variance and standard_deviation.')).to.be('Mean, Variance And Standard_deviation.');
|
||||
expect(string.convert('Stay CALM!')).to.be('Stay Calm!');
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -36,12 +36,14 @@ export default function StringFormatProvider(Private) {
|
|||
{ id: false, name: '- none -' },
|
||||
{ id: 'lower', name: 'Lower Case' },
|
||||
{ id: 'upper', name: 'Upper Case' },
|
||||
{ id: 'title', name: 'Title Case' },
|
||||
{ id: 'short', name: 'Short Dots' },
|
||||
{ id: 'base64', name: 'Base64 Decode'}
|
||||
];
|
||||
|
||||
_String.sampleInputs = [
|
||||
'A Quick Brown Fox.',
|
||||
'STAY CALM!',
|
||||
'com.organizations.project.ClassName',
|
||||
'hostname.net',
|
||||
'SGVsbG8gd29ybGQ='
|
||||
|
@ -55,10 +57,15 @@ export default function StringFormatProvider(Private) {
|
|||
}
|
||||
};
|
||||
|
||||
_String.prototype._toTitleCase = function (val) {
|
||||
return val.replace(/\w\S*/g, txt => { return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); });
|
||||
};
|
||||
|
||||
_String.prototype._convert = function (val) {
|
||||
switch (this.param('transform')) {
|
||||
case 'lower': return String(val).toLowerCase();
|
||||
case 'upper': return String(val).toUpperCase();
|
||||
case 'title': return this._toTitleCase(val);
|
||||
case 'short': return _.shortenDottedString(val);
|
||||
case 'base64': return this._base64Decode(val);
|
||||
default: return _.asPrettyString(val);
|
||||
|
|
|
@ -142,8 +142,14 @@ a {
|
|||
|
||||
.kibana-nav-options {
|
||||
padding-bottom: 0;
|
||||
padding-right: 0px;
|
||||
|
||||
.kibana-nav-actions {
|
||||
margin-left: auto;
|
||||
|
||||
.button-group > :last-child {
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
.kibana-nav-info {
|
||||
line-height: 30px;
|
||||
|
|
|
@ -1,32 +1,12 @@
|
|||
<ul ng-show="timefilter.enabled" class="nav navbar-nav navbar-right navbar-timepicker">
|
||||
<li>
|
||||
<button
|
||||
ng-click="toggleRefresh()"
|
||||
ng-show="timefilter.refreshInterval.value > 0">
|
||||
<i class="fa" ng-class="timefilter.refreshInterval.pause ? 'fa-play' : 'fa-pause'"></i>
|
||||
</button>
|
||||
</li>
|
||||
|
||||
<li
|
||||
ng-show="timefilter.refreshInterval.value > 0 || configTemplate.is('interval') || configTemplate.is('filter')">
|
||||
|
||||
<button ng-click="configTemplate.toggle('interval')"
|
||||
ng-class="{active: configTemplate.is('interval') }"
|
||||
class="navbar-timepicker-auto-refresh-desc">
|
||||
<span ng-show="timefilter.refreshInterval.value === 0"><i class="fa fa-repeat"></i> Auto-refresh</span>
|
||||
<span ng-show="timefilter.refreshInterval.value > 0">{{timefilter.refreshInterval.display}}</span>
|
||||
</button>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<button ng-class="{active: configTemplate.is('filter')}"
|
||||
ng-click="configTemplate.toggle('filter')"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
class="navbar-timepicker-time-desc">
|
||||
<i aria-hidden="true" class="fa fa-clock-o"></i>
|
||||
<pretty-duration from="timefilter.time.from" to="timefilter.time.to"></pretty-duration>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<div ng-show="timefilter.enabled" class="button-group">
|
||||
<button ng-click="toggleRefresh()" ng-show="timefilter.refreshInterval.value > 0">
|
||||
<i class="fa fa-pause" ng-class="timefilter.refreshInterval.pause ? 'fa-play' : 'fa-pause'"></i>
|
||||
</button>
|
||||
<button ng-click="configTemplate.toggle('interval')" ng-class="{active: configTemplate.is('interval') }" class="navbar-timepicker-auto-refresh-desc" ng-show="timefilter.refreshInterval.value > 0 || configTemplate.is('interval') || configTemplate.is('filter')">
|
||||
<span ng-show="timefilter.refreshInterval.value === 0"><i class="fa fa-repeat"></i> Auto-refresh</span>
|
||||
<span ng-show="timefilter.refreshInterval.value > 0">{{timefilter.refreshInterval.display}}</span>
|
||||
</button><button ng-class="{active: configTemplate.is('filter')}" ng-click="configTemplate.toggle('filter')" aria-haspopup="true" aria-expanded="false" class="navbar-timepicker-time-desc">
|
||||
<i aria-hidden="true" class="fa fa-clock-o"></i>
|
||||
<pretty-duration from="timefilter.time.from" to="timefilter.time.to"></pretty-duration>
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -13,6 +13,7 @@ class UiExports {
|
|||
this.exportConsumer = _.memoize(this.exportConsumer);
|
||||
this.consumers = [];
|
||||
this.bundleProviders = [];
|
||||
this.defaultInjectedVars = {};
|
||||
}
|
||||
|
||||
consumePlugin(plugin) {
|
||||
|
@ -52,7 +53,17 @@ class UiExports {
|
|||
return (plugin, specs) => {
|
||||
const id = plugin.id;
|
||||
for (let spec of [].concat(specs || [])) {
|
||||
const app = this.apps.new({ id, ...spec });
|
||||
|
||||
let app = this.apps.new(_.defaults({}, spec, {
|
||||
id: plugin.id,
|
||||
urlBasePath: this.urlBasePath
|
||||
}));
|
||||
|
||||
plugin.extendInit((server, options) => { // eslint-disable-line no-loop-func
|
||||
const wrapped = app.getInjectedVars;
|
||||
app.getInjectedVars = () => wrapped.call(plugin, server, options);
|
||||
});
|
||||
|
||||
plugin.apps.add(app);
|
||||
}
|
||||
};
|
||||
|
@ -88,6 +99,13 @@ class UiExports {
|
|||
this.aliases[adhocType] = _.union(this.aliases[adhocType] || [], spec);
|
||||
});
|
||||
};
|
||||
|
||||
case 'injectDefaultVars':
|
||||
return (plugin, injector) => {
|
||||
plugin.extendInit(async (server, options) => {
|
||||
_.merge(this.defaultInjectedVars, await injector.call(plugin, server, options));
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
var path = require('path');
|
||||
import { resolve as resolveUrl } from 'url';
|
||||
|
||||
const URL = 'https://selenium-release.storage.googleapis.com/2.48/selenium-server-standalone-2.48.2.jar';
|
||||
const DIR = resolveUrl(URL, './');
|
||||
const FILE = URL.replace(DIR, '');
|
||||
|
||||
module.exports = function (grunt) {
|
||||
return {
|
||||
options: {
|
||||
selenium: {
|
||||
filename: 'selenium-server-standalone-2.48.2.jar',
|
||||
server: 'https://selenium-release.storage.googleapis.com/2.48/',
|
||||
filename: FILE,
|
||||
server: DIR,
|
||||
md5: 'b2784fc67c149d3c13c83d2108104689',
|
||||
directory: path.join(grunt.config.get('root'), 'selenium')
|
||||
path: path.join(grunt.config.get('root'), 'selenium', FILE)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -122,7 +122,7 @@ module.exports = function (grunt) {
|
|||
cmd: 'java',
|
||||
args: [
|
||||
'-jar',
|
||||
'selenium/selenium-server-standalone-2.48.2.jar',
|
||||
'<%= downloadSelenium.options.selenium.path %>',
|
||||
'-port',
|
||||
uiConfig.servers.webdriver.port,
|
||||
]
|
||||
|
@ -138,7 +138,7 @@ module.exports = function (grunt) {
|
|||
cmd: 'java',
|
||||
args: [
|
||||
'-jar',
|
||||
'selenium/selenium-server-standalone-2.48.2.jar',
|
||||
'<%= downloadSelenium.options.selenium.path %>',
|
||||
'-port',
|
||||
uiConfig.servers.webdriver.port,
|
||||
]
|
||||
|
|
|
@ -11,8 +11,9 @@ module.exports = function (grunt) {
|
|||
const done = this.async();
|
||||
const config = this.options();
|
||||
|
||||
const SELENIUM_FILE_PATH = path.join(config.selenium.directory, config.selenium.filename);
|
||||
const SELENIUM_DOWNLOAD_URL = config.selenium.server + config.selenium.filename;
|
||||
const FILE = config.selenium.path;
|
||||
const DIR = path.dirname(config.selenium.path);
|
||||
const URL = config.selenium.server + config.selenium.filename;
|
||||
|
||||
function validateDownload(path, expectedHash, success) {
|
||||
grunt.log.write('Validating hash...');
|
||||
|
@ -28,27 +29,27 @@ module.exports = function (grunt) {
|
|||
}
|
||||
|
||||
function downloadSelenium(success) {
|
||||
grunt.log.write(`Downloading ${SELENIUM_DOWNLOAD_URL}...`);
|
||||
request.get(SELENIUM_DOWNLOAD_URL)
|
||||
.pipe(fs.createWriteStream(SELENIUM_FILE_PATH))
|
||||
grunt.log.write(`Downloading ${URL}...`);
|
||||
request.get(URL)
|
||||
.pipe(fs.createWriteStream(FILE))
|
||||
.on('error', function downloadError(err) {
|
||||
grunt.fail.warn(err);
|
||||
})
|
||||
.on('finish', function downloadFinish() {
|
||||
grunt.log.writeln('done');
|
||||
validateDownload(SELENIUM_FILE_PATH, config.selenium.md5, success);
|
||||
validateDownload(FILE, config.selenium.md5, success);
|
||||
});
|
||||
}
|
||||
|
||||
function start() {
|
||||
try {
|
||||
fs.mkdirSync(config.selenium.directory);
|
||||
fs.mkdirSync(DIR);
|
||||
} catch (err) {
|
||||
if (err && err.code !== 'EEXIST') grunt.fail.warn(err);
|
||||
}
|
||||
|
||||
if (fs.existsSync(SELENIUM_FILE_PATH)) {
|
||||
validateDownload(SELENIUM_FILE_PATH, config.selenium.md5, done);
|
||||
if (fs.existsSync(FILE)) {
|
||||
validateDownload(FILE, config.selenium.md5, done);
|
||||
} else {
|
||||
downloadSelenium(done);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,18 @@
|
|||
import { compact } from 'lodash';
|
||||
import { delimiter } from 'path';
|
||||
|
||||
module.exports = function (grunt) {
|
||||
let { compact } = require('lodash');
|
||||
grunt.registerTask('jenkins', 'Jenkins build script', function () {
|
||||
process.env.JAVA_HOME = '/usr/lib/jvm/jdk8';
|
||||
// make sure JAVA_HOME points to JDK8
|
||||
const HOME = '/usr/lib/jvm/jdk8';
|
||||
process.env.JAVA_HOME = HOME;
|
||||
|
||||
// extend PATH to point to JDK8
|
||||
const path = process.env.PATH.split(delimiter);
|
||||
path.unshift(`${HOME}/bin`);
|
||||
process.env.PATH = path.join(delimiter);
|
||||
|
||||
// always build os packages on jenkins
|
||||
grunt.option('os-packages', true);
|
||||
|
||||
grunt.task.run(compact([
|
||||
|
|
|
@ -141,7 +141,7 @@ define(function (require) {
|
|||
+ ' Here’s...", "twitter:card": "summary", "twitter:image": "'
|
||||
+ 'http://IMAGES1.laweekly.com/imager/the-rapture-at-the-mayan-7-25/u/original/2463272/rapturetn05.jpg",'
|
||||
+ ' "twitter:site": "@laweekly" } machine.os:win 7 machine.ram:7,516,192,768 _id:AU_x3_g4GFA8no6QjkYX'
|
||||
+ ' _type:apache _index:logstash-2015.09.22 _score: relatedContent.article:modified_time:November 27th'
|
||||
+ ' _type:apache _index:logstash-2015.09.22 _score: - relatedContent.article:modified_time:November 27th'
|
||||
+ ' 2014, 16:00:51.000, November 27th 2014, 16:28:42.000 relatedContent.article:published_time:July 26th'
|
||||
+ ' 2007, 19:42:30.000, December 13th 2007, 20:19:35.000';
|
||||
return discoverPage.getDocTableIndex(1)
|
||||
|
@ -219,7 +219,7 @@ define(function (require) {
|
|||
+ ' "Arts", "og:site_name": "LA Weekly", "twitter:title": "Shopping Daze", "twitter:description": "LA'
|
||||
+ ' Weekly is the definitive source of information for news, music, movies, restaurants, reviews, and'
|
||||
+ ' events in Los Angeles.", "twitter:card": "summary", "twitter:site": "@laweekly" } machine.os:osx'
|
||||
+ ' machine.ram:15,032,385,536 _id:AU_x3_g3GFA8no6QjkFm _type:apache _index:logstash-2015.09.20 _score:'
|
||||
+ ' machine.ram:15,032,385,536 _id:AU_x3_g3GFA8no6QjkFm _type:apache _index:logstash-2015.09.20 _score: -'
|
||||
+ ' relatedContent.article:modified_time:October 28th 2014, 22:00:08.000, November 26th 2014,'
|
||||
+ ' 01:05:47.000, November 26th 2014, 03:52:35.000, November 26th 2014, 04:15:21.000, November 27th 2014,'
|
||||
+ ' 16:01:03.000 relatedContent.article:published_time:October 21st 2005, 01:10:25.000, March 5th 2006,'
|
||||
|
|
|
@ -326,6 +326,33 @@ define(function (require) {
|
|||
});
|
||||
},
|
||||
|
||||
clickLoadSavedVisButton: function clickLoadSavedVisButton() {
|
||||
return this.remote
|
||||
.setFindTimeout(defaultTimeout)
|
||||
.findDisplayedByCssSelector('button[aria-label="Load Saved Visualization"]')
|
||||
.click();
|
||||
},
|
||||
|
||||
filterVisByName: function filterVisByName(vizName) {
|
||||
return this.remote
|
||||
.findByCssSelector('input[name="filter"]')
|
||||
.click()
|
||||
// can't uses dashes in saved visualizations when filtering
|
||||
// or extended character sets
|
||||
// https://github.com/elastic/kibana/issues/6300
|
||||
.type(vizName.replace('-',' '));
|
||||
},
|
||||
|
||||
clickVisualizationByLinkText: function clickVisualizationByLinkText(vizName) {
|
||||
var self = this;
|
||||
common.debug('clickVisualizationByLinkText(' + vizName + ')');
|
||||
|
||||
return this.remote
|
||||
.setFindTimeout(defaultTimeout)
|
||||
.findByLinkText(vizName)
|
||||
.click();
|
||||
},
|
||||
|
||||
// this starts by clicking the Load Saved Viz button, not from the
|
||||
// bottom half of the "Create a new visualization Step 1" page
|
||||
loadSavedVisualization: function loadSavedVisualization(vizName) {
|
||||
|
|
|
@ -12,7 +12,12 @@ define(function (require) {
|
|||
});
|
||||
|
||||
bdd.afterEach(function () {
|
||||
return request.del('/kibana/ingest/logstash-*');
|
||||
return request.del('/kibana/ingest/logstash-*')
|
||||
.then(function () {
|
||||
return scenarioManager.client.indices.delete({
|
||||
index: 'logstash-*'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
bdd.it('should return 400 for an invalid payload', function invalidPayload() {
|
||||
|
@ -57,6 +62,29 @@ define(function (require) {
|
|||
});
|
||||
});
|
||||
|
||||
bdd.it('should successfully create new indices based on the template', function newIndices() {
|
||||
return request.post('/kibana/ingest')
|
||||
.send(createTestData())
|
||||
.expect(204)
|
||||
.then(function () {
|
||||
return scenarioManager.client.create({
|
||||
index: 'logstash-1',
|
||||
type: 'foo',
|
||||
id: '1',
|
||||
body: {
|
||||
ip: '192.168.1.1',
|
||||
'@timestamp': '2015-09-20T10:28:22.684Z',
|
||||
agent: 'Jack',
|
||||
bytes: 9001,
|
||||
geo: {coordinates: {lat: 43.07260861, lon: -92.61077833}}
|
||||
}
|
||||
})
|
||||
.then(function (response) {
|
||||
expect(response.created).to.be.ok();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
bdd.it('should provide defaults for field properties', function createTemplate() {
|
||||
return request.post('/kibana/ingest')
|
||||
.send(createTestData())
|
||||
|
@ -92,15 +120,15 @@ define(function (require) {
|
|||
.then(function (template) {
|
||||
var mappings = template['kibana-logstash-*'].mappings._default_.properties;
|
||||
expect(mappings).to.be.ok();
|
||||
expect(_.isEqual(mappings.ip, {index: 'not_analyzed', type: 'ip', doc_values: true})).to.be.ok();
|
||||
expect(_.isEqual(mappings['@timestamp'], {index: 'not_analyzed', type: 'date', doc_values: true})).to.be.ok();
|
||||
expect(_.isEqual(mappings.bytes, {index: 'not_analyzed', type: 'double', doc_values: true})).to.be.ok();
|
||||
expect(_.isEqual(mappings.ip, {index: true, type: 'ip', doc_values: true})).to.be.ok();
|
||||
expect(_.isEqual(mappings['@timestamp'], {index: true, type: 'date', doc_values: true})).to.be.ok();
|
||||
expect(_.isEqual(mappings.bytes, {index: true, type: 'double', doc_values: true})).to.be.ok();
|
||||
|
||||
// object fields are mapped as such, with individual mappings for each of their properties
|
||||
expect(_.isEqual(mappings.geo, {
|
||||
properties: {
|
||||
coordinates: {
|
||||
index: 'not_analyzed',
|
||||
index: true,
|
||||
type: 'geo_point',
|
||||
doc_values: true
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ import { defaultsDeep, set } from 'lodash';
|
|||
import { header as basicAuthHeader } from './base_auth';
|
||||
import { kibanaUser, kibanaServer } from '../shield';
|
||||
import KbnServer from '../../src/server/kbn_server';
|
||||
import fromRoot from '../../src/utils/from_root';
|
||||
import serverConfig from '../server_config';
|
||||
|
||||
const SERVER_DEFAULTS = {
|
||||
|
@ -16,11 +15,7 @@ const SERVER_DEFAULTS = {
|
|||
logging: {
|
||||
quiet: true
|
||||
},
|
||||
plugins: {
|
||||
scanDirs: [
|
||||
fromRoot('src/plugins')
|
||||
]
|
||||
},
|
||||
plugins: {},
|
||||
optimize: {
|
||||
enabled: false
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue