mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
Merge branch 'master' of github.com:elastic/kibana into renameAllFiles
This commit is contained in:
commit
d77de4e1ca
18 changed files with 224 additions and 24 deletions
|
@ -218,7 +218,7 @@ So, you've been assigned a pull to review. What's that look like?
|
|||
|
||||
Remember, someone is blocked by a pull awaiting review, make it count. Be thorough, the more action items you catch in the first review, the less back and forth will be required, and the better chance the pull has of being successful. Don't you like success?
|
||||
|
||||
1. **Understand the issue** that is being fixed, or the feature being added. Check the description on the pull, and check out the related issue. If you don't understand something, ask the person the submitter for clarification.
|
||||
1. **Understand the issue** that is being fixed, or the feature being added. Check the description on the pull, and check out the related issue. If you don't understand something, ask the submitter for clarification.
|
||||
1. **Reproduce the bug** (or the lack of feature I guess?) in the destination branch, usually `master`. The referenced issue will help you here. If you're unable to reproduce the issue, contact the issue submitter for clarification
|
||||
1. **Check out the pull** and test it. Is the issue fixed? Does it have nasty side effects? Try to create suspect inputs. If it operates on the value of a field try things like: strings (including an empty string), null, numbers, dates. Try to think of edge cases that might break the code.
|
||||
1. **Merge the target branch**. It is possible that tests or the linter have been updated in the target branch since the pull was submitted. Merging the pull could cause core to start failing.
|
||||
|
|
|
@ -156,7 +156,7 @@
|
|||
"grunt-cli": "0.1.13",
|
||||
"grunt-contrib-clean": "0.6.0",
|
||||
"grunt-contrib-copy": "0.8.1",
|
||||
"grunt-esvm": "2.1.1",
|
||||
"grunt-esvm": "3.0.3",
|
||||
"grunt-karma": "0.12.0",
|
||||
"grunt-run": "0.5.0",
|
||||
"grunt-s3": "0.2.0-alpha.3",
|
||||
|
@ -174,7 +174,6 @@
|
|||
"karma-ie-launcher": "0.2.0",
|
||||
"karma-mocha": "0.2.0",
|
||||
"karma-safari-launcher": "0.1.1",
|
||||
"libesvm": "3.3.0",
|
||||
"license-checker": "3.1.0",
|
||||
"load-grunt-config": "0.19.1",
|
||||
"makelogs": "3.0.0-beta3",
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import _ from 'lodash';
|
||||
import Promise from 'bluebird';
|
||||
import sinon from 'sinon';
|
||||
import url from 'url';
|
||||
|
||||
import serverConfig from '../../../../../test/server_config';
|
||||
import checkEsVersion from '../check_es_version';
|
||||
|
||||
describe('plugins/elasticsearch', function () {
|
||||
|
@ -23,7 +25,7 @@ describe('plugins/elasticsearch', function () {
|
|||
status: {
|
||||
red: sinon.stub()
|
||||
},
|
||||
url: 'http://localhost:9210'
|
||||
url: url.format(serverConfig.servers.elasticsearch)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
import Promise from 'bluebird';
|
||||
import sinon from 'sinon';
|
||||
import expect from 'expect.js';
|
||||
import url from 'url';
|
||||
|
||||
const NoConnections = require('elasticsearch').errors.NoConnections;
|
||||
|
||||
import healthCheck from '../health_check';
|
||||
import serverConfig from '../../../../../test/server_config';
|
||||
|
||||
const esPort = serverConfig.servers.elasticsearch.port;
|
||||
const esUrl = url.format(serverConfig.servers.elasticsearch);
|
||||
|
||||
describe('plugins/elasticsearch', function () {
|
||||
describe('lib/health_check', function () {
|
||||
|
@ -39,7 +45,7 @@ describe('plugins/elasticsearch', function () {
|
|||
nodes: {
|
||||
'node-01': {
|
||||
version: '1.5.0',
|
||||
http_address: 'inet[/127.0.0.1:9210]',
|
||||
http_address: `inet[/127.0.0.1:${esPort}]`,
|
||||
ip: '127.0.0.1'
|
||||
}
|
||||
}
|
||||
|
@ -73,7 +79,7 @@ describe('plugins/elasticsearch', function () {
|
|||
|
||||
it('should set the cluster red if the ping fails, then to green', function () {
|
||||
|
||||
get.withArgs('elasticsearch.url').returns('http://localhost:9210');
|
||||
get.withArgs('elasticsearch.url').returns(esUrl);
|
||||
get.withArgs('elasticsearch.engineVersion').returns('^1.4.4');
|
||||
get.withArgs('kibana.index').returns('.my-kibana');
|
||||
client.ping.onCall(0).returns(Promise.reject(new NoConnections()));
|
||||
|
@ -85,7 +91,7 @@ describe('plugins/elasticsearch', function () {
|
|||
expect(plugin.status.yellow.args[0][0]).to.be('Waiting for Elasticsearch');
|
||||
sinon.assert.calledOnce(plugin.status.red);
|
||||
expect(plugin.status.red.args[0][0]).to.be(
|
||||
'Unable to connect to Elasticsearch at http://localhost:9210.'
|
||||
`Unable to connect to Elasticsearch at ${esUrl}.`
|
||||
);
|
||||
sinon.assert.calledTwice(client.ping);
|
||||
sinon.assert.calledOnce(client.nodes.info);
|
||||
|
@ -97,7 +103,7 @@ describe('plugins/elasticsearch', function () {
|
|||
});
|
||||
|
||||
it('should set the cluster red if the health check status is red, then to green', function () {
|
||||
get.withArgs('elasticsearch.url').returns('http://localhost:9210');
|
||||
get.withArgs('elasticsearch.url').returns(esUrl);
|
||||
get.withArgs('elasticsearch.engineVersion').returns('^1.4.4');
|
||||
get.withArgs('kibana.index').returns('.my-kibana');
|
||||
client.ping.returns(Promise.resolve());
|
||||
|
@ -120,7 +126,7 @@ describe('plugins/elasticsearch', function () {
|
|||
});
|
||||
|
||||
it('should set the cluster yellow if the health check timed_out and create index', function () {
|
||||
get.withArgs('elasticsearch.url').returns('http://localhost:9210');
|
||||
get.withArgs('elasticsearch.url').returns(esUrl);
|
||||
get.withArgs('elasticsearch.engineVersion').returns('^1.4.4');
|
||||
get.withArgs('kibana.index').returns('.my-kibana');
|
||||
client.ping.returns(Promise.resolve());
|
||||
|
|
|
@ -7,9 +7,10 @@ module.exports = function registerDelete(server) {
|
|||
path: '/api/kibana/ingest/{id}',
|
||||
method: 'DELETE',
|
||||
handler: function (req, reply) {
|
||||
const kibanaIndex = server.config().get('kibana.index');
|
||||
const callWithRequest = server.plugins.elasticsearch.callWithRequest;
|
||||
const deletePatternParams = {
|
||||
index: '.kibana',
|
||||
index: kibanaIndex,
|
||||
type: 'index-pattern',
|
||||
id: req.params.id
|
||||
};
|
||||
|
|
|
@ -17,6 +17,7 @@ module.exports = function registerPost(server) {
|
|||
}
|
||||
},
|
||||
handler: function (req, reply) {
|
||||
const kibanaIndex = server.config().get('kibana.index');
|
||||
const callWithRequest = server.plugins.elasticsearch.callWithRequest;
|
||||
const requestDocument = _.cloneDeep(req.payload);
|
||||
const indexPatternId = requestDocument.id;
|
||||
|
@ -36,7 +37,7 @@ module.exports = function registerPost(server) {
|
|||
}
|
||||
|
||||
const patternCreateParams = {
|
||||
index: '.kibana',
|
||||
index: kibanaIndex,
|
||||
type: 'index-pattern',
|
||||
id: indexPatternId,
|
||||
body: indexPattern
|
||||
|
@ -74,7 +75,7 @@ module.exports = function registerPost(server) {
|
|||
return callWithRequest(req, 'indices.putTemplate', templateParams)
|
||||
.catch((templateError) => {
|
||||
const deleteParams = {
|
||||
index: '.kibana',
|
||||
index: kibanaIndex,
|
||||
type: 'index-pattern',
|
||||
id: indexPatternId
|
||||
};
|
||||
|
|
|
@ -11,6 +11,7 @@ var config;
|
|||
var formatIds = [
|
||||
'bytes',
|
||||
'date',
|
||||
'duration',
|
||||
'ip',
|
||||
'number',
|
||||
'percent',
|
||||
|
|
50
src/ui/public/stringify/__tests__/_duration.js
Normal file
50
src/ui/public/stringify/__tests__/_duration.js
Normal file
|
@ -0,0 +1,50 @@
|
|||
import expect from 'expect.js';
|
||||
import ngMock from 'ng_mock';
|
||||
import RegistryFieldFormatsProvider from 'ui/registry/field_formats';
|
||||
|
||||
describe('Duration Format', function () {
|
||||
let fieldFormats;
|
||||
let DurationFormat;
|
||||
|
||||
beforeEach(ngMock.module('kibana'));
|
||||
beforeEach(ngMock.inject(function (Private) {
|
||||
fieldFormats = Private(RegistryFieldFormatsProvider);
|
||||
DurationFormat = fieldFormats.getType('duration');
|
||||
}));
|
||||
|
||||
test({ inputFormat: 'seconds', outputFormat: 'humanize' })
|
||||
(-60, 'minus a minute')
|
||||
(60, 'a minute')
|
||||
(125, '2 minutes');
|
||||
|
||||
test({ inputFormat: 'minutes', outputFormat: 'humanize' })
|
||||
(-60, 'minus an hour')
|
||||
(60, 'an hour')
|
||||
(125, '2 hours');
|
||||
|
||||
test({ inputFormat: 'minutes', outputFormat: 'asHours' }) // outputPrecision defaults to: 2
|
||||
(-60, '-1.00')
|
||||
(60, '1.00')
|
||||
(125, '2.08');
|
||||
|
||||
test({ inputFormat: 'seconds', outputFormat: 'asSeconds', outputPrecision: 0 })
|
||||
(-60, '-60')
|
||||
(60, '60')
|
||||
(125, '125');
|
||||
|
||||
test({ inputFormat: 'seconds', outputFormat: 'asSeconds', outputPrecision: 2 })
|
||||
(-60, '-60.00')
|
||||
(-32.333, '-32.33')
|
||||
(60, '60.00')
|
||||
(125, '125.00');
|
||||
|
||||
function test({ inputFormat, outputFormat, outputPrecision }) {
|
||||
return function testFixture(input, output) {
|
||||
it(`should format ${input} ${inputFormat} through ${outputFormat}${outputPrecision ? `, ${outputPrecision} decimals` : ''}`, () => {
|
||||
const duration = new DurationFormat({ inputFormat, outputFormat, outputPrecision });
|
||||
expect(duration.convert(input)).to.eql(output);
|
||||
});
|
||||
return testFixture;
|
||||
};
|
||||
}
|
||||
});
|
|
@ -5,6 +5,7 @@ import './_string';
|
|||
import './_url';
|
||||
import './_color';
|
||||
import './_date';
|
||||
import './_duration';
|
||||
import './_truncate';
|
||||
describe('Stringify Component', function () {
|
||||
});
|
||||
|
|
28
src/ui/public/stringify/editors/duration.html
Normal file
28
src/ui/public/stringify/editors/duration.html
Normal file
|
@ -0,0 +1,28 @@
|
|||
<div class="editor-duration">
|
||||
<div class="form-group">
|
||||
<label>Input Format</label>
|
||||
<select
|
||||
ng-model="editor.formatParams.inputFormat"
|
||||
ng-options="inputFormat.kind as inputFormat.text for inputFormat in editor.field.format.type.inputFormats"
|
||||
class="form-control">
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Output Format</label>
|
||||
<select
|
||||
ng-model="editor.formatParams.outputFormat"
|
||||
ng-options="outputFormat.method as outputFormat.text for outputFormat in editor.field.format.type.outputFormats"
|
||||
class="form-control">
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group" ng-hide="editor.field.format.isHuman()">
|
||||
<label>Decimal Places</label>
|
||||
<input type="number" min="0" max="20" ng-model="editor.formatParams.outputPrecision" class="form-control" />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<field-format-editor-samples
|
||||
ng-model="editor.formatParams"
|
||||
inputs="cntrl.sampleInputs">
|
||||
</field-format-editor-samples>
|
||||
</div>
|
10
src/ui/public/stringify/editors/duration.less
Normal file
10
src/ui/public/stringify/editors/duration.less
Normal file
|
@ -0,0 +1,10 @@
|
|||
.editor-duration {
|
||||
display: flex;
|
||||
> .form-group {
|
||||
flex: 1 1 1%;
|
||||
padding-right: 5px;
|
||||
&:last-child {
|
||||
padding-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ import fieldFormats from 'ui/registry/field_formats';
|
|||
import stringifyUrl from 'ui/stringify/types/url';
|
||||
import stringifyBytes from 'ui/stringify/types/bytes';
|
||||
import stringifyDate from 'ui/stringify/types/date';
|
||||
import stringifyDuration from 'ui/stringify/types/duration';
|
||||
import stringifyIp from 'ui/stringify/types/ip';
|
||||
import stringifyNumber from 'ui/stringify/types/number';
|
||||
import stringifyPercent from 'ui/stringify/types/percent';
|
||||
|
@ -9,9 +10,11 @@ import stringifyString from 'ui/stringify/types/string';
|
|||
import stringifySource from 'ui/stringify/types/source';
|
||||
import stringifyColor from 'ui/stringify/types/color';
|
||||
import stringifyTruncate from 'ui/stringify/types/truncate';
|
||||
|
||||
fieldFormats.register(stringifyUrl);
|
||||
fieldFormats.register(stringifyBytes);
|
||||
fieldFormats.register(stringifyDate);
|
||||
fieldFormats.register(stringifyDuration);
|
||||
fieldFormats.register(stringifyIp);
|
||||
fieldFormats.register(stringifyNumber);
|
||||
fieldFormats.register(stringifyPercent);
|
||||
|
|
98
src/ui/public/stringify/types/duration.js
Normal file
98
src/ui/public/stringify/types/duration.js
Normal file
|
@ -0,0 +1,98 @@
|
|||
import 'ui/stringify/editors/duration.less';
|
||||
import _ from 'lodash';
|
||||
import moment from 'moment';
|
||||
import IndexPatternsFieldFormatProvider from 'ui/index_patterns/_field_format/field_format';
|
||||
import durationTemplate from 'ui/stringify/editors/duration.html';
|
||||
|
||||
export default function DurationFormatProvider(Private) {
|
||||
const ratioToSeconds = {
|
||||
picoseconds: 0.000000000001,
|
||||
nanoseconds: 0.000000001,
|
||||
microseconds: 0.000001
|
||||
};
|
||||
const FieldFormat = Private(IndexPatternsFieldFormatProvider);
|
||||
const HUMAN_FRIENDLY = 'humanize';
|
||||
const DEFAULT_OUTPUT_PRECISION = 2;
|
||||
const DEFAULT_INPUT_FORMAT = { text: 'Seconds', kind: 'seconds' };
|
||||
const inputFormats = [
|
||||
{ text: 'Picoseconds', kind: 'picoseconds' },
|
||||
{ text: 'Nanoseconds', kind: 'nanoseconds' },
|
||||
{ text: 'Microseconds', kind: 'microseconds' },
|
||||
{ text: 'Milliseconds', kind: 'milliseconds' },
|
||||
DEFAULT_INPUT_FORMAT,
|
||||
{ text: 'Minutes', kind: 'minutes' },
|
||||
{ text: 'Hours', kind: 'hours' },
|
||||
{ text: 'Days', kind: 'days' },
|
||||
{ text: 'Weeks', kind: 'weeks' },
|
||||
{ text: 'Months', kind: 'months' },
|
||||
{ text: 'Years', kind: 'years' }
|
||||
];
|
||||
const DEFAULT_OUTPUT_FORMAT = { text: 'Human Readable', method: 'humanize' };
|
||||
const outputFormats = [
|
||||
DEFAULT_OUTPUT_FORMAT,
|
||||
{ text: 'Milliseconds', method: 'asMilliseconds' },
|
||||
{ text: 'Seconds', method: 'asSeconds' },
|
||||
{ text: 'Minutes', method: 'asMinutes' },
|
||||
{ text: 'Hours', method: 'asHours' },
|
||||
{ text: 'Days', method: 'asDays' },
|
||||
{ text: 'Weeks', method: 'asWeeks' },
|
||||
{ text: 'Months', method: 'asMonths' },
|
||||
{ text: 'Years', method: 'asYears' }
|
||||
];
|
||||
|
||||
class Duration extends FieldFormat {
|
||||
isHuman() {
|
||||
return this.param('outputFormat') === HUMAN_FRIENDLY;
|
||||
}
|
||||
_convert(val) {
|
||||
const inputFormat = this.param('inputFormat');
|
||||
const outputFormat = this.param('outputFormat');
|
||||
const outputPrecision = this.param('outputPrecision');
|
||||
const human = this.isHuman();
|
||||
const prefix = val < 0 && human ? 'minus ' : '';
|
||||
const duration = parseInputAsDuration(val, inputFormat);
|
||||
const formatted = duration[outputFormat]();
|
||||
const precise = human ? formatted : formatted.toFixed(outputPrecision);
|
||||
return prefix + precise;
|
||||
}
|
||||
}
|
||||
|
||||
Duration.id = 'duration';
|
||||
Duration.title = 'Duration';
|
||||
Duration.fieldType = 'number';
|
||||
|
||||
Duration.inputFormats = inputFormats;
|
||||
Duration.outputFormats = outputFormats;
|
||||
|
||||
Duration.editor = {
|
||||
template: durationTemplate,
|
||||
controllerAs: 'cntrl',
|
||||
controller($scope, $interval) {
|
||||
this.sampleInputs = [
|
||||
-123,
|
||||
1,
|
||||
12,
|
||||
123,
|
||||
658,
|
||||
1988,
|
||||
3857,
|
||||
123292,
|
||||
923528271
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
Duration.paramDefaults = {
|
||||
inputFormat: DEFAULT_INPUT_FORMAT.kind,
|
||||
outputFormat: DEFAULT_OUTPUT_FORMAT.method,
|
||||
outputPrecision: DEFAULT_OUTPUT_PRECISION
|
||||
};
|
||||
|
||||
return Duration;
|
||||
|
||||
function parseInputAsDuration(val, inputFormat) {
|
||||
const ratio = ratioToSeconds[inputFormat] || 1;
|
||||
const kind = inputFormat in ratioToSeconds ? 'seconds' : inputFormat;
|
||||
return moment.duration(val * ratio, kind);
|
||||
}
|
||||
};
|
|
@ -4,6 +4,9 @@ import Bluebird from 'bluebird';
|
|||
import 'elasticsearch-browser';
|
||||
import ngMock from 'ng_mock';
|
||||
import sinon from 'sinon';
|
||||
import url from 'url';
|
||||
|
||||
import serverConfig from '../../../../../test/server_config';
|
||||
|
||||
describe('Scanner', function () {
|
||||
let es;
|
||||
|
@ -11,7 +14,7 @@ describe('Scanner', function () {
|
|||
beforeEach(ngMock.module('kibana'));
|
||||
beforeEach(ngMock.inject(function (esFactory) {
|
||||
es = esFactory({
|
||||
host: 'http://localhost:9210',
|
||||
host: url.format(serverConfig.servers.elasticsearch),
|
||||
defer: function () {
|
||||
return Bluebird.defer();
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ module.exports = function (grunt) {
|
|||
var resolve = require('path').resolve;
|
||||
var directory = resolve(__dirname, '../../esvm');
|
||||
var dataDir = resolve(directory, 'data_dir');
|
||||
var uiConfig = require('../../test/server_config');
|
||||
var serverConfig = require('../../test/server_config');
|
||||
|
||||
return {
|
||||
options: {
|
||||
|
@ -14,11 +14,6 @@ module.exports = function (grunt) {
|
|||
},
|
||||
http: {
|
||||
port: 9200
|
||||
},
|
||||
marvel: {
|
||||
agent: {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -41,7 +36,7 @@ module.exports = function (grunt) {
|
|||
purge: true,
|
||||
config: {
|
||||
http: {
|
||||
port: 9210
|
||||
port: serverConfig.servers.elasticsearch.port
|
||||
},
|
||||
cluster: {
|
||||
name: 'esvm-test'
|
||||
|
@ -55,7 +50,7 @@ module.exports = function (grunt) {
|
|||
purge: true,
|
||||
config: {
|
||||
http: {
|
||||
port: uiConfig.servers.elasticsearch.port
|
||||
port: serverConfig.servers.elasticsearch.port
|
||||
},
|
||||
cluster: {
|
||||
name: 'esvm-ui'
|
||||
|
|
|
@ -23,7 +23,7 @@ module.exports = {
|
|||
}
|
||||
},
|
||||
apps: {
|
||||
statusPage: {
|
||||
status_page: {
|
||||
pathname: 'status'
|
||||
},
|
||||
discover: {
|
||||
|
|
|
@ -13,7 +13,7 @@ describe('getUrl', function () {
|
|||
expect(url).to.be('http://localhost/foo');
|
||||
});
|
||||
|
||||
it('should convert to a secure url with port', function () {
|
||||
it('should convert to a url with port', function () {
|
||||
var url = getUrl({
|
||||
protocol: 'http',
|
||||
hostname: 'localhost',
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import url from 'url';
|
||||
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 = {
|
||||
server: {
|
||||
|
@ -23,7 +25,7 @@ const SERVER_DEFAULTS = {
|
|||
enabled: false
|
||||
},
|
||||
elasticsearch: {
|
||||
url: 'http://localhost:9210',
|
||||
url: url.format(serverConfig.servers.elasticsearch),
|
||||
username: kibanaServer.username,
|
||||
password: kibanaServer.password
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue