Merge branch 'master' of github.com:grafana/grafana

This commit is contained in:
Torkel Ödegaard 2018-09-21 09:24:03 +02:00
commit 785f35b1c9
21 changed files with 66 additions and 23 deletions

View File

@ -5,5 +5,5 @@
# root_url = %(protocol)s://%(domain)s:10081/grafana/ # root_url = %(protocol)s://%(domain)s:10081/grafana/
apacheproxy: apacheproxy:
build: blocks/apache_proxy build: docker/blocks/apache_proxy
network_mode: host network_mode: host

View File

@ -1,5 +1,5 @@
collectd: collectd:
build: blocks/collectd build: docker/blocks/collectd
environment: environment:
HOST_NAME: myserver HOST_NAME: myserver
GRAPHITE_HOST: graphite GRAPHITE_HOST: graphite

View File

@ -1,5 +1,5 @@
graphite09: graphite09:
build: blocks/graphite build: docker/blocks/graphite
ports: ports:
- "8080:80" - "8080:80"
- "2003:2003" - "2003:2003"

View File

@ -1,6 +1,6 @@
graphite: graphite:
build: build:
context: blocks/graphite1 context: docker/blocks/graphite1
args: args:
version: master version: master
ports: ports:

View File

@ -1,6 +1,6 @@
mssql: mssql:
build: build:
context: blocks/mssql/build context: docker/blocks/mssql/build
environment: environment:
ACCEPT_EULA: Y ACCEPT_EULA: Y
MSSQL_SA_PASSWORD: Password! MSSQL_SA_PASSWORD: Password!

View File

@ -1,6 +1,6 @@
mssqltests: mssqltests:
build: build:
context: blocks/mssql/build context: docker/blocks/mssql/build
environment: environment:
ACCEPT_EULA: Y ACCEPT_EULA: Y
MSSQL_SA_PASSWORD: Password! MSSQL_SA_PASSWORD: Password!

View File

@ -1,5 +1,5 @@
mysql_opendata: mysql_opendata:
build: blocks/mysql_opendata build: docker/blocks/mysql_opendata
environment: environment:
MYSQL_ROOT_PASSWORD: rootpass MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: testdata MYSQL_DATABASE: testdata

View File

@ -1,6 +1,6 @@
mysqltests: mysqltests:
build: build:
context: blocks/mysql_tests context: docker/blocks/mysql_tests
environment: environment:
MYSQL_ROOT_PASSWORD: rootpass MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: grafana_tests MYSQL_DATABASE: grafana_tests

View File

@ -5,5 +5,5 @@
# root_url = %(protocol)s://%(domain)s:10080/grafana/ # root_url = %(protocol)s://%(domain)s:10080/grafana/
nginxproxy: nginxproxy:
build: blocks/nginx_proxy build: docker/blocks/nginx_proxy
network_mode: host network_mode: host

View File

@ -1,5 +1,5 @@
openldap: openldap:
build: blocks/openldap build: docker/blocks/openldap
environment: environment:
SLAPD_PASSWORD: grafana SLAPD_PASSWORD: grafana
SLAPD_DOMAIN: grafana.org SLAPD_DOMAIN: grafana.org

View File

@ -1,6 +1,6 @@
postgrestest: postgrestest:
build: build:
context: blocks/postgres_tests context: docker/blocks/postgres_tests
environment: environment:
POSTGRES_USER: grafanatest POSTGRES_USER: grafanatest
POSTGRES_PASSWORD: grafanatest POSTGRES_PASSWORD: grafanatest

View File

@ -1,5 +1,5 @@
prometheus: prometheus:
build: blocks/prometheus build: docker/blocks/prometheus
network_mode: host network_mode: host
ports: ports:
- "9090:9090" - "9090:9090"
@ -25,7 +25,7 @@
- "9093:9093" - "9093:9093"
prometheus-random-data: prometheus-random-data:
build: blocks/prometheus_random_data build: docker/blocks/prometheus_random_data
network_mode: host network_mode: host
ports: ports:
- "8081:8080" - "8081:8080"

View File

@ -1,5 +1,5 @@
prometheus: prometheus:
build: blocks/prometheus2 build: docker/blocks/prometheus2
network_mode: host network_mode: host
ports: ports:
- "9090:9090" - "9090:9090"
@ -25,7 +25,7 @@
- "9093:9093" - "9093:9093"
prometheus-random-data: prometheus-random-data:
build: blocks/prometheus_random_data build: docker/blocks/prometheus_random_data
network_mode: host network_mode: host
ports: ports:
- "8081:8080" - "8081:8080"

View File

@ -1,5 +1,5 @@
prometheus: prometheus:
build: blocks/prometheus_mac build: docker/blocks/prometheus_mac
ports: ports:
- "9090:9090" - "9090:9090"
@ -21,6 +21,6 @@
- "9093:9093" - "9093:9093"
prometheus-random-data: prometheus-random-data:
build: blocks/prometheus_random_data build: docker/blocks/prometheus_random_data
ports: ports:
- "8081:8080" - "8081:8080"

View File

@ -32,11 +32,11 @@ permissions and org memberships.
## Grafana Auth ## Grafana Auth
Grafana of course has a built in user authentication system with password authenticaten enabled by default. You can Grafana of course has a built in user authentication system with password authentication enabled by default. You can
disable authentication by enabling anonymous access. You can also hide login form and only allow login through an auth disable authentication by enabling anonymous access. You can also hide login form and only allow login through an auth
provider (listed above). There is also options for allowing self sign up. provider (listed above). There is also options for allowing self sign up.
### Anonymous authenticaten ### Anonymous authentication
You can make Grafana accessible without any login required by enabling anonymous access in the configuration file. You can make Grafana accessible without any login required by enabling anonymous access in the configuration file.
@ -84,4 +84,3 @@ Set to the option detailed below to true to hide sign-out menu link. Useful if y
[auth] [auth]
disable_signout_menu = true disable_signout_menu = true
``` ```

View File

@ -5,7 +5,9 @@ const LegendItem = ({ series }) => (
<div className="graph-legend-icon"> <div className="graph-legend-icon">
<i className="fa fa-minus pointer" style={{ color: series.color }} /> <i className="fa fa-minus pointer" style={{ color: series.color }} />
</div> </div>
<a className="graph-legend-alias pointer">{series.alias}</a> <a className="graph-legend-alias pointer" title={series.alias}>
{series.alias}
</a>
</div> </div>
); );

View File

@ -255,6 +255,8 @@ class PromQueryField extends React.Component<PromQueryFieldProps, PromQueryField
// Keep this DOM-free for testing // Keep this DOM-free for testing
getTypeahead({ prefix, wrapperClasses, text }: PromTypeaheadInput): TypeaheadOutput { getTypeahead({ prefix, wrapperClasses, text }: PromTypeaheadInput): TypeaheadOutput {
// Syntax spans have 3 classes by default. More indicate a recognized token
const tokenRecognized = wrapperClasses.length > 3;
// Determine candidates by CSS context // Determine candidates by CSS context
if (_.includes(wrapperClasses, 'context-range')) { if (_.includes(wrapperClasses, 'context-range')) {
// Suggestions for metric[|] // Suggestions for metric[|]
@ -266,7 +268,7 @@ class PromQueryField extends React.Component<PromQueryFieldProps, PromQueryField
return this.getAggregationTypeahead.apply(this, arguments); return this.getAggregationTypeahead.apply(this, arguments);
} else if ( } else if (
// Non-empty but not inside known token // Non-empty but not inside known token
(prefix && !_.includes(wrapperClasses, 'token')) || (prefix && !tokenRecognized) ||
(prefix === '' && !text.match(/^[)\s]+$/)) || // Empty context or after ')' (prefix === '' && !text.match(/^[)\s]+$/)) || // Empty context or after ')'
text.match(/[+\-*/^%]/) // After binary operator text.match(/[+\-*/^%]/) // After binary operator
) { ) {

View File

@ -53,4 +53,22 @@ describe('braces', () => {
handler(event, change); handler(event, change);
expect(Plain.serialize(change.value)).toEqual('sum(rate(metric{namespace="dev", cluster="c1"}[2m]))'); expect(Plain.serialize(change.value)).toEqual('sum(rate(metric{namespace="dev", cluster="c1"}[2m]))');
}); });
it('removes closing brace when opening brace is removed', () => {
const change = Plain.deserialize('time()').change();
let event;
change.move(5);
event = new window.KeyboardEvent('keydown', { key: 'Backspace' });
handler(event, change);
expect(Plain.serialize(change.value)).toEqual('time');
});
it('keeps closing brace when opening brace is removed and inner values exist', () => {
const change = Plain.deserialize('time(value)').change();
let event;
change.move(5);
event = new window.KeyboardEvent('keydown', { key: 'Backspace' });
const handled = handler(event, change);
expect(handled).toBeFalsy();
});
}); });

View File

@ -43,6 +43,22 @@ export default function BracesPlugin() {
return true; return true;
} }
case 'Backspace': {
const text = value.anchorText.text;
const offset = value.anchorOffset;
const previousChar = text[offset - 1];
const nextChar = text[offset];
if (BRACES[previousChar] && BRACES[previousChar] === nextChar) {
event.preventDefault();
// Remove closing brace if directly following
change
.deleteBackward()
.deleteForward()
.focus();
return true;
}
}
default: { default: {
break; break;
} }

View File

@ -46,7 +46,7 @@ export function determineQueryHints(series: any[], datasource?: any): any[] {
// Check for monotony // Check for monotony
const datapoints: number[][] = s.datapoints; const datapoints: number[][] = s.datapoints;
if (datapoints.length > 1) { if (query.indexOf('rate(') === -1 && datapoints.length > 1) {
let increasing = false; let increasing = false;
const monotonic = datapoints.filter(dp => dp[0] !== null).every((dp, index) => { const monotonic = datapoints.filter(dp => dp[0] !== null).every((dp, index) => {
if (index === 0) { if (index === 0) {

View File

@ -247,6 +247,12 @@ describe('PrometheusDatasource', () => {
}); });
}); });
it('returns no rate hint for a monotonously increasing series that already has a rate', () => {
const series = [{ datapoints: [[23, 1000], [24, 1001]], query: 'rate(metric[1m])', responseIndex: 0 }];
const hints = determineQueryHints(series);
expect(hints).toEqual([null]);
});
it('returns a rate hint w/o action for a complex monotonously increasing series', () => { it('returns a rate hint w/o action for a complex monotonously increasing series', () => {
const series = [{ datapoints: [[23, 1000], [24, 1001]], query: 'sum(metric)', responseIndex: 0 }]; const series = [{ datapoints: [[23, 1000], [24, 1001]], query: 'sum(metric)', responseIndex: 0 }];
const hints = determineQueryHints(series); const hints = determineQueryHints(series);