mirror of
https://github.com/grafana/grafana.git
synced 2025-07-30 16:02:31 +08:00
Merge branch 'master' of github.com:grafana/grafana
Conflicts: examples/nginx-app/package.json examples/nginx-app/plugin.json
This commit is contained in:
@ -64,9 +64,19 @@ Name | Description
|
|||||||
`metrics(namespace)` | Returns a list of metrics in the namespace.
|
`metrics(namespace)` | Returns a list of metrics in the namespace.
|
||||||
`dimension_keys(namespace)` | Returns a list of dimension keys in the namespace.
|
`dimension_keys(namespace)` | Returns a list of dimension keys in the namespace.
|
||||||
`dimension_values(region, namespace, metric, dimension_key)` | Returns a list of dimension values matching the specified `region`, `namespace`, `metric` and `dimension_key`.
|
`dimension_values(region, namespace, metric, dimension_key)` | Returns a list of dimension values matching the specified `region`, `namespace`, `metric` and `dimension_key`.
|
||||||
|
`ebs_volume_ids(region, instance_id)` | Returns a list of volume id matching the specified `region`, `instance_id`.
|
||||||
|
`ec2_instance_attribute(region, attribute_name, filters)` | Returns a list of attribute matching the specified `region`, `attribute_name`, `filters`.
|
||||||
|
|
||||||
For details about the metrics CloudWatch provides, please refer to the [CloudWatch documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/CW_Support_For_AWS.html).
|
For details about the metrics CloudWatch provides, please refer to the [CloudWatch documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/CW_Support_For_AWS.html).
|
||||||
|
|
||||||
|
The `ec2_instance_attribute` query take `filters` in JSON format.
|
||||||
|
You can specify [pre-defined filters of ec2:DescribeInstances](http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeInstances.html).
|
||||||
|
Specify like `{ filter_name1: [ filter_value1 ], filter_name2: [ filter_value2 ] }`
|
||||||
|
|
||||||
|
Example `ec2_instance_attribute()` query
|
||||||
|
|
||||||
|
ec2_instance_attribute(us-east-1, InstanceId, { "tag:Environment": [ "production" ] })
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Cost
|
## Cost
|
||||||
|
@ -74,7 +74,7 @@ page_keywords: grafana, admin, http, api, documentation, datasource
|
|||||||
"jsonData":null
|
"jsonData":null
|
||||||
}
|
}
|
||||||
|
|
||||||
## Get a single data sources by Name
|
## Get a single data source by Name
|
||||||
|
|
||||||
`GET /api/datasources/name/:name`
|
`GET /api/datasources/name/:name`
|
||||||
|
|
||||||
@ -107,6 +107,26 @@ page_keywords: grafana, admin, http, api, documentation, datasource
|
|||||||
"jsonData":null
|
"jsonData":null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
## Get data source Id by Name
|
||||||
|
|
||||||
|
`GET /api/datasources/id/:name`
|
||||||
|
|
||||||
|
**Example Request**:
|
||||||
|
|
||||||
|
GET /api/datasources/id/test_datasource HTTP/1.1
|
||||||
|
Accept: application/json
|
||||||
|
Content-Type: application/json
|
||||||
|
Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
|
||||||
|
|
||||||
|
**Example Response**:
|
||||||
|
|
||||||
|
HTTP/1.1 200
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"id":1
|
||||||
|
}
|
||||||
|
|
||||||
## Create data source
|
## Create data source
|
||||||
|
|
||||||
`POST /api/datasources`
|
`POST /api/datasources`
|
||||||
|
@ -373,7 +373,7 @@ Set to `true` to enable auto sign up of users who do not exist in Grafana DB. De
|
|||||||
|
|
||||||
### provider
|
### provider
|
||||||
|
|
||||||
Valid values are `memory`, `file`, `mysql`, `postgres`, `memcache`. Default is `file`.
|
Valid values are `memory`, `file`, `mysql`, `postgres`, `memcache` or `redis`. Default is `file`.
|
||||||
|
|
||||||
### provider_config
|
### provider_config
|
||||||
|
|
||||||
@ -384,6 +384,7 @@ session provider you have configured.
|
|||||||
- **mysql:** go-sql-driver/mysql dsn config string, e.g. `user:password@tcp(127.0.0.1:3306)/database_name`
|
- **mysql:** go-sql-driver/mysql dsn config string, e.g. `user:password@tcp(127.0.0.1:3306)/database_name`
|
||||||
- **postgres:** ex: user=a password=b host=localhost port=5432 dbname=c sslmode=disable
|
- **postgres:** ex: user=a password=b host=localhost port=5432 dbname=c sslmode=disable
|
||||||
- **memcache:** ex: 127.0.0.1:11211
|
- **memcache:** ex: 127.0.0.1:11211
|
||||||
|
- **redis:** ex: `addr=127.0.0.1:6379,pool_size=100,db=grafana`
|
||||||
|
|
||||||
If you use MySQL or Postgres as the session store you need to create the
|
If you use MySQL or Postgres as the session store you need to create the
|
||||||
session table manually.
|
session table manually.
|
||||||
|
@ -6,7 +6,7 @@ page_keywords: grafana, ldap, configuration, documentation, integration
|
|||||||
|
|
||||||
# LDAP Integration
|
# LDAP Integration
|
||||||
|
|
||||||
Grafana 2.1 ships with a strong LDAP integration feature. The LDAP integration in Grafana allows your
|
Grafana (2.1 and newer) ships with a strong LDAP integration feature. The LDAP integration in Grafana allows your
|
||||||
Grafana users to login with their LDAP credentials. You can also specify mappings between LDAP
|
Grafana users to login with their LDAP credentials. You can also specify mappings between LDAP
|
||||||
group memberships and Grafana Organization user roles.
|
group memberships and Grafana Organization user roles.
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
## Example plugin implementations
|
## Example plugin implementations
|
||||||
|
|
||||||
[datasource-plugin-genericdatsource](https://github.com/grafana/datasource-plugin-genericdatasource/tree/3.0)
|
datasource:[simple-json-datasource](https://github.com/grafana/simple-json-datasource)
|
||||||
|
app: [example-app](https://github.com/grafana/example-app)
|
7
examples/nginx-app/.gitignore
vendored
7
examples/nginx-app/.gitignore
vendored
@ -1,7 +0,0 @@
|
|||||||
.DS_Store
|
|
||||||
|
|
||||||
node_modules
|
|
||||||
tmp/*
|
|
||||||
npm-debug.log
|
|
||||||
dist/*
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"disallowImplicitTypeConversion": ["string"],
|
|
||||||
"disallowKeywords": ["with"],
|
|
||||||
"disallowMultipleLineBreaks": true,
|
|
||||||
"disallowMixedSpacesAndTabs": true,
|
|
||||||
"disallowTrailingWhitespace": true,
|
|
||||||
"requireSpacesInFunctionExpression": {
|
|
||||||
"beforeOpeningCurlyBrace": true
|
|
||||||
},
|
|
||||||
"disallowSpacesInsideArrayBrackets": true,
|
|
||||||
"disallowSpacesInsideParentheses": true,
|
|
||||||
"validateIndentation": 2
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
{
|
|
||||||
"browser": true,
|
|
||||||
"esnext": true,
|
|
||||||
|
|
||||||
"bitwise":false,
|
|
||||||
"curly": true,
|
|
||||||
"eqnull": true,
|
|
||||||
"devel": true,
|
|
||||||
"eqeqeq": true,
|
|
||||||
"forin": false,
|
|
||||||
"immed": true,
|
|
||||||
"supernew": true,
|
|
||||||
"expr": true,
|
|
||||||
"indent": 2,
|
|
||||||
"latedef": true,
|
|
||||||
"newcap": true,
|
|
||||||
"noarg": true,
|
|
||||||
"noempty": true,
|
|
||||||
"undef": true,
|
|
||||||
"boss": true,
|
|
||||||
"trailing": true,
|
|
||||||
"laxbreak": true,
|
|
||||||
"laxcomma": true,
|
|
||||||
"sub": true,
|
|
||||||
"unused": true,
|
|
||||||
"maxdepth": 6,
|
|
||||||
"maxlen": 140,
|
|
||||||
|
|
||||||
"globals": {
|
|
||||||
"System": true,
|
|
||||||
"define": true,
|
|
||||||
"require": true,
|
|
||||||
"Chromath": false,
|
|
||||||
"setImmediate": true
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
module.exports = function(grunt) {
|
|
||||||
|
|
||||||
require('load-grunt-tasks')(grunt);
|
|
||||||
|
|
||||||
grunt.loadNpmTasks('grunt-execute');
|
|
||||||
grunt.loadNpmTasks('grunt-contrib-clean');
|
|
||||||
|
|
||||||
grunt.initConfig({
|
|
||||||
|
|
||||||
clean: ["dist"],
|
|
||||||
|
|
||||||
copy: {
|
|
||||||
src_to_dist: {
|
|
||||||
cwd: 'src',
|
|
||||||
expand: true,
|
|
||||||
src: ['**/*', '!**/*.js', '!**/*.scss'],
|
|
||||||
dest: 'dist'
|
|
||||||
},
|
|
||||||
pluginDef: {
|
|
||||||
expand: true,
|
|
||||||
src: ['plugin.json', 'readme.md'],
|
|
||||||
dest: 'dist',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
watch: {
|
|
||||||
rebuild_all: {
|
|
||||||
files: ['src/**/*', 'plugin.json', 'readme.md'],
|
|
||||||
tasks: ['default'],
|
|
||||||
options: {spawn: false}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
babel: {
|
|
||||||
options: {
|
|
||||||
sourceMap: true,
|
|
||||||
presets: ["es2015"],
|
|
||||||
plugins: ['transform-es2015-modules-systemjs', "transform-es2015-for-of"],
|
|
||||||
},
|
|
||||||
dist: {
|
|
||||||
files: [{
|
|
||||||
cwd: 'src',
|
|
||||||
expand: true,
|
|
||||||
src: ['**/*.js'],
|
|
||||||
dest: 'dist',
|
|
||||||
ext:'.js'
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
grunt.registerTask('default', ['clean', 'copy:src_to_dist', 'copy:pluginDef', 'babel']);
|
|
||||||
};
|
|
@ -1,37 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "kentik-app",
|
|
||||||
"private": true,
|
|
||||||
"version": "1.0.0",
|
|
||||||
"description": "",
|
|
||||||
"main": "index.js",
|
|
||||||
"scripts": {
|
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/raintank/kentik-app-poc.git"
|
|
||||||
},
|
|
||||||
"author": "",
|
|
||||||
"license": "ISC",
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/raintank/kentik-app-poc/issues"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"grunt": "~0.4.5",
|
|
||||||
"babel": "~6.5.1",
|
|
||||||
"grunt-babel": "~6.0.0",
|
|
||||||
"grunt-contrib-copy": "~0.8.2",
|
|
||||||
"grunt-contrib-watch": "^0.6.1",
|
|
||||||
"grunt-contrib-uglify": "~0.11.0",
|
|
||||||
"grunt-systemjs-builder": "^0.2.5",
|
|
||||||
"load-grunt-tasks": "~3.2.0",
|
|
||||||
"grunt-execute": "~0.2.2",
|
|
||||||
"grunt-contrib-clean": "~0.6.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"babel-plugin-transform-es2015-modules-systemjs": "^6.5.0",
|
|
||||||
"babel-preset-es2015": "^6.5.0",
|
|
||||||
"lodash": "~4.0.0"
|
|
||||||
},
|
|
||||||
"homepage": "https://github.com/raintank/kentik-app-poc#readme"
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
## Overview
|
|
||||||
|
|
||||||
This application is an example app.
|
|
||||||
|
|
||||||
### Awesome
|
|
||||||
|
|
||||||
Even though it does not have any features it is still pretty awesome.
|
|
@ -1,3 +0,0 @@
|
|||||||
<h3>
|
|
||||||
Nginx config!
|
|
||||||
</h3>
|
|
@ -1,6 +0,0 @@
|
|||||||
|
|
||||||
export class NginxAppConfigCtrl {
|
|
||||||
}
|
|
||||||
NginxAppConfigCtrl.templateUrl = 'components/config.html';
|
|
||||||
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
|||||||
<h3>
|
|
||||||
Logs page!
|
|
||||||
</h3>
|
|
@ -1,6 +0,0 @@
|
|||||||
|
|
||||||
export class LogsPageCtrl {
|
|
||||||
}
|
|
||||||
LogsPageCtrl.templateUrl = 'components/logs.html';
|
|
||||||
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
|||||||
<h3>
|
|
||||||
Stream page!
|
|
||||||
</h3>
|
|
@ -1,6 +0,0 @@
|
|||||||
|
|
||||||
export class StreamPageCtrl {
|
|
||||||
}
|
|
||||||
StreamPageCtrl.templateUrl = 'components/stream.html';
|
|
||||||
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
|||||||
export default class NginxDatasource {
|
|
||||||
|
|
||||||
constructor() {}
|
|
||||||
|
|
||||||
query(options) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
testDatasource() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
import {Datasource} from './datasource';
|
|
||||||
|
|
||||||
export {
|
|
||||||
Datasource
|
|
||||||
};
|
|
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "datasource",
|
|
||||||
"name": "Nginx Datasource",
|
|
||||||
"id": "nginx-datasource"
|
|
||||||
}
|
|
Binary file not shown.
Before Width: | Height: | Size: 14 KiB |
Binary file not shown.
Before Width: | Height: | Size: 6.3 KiB |
@ -1,9 +0,0 @@
|
|||||||
import {LogsPageCtrl} from './components/logs';
|
|
||||||
import {StreamPageCtrl} from './components/stream';
|
|
||||||
import {NginxAppConfigCtrl} from './components/config';
|
|
||||||
|
|
||||||
export {
|
|
||||||
NginxAppConfigCtrl as ConfigCtrl,
|
|
||||||
StreamPageCtrl,
|
|
||||||
LogsPageCtrl
|
|
||||||
};
|
|
@ -1,15 +0,0 @@
|
|||||||
import {PanelCtrl} from 'app/plugins/sdk';
|
|
||||||
|
|
||||||
class NginxPanelCtrl extends PanelCtrl {
|
|
||||||
|
|
||||||
constructor($scope, $injector) {
|
|
||||||
super($scope, $injector);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
NginxPanelCtrl.template = '<h2>nginx!</h2>';
|
|
||||||
|
|
||||||
export {
|
|
||||||
NginxPanelCtrl as PanelCtrl
|
|
||||||
};
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "panel",
|
|
||||||
"name": "Nginx Panel",
|
|
||||||
"id": "nginx-panel"
|
|
||||||
}
|
|
@ -167,11 +167,10 @@ func Register(r *macaron.Macaron) {
|
|||||||
r.Put("/:id", bind(m.UpdateDataSourceCommand{}), UpdateDataSource)
|
r.Put("/:id", bind(m.UpdateDataSourceCommand{}), UpdateDataSource)
|
||||||
r.Delete("/:id", DeleteDataSource)
|
r.Delete("/:id", DeleteDataSource)
|
||||||
r.Get("/:id", wrap(GetDataSourceById))
|
r.Get("/:id", wrap(GetDataSourceById))
|
||||||
|
r.Get("/name/:name", wrap(GetDataSourceByName))
|
||||||
}, reqOrgAdmin)
|
}, reqOrgAdmin)
|
||||||
|
|
||||||
r.Group("/datasources/name/:name", func() {
|
r.Get("/datasources/id/:name", wrap(GetDataSourceIdByName), reqSignedIn)
|
||||||
r.Get("/", wrap(GetDataSourceByName))
|
|
||||||
}, reqOrgAdmin)
|
|
||||||
|
|
||||||
r.Group("/plugins", func() {
|
r.Group("/plugins", func() {
|
||||||
r.Get("/", wrap(GetPluginList))
|
r.Get("/", wrap(GetPluginList))
|
||||||
|
@ -55,8 +55,10 @@ func init() {
|
|||||||
"S3BytesWritten", "S3BytesRead", "HDFSUtilization", "HDFSBytesRead", "HDFSBytesWritten", "MissingBlocks", "CorruptBlocks", "TotalLoad", "MemoryTotalMB", "MemoryReservedMB", "MemoryAvailableMB", "MemoryAllocatedMB", "PendingDeletionBlocks", "UnderReplicatedBlocks", "DfsPendingReplicationBlocks", "CapacityRemainingGB",
|
"S3BytesWritten", "S3BytesRead", "HDFSUtilization", "HDFSBytesRead", "HDFSBytesWritten", "MissingBlocks", "CorruptBlocks", "TotalLoad", "MemoryTotalMB", "MemoryReservedMB", "MemoryAvailableMB", "MemoryAllocatedMB", "PendingDeletionBlocks", "UnderReplicatedBlocks", "DfsPendingReplicationBlocks", "CapacityRemainingGB",
|
||||||
"HbaseBackupFailed", "MostRecentBackupDuration", "TimeSinceLastSuccessfulBackup"},
|
"HbaseBackupFailed", "MostRecentBackupDuration", "TimeSinceLastSuccessfulBackup"},
|
||||||
"AWS/ES": {"ClusterStatus.green", "ClusterStatus.yellow", "ClusterStatus.red", "Nodes", "SearchableDocuments", "DeletedDocuments", "CPUUtilization", "FreeStorageSpace", "JVMMemoryPressure", "AutomatedSnapshotFailure", "MasterCPUUtilization", "MasterFreeStorageSpace", "MasterJVMMemoryPressure", "ReadLatency", "WriteLatency", "ReadThroughput", "WriteThroughput", "DiskQueueLength", "ReadIOPS", "WriteIOPS"},
|
"AWS/ES": {"ClusterStatus.green", "ClusterStatus.yellow", "ClusterStatus.red", "Nodes", "SearchableDocuments", "DeletedDocuments", "CPUUtilization", "FreeStorageSpace", "JVMMemoryPressure", "AutomatedSnapshotFailure", "MasterCPUUtilization", "MasterFreeStorageSpace", "MasterJVMMemoryPressure", "ReadLatency", "WriteLatency", "ReadThroughput", "WriteThroughput", "DiskQueueLength", "ReadIOPS", "WriteIOPS"},
|
||||||
|
"AWS/Events": {"Invocations", "FailedInvocations", "TriggeredRules", "MatchedEvents", "ThrottledRules"},
|
||||||
"AWS/Kinesis": {"PutRecord.Bytes", "PutRecord.Latency", "PutRecord.Success", "PutRecords.Bytes", "PutRecords.Latency", "PutRecords.Records", "PutRecords.Success", "IncomingBytes", "IncomingRecords", "GetRecords.Bytes", "GetRecords.IteratorAgeMilliseconds", "GetRecords.Latency", "GetRecords.Success"},
|
"AWS/Kinesis": {"PutRecord.Bytes", "PutRecord.Latency", "PutRecord.Success", "PutRecords.Bytes", "PutRecords.Latency", "PutRecords.Records", "PutRecords.Success", "IncomingBytes", "IncomingRecords", "GetRecords.Bytes", "GetRecords.IteratorAgeMilliseconds", "GetRecords.Latency", "GetRecords.Success"},
|
||||||
"AWS/Lambda": {"Invocations", "Errors", "Duration", "Throttles"},
|
"AWS/Lambda": {"Invocations", "Errors", "Duration", "Throttles"},
|
||||||
|
"AWS/Logs": {"IncomingBytes", "IncomingLogEvents", "ForwardedBytes", "ForwardedLogEvents", "DeliveryErrors", "DeliveryThrottling"},
|
||||||
"AWS/ML": {"PredictCount", "PredictFailureCount"},
|
"AWS/ML": {"PredictCount", "PredictFailureCount"},
|
||||||
"AWS/OpsWorks": {"cpu_idle", "cpu_nice", "cpu_system", "cpu_user", "cpu_waitio", "load_1", "load_5", "load_15", "memory_buffers", "memory_cached", "memory_free", "memory_swap", "memory_total", "memory_used", "procs"},
|
"AWS/OpsWorks": {"cpu_idle", "cpu_nice", "cpu_system", "cpu_user", "cpu_waitio", "load_1", "load_5", "load_15", "memory_buffers", "memory_cached", "memory_free", "memory_swap", "memory_total", "memory_used", "procs"},
|
||||||
"AWS/Redshift": {"CPUUtilization", "DatabaseConnections", "HealthStatus", "MaintenanceMode", "NetworkReceiveThroughput", "NetworkTransmitThroughput", "PercentageDiskSpaceUsed", "ReadIOPS", "ReadLatency", "ReadThroughput", "WriteIOPS", "WriteLatency", "WriteThroughput"},
|
"AWS/Redshift": {"CPUUtilization", "DatabaseConnections", "HealthStatus", "MaintenanceMode", "NetworkReceiveThroughput", "NetworkTransmitThroughput", "PercentageDiskSpaceUsed", "ReadIOPS", "ReadLatency", "ReadThroughput", "WriteIOPS", "WriteLatency", "WriteThroughput"},
|
||||||
@ -85,8 +87,10 @@ func init() {
|
|||||||
"AWS/ELB": {"LoadBalancerName", "AvailabilityZone"},
|
"AWS/ELB": {"LoadBalancerName", "AvailabilityZone"},
|
||||||
"AWS/ElasticMapReduce": {"ClusterId", "JobFlowId", "JobId"},
|
"AWS/ElasticMapReduce": {"ClusterId", "JobFlowId", "JobId"},
|
||||||
"AWS/ES": {},
|
"AWS/ES": {},
|
||||||
|
"AWS/Events": {"RuleName"},
|
||||||
"AWS/Kinesis": {"StreamName"},
|
"AWS/Kinesis": {"StreamName"},
|
||||||
"AWS/Lambda": {"FunctionName"},
|
"AWS/Lambda": {"FunctionName"},
|
||||||
|
"AWS/Logs": {"LogGroupName", "DestinationType", "FilterName"},
|
||||||
"AWS/ML": {"MLModelId", "RequestMode"},
|
"AWS/ML": {"MLModelId", "RequestMode"},
|
||||||
"AWS/OpsWorks": {"StackId", "LayerId", "InstanceId"},
|
"AWS/OpsWorks": {"StackId", "LayerId", "InstanceId"},
|
||||||
"AWS/Redshift": {"NodeID", "ClusterIdentifier"},
|
"AWS/Redshift": {"NodeID", "ClusterIdentifier"},
|
||||||
|
@ -116,6 +116,25 @@ func GetDataSourceByName(c *middleware.Context) Response {
|
|||||||
return Json(200, &dtos)
|
return Json(200, &dtos)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get /api/datasources/id/:name
|
||||||
|
func GetDataSourceIdByName(c *middleware.Context) Response {
|
||||||
|
query := m.GetDataSourceByNameQuery{Name: c.Params(":name"), OrgId: c.OrgId}
|
||||||
|
|
||||||
|
if err := bus.Dispatch(&query); err != nil {
|
||||||
|
if err == m.ErrDataSourceNotFound {
|
||||||
|
return ApiError(404, "Data source not found", nil)
|
||||||
|
}
|
||||||
|
return ApiError(500, "Failed to query datasources", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ds := query.Result
|
||||||
|
dtos := dtos.AnyId{
|
||||||
|
Id: ds.Id,
|
||||||
|
}
|
||||||
|
|
||||||
|
return Json(200, &dtos)
|
||||||
|
}
|
||||||
|
|
||||||
func convertModelToDtos(ds m.DataSource) dtos.DataSource {
|
func convertModelToDtos(ds m.DataSource) dtos.DataSource {
|
||||||
return dtos.DataSource{
|
return dtos.DataSource{
|
||||||
Id: ds.Id,
|
Id: ds.Id,
|
||||||
|
@ -10,6 +10,10 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type AnyId struct {
|
||||||
|
Id int64 `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
type LoginCommand struct {
|
type LoginCommand struct {
|
||||||
User string `json:"user" binding:"Required"`
|
User string `json:"user" binding:"Required"`
|
||||||
Password string `json:"password" binding:"Required"`
|
Password string `json:"password" binding:"Required"`
|
||||||
|
@ -48,18 +48,23 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) {
|
|||||||
data.User.LightTheme = true
|
data.User.LightTheme = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dashboardChildNavs := []*dtos.NavLink{
|
||||||
|
{Text: "Home", Url: setting.AppSubUrl + "/"},
|
||||||
|
{Text: "Playlists", Url: setting.AppSubUrl + "/playlists"},
|
||||||
|
{Text: "Snapshots", Url: setting.AppSubUrl + "/dashboard/snapshots"},
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.OrgRole == m.ROLE_ADMIN || c.OrgRole == m.ROLE_EDITOR {
|
||||||
|
dashboardChildNavs = append(dashboardChildNavs, &dtos.NavLink{Divider: true})
|
||||||
|
dashboardChildNavs = append(dashboardChildNavs, &dtos.NavLink{Text: "New", Url: setting.AppSubUrl + "/dashboard/new"})
|
||||||
|
dashboardChildNavs = append(dashboardChildNavs, &dtos.NavLink{Text: "Import", Url: setting.AppSubUrl + "/import/dashboard"})
|
||||||
|
}
|
||||||
|
|
||||||
data.MainNavLinks = append(data.MainNavLinks, &dtos.NavLink{
|
data.MainNavLinks = append(data.MainNavLinks, &dtos.NavLink{
|
||||||
Text: "Dashboards",
|
Text: "Dashboards",
|
||||||
Icon: "icon-gf icon-gf-dashboard",
|
Icon: "icon-gf icon-gf-dashboard",
|
||||||
Url: setting.AppSubUrl + "/",
|
Url: setting.AppSubUrl + "/",
|
||||||
Children: []*dtos.NavLink{
|
Children: dashboardChildNavs,
|
||||||
{Text: "Home", Url: setting.AppSubUrl + "/"},
|
|
||||||
{Text: "Playlists", Url: setting.AppSubUrl + "/playlists"},
|
|
||||||
{Text: "Snapshots", Url: setting.AppSubUrl + "/dashboard/snapshots"},
|
|
||||||
{Divider: true},
|
|
||||||
{Text: "New", Url: setting.AppSubUrl + "/dashboard/new"},
|
|
||||||
{Text: "Import", Url: setting.AppSubUrl + "/import/dashboard"},
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if c.OrgRole == m.ROLE_ADMIN {
|
if c.OrgRole == m.ROLE_ADMIN {
|
||||||
|
@ -31,6 +31,7 @@ func RenderToPng(c *middleware.Context) {
|
|||||||
Width: queryReader.Get("width", "800"),
|
Width: queryReader.Get("width", "800"),
|
||||||
Height: queryReader.Get("height", "400"),
|
Height: queryReader.Get("height", "400"),
|
||||||
SessionId: c.Session.ID(),
|
SessionId: c.Session.ID(),
|
||||||
|
Timeout: queryReader.Get("timeout", "15"),
|
||||||
}
|
}
|
||||||
|
|
||||||
renderOpts.Url = setting.ToAbsUrl(renderOpts.Url)
|
renderOpts.Url = setting.ToAbsUrl(renderOpts.Url)
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"archive/zip"
|
"archive/zip"
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"github.com/grafana/grafana/pkg/cmd/grafana-cli/log"
|
"github.com/grafana/grafana/pkg/cmd/grafana-cli/log"
|
||||||
m "github.com/grafana/grafana/pkg/cmd/grafana-cli/models"
|
m "github.com/grafana/grafana/pkg/cmd/grafana-cli/models"
|
||||||
s "github.com/grafana/grafana/pkg/cmd/grafana-cli/services"
|
s "github.com/grafana/grafana/pkg/cmd/grafana-cli/services"
|
||||||
@ -64,32 +65,33 @@ func InstallPlugin(pluginName, version string, c CommandLine) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
url := v.Url
|
|
||||||
commit := v.Commit
|
|
||||||
|
|
||||||
if version == "" {
|
if version == "" {
|
||||||
version = v.Version
|
version = v.Version
|
||||||
}
|
}
|
||||||
|
|
||||||
downloadURL := url + "/archive/" + commit + ".zip"
|
downloadURL := fmt.Sprintf("%s/%s/versions/%s/download",
|
||||||
|
c.GlobalString("repo"),
|
||||||
|
pluginName,
|
||||||
|
version)
|
||||||
|
|
||||||
log.Infof("installing %v @ %v\n", plugin.Id, version)
|
log.Infof("installing %v @ %v\n", plugin.Id, version)
|
||||||
log.Infof("from url: %v\n", downloadURL)
|
log.Infof("from url: %v\n", downloadURL)
|
||||||
log.Infof("on commit: %v\n", commit)
|
|
||||||
log.Infof("into: %v\n", pluginFolder)
|
log.Infof("into: %v\n", pluginFolder)
|
||||||
|
|
||||||
err = downloadFile(plugin.Id, pluginFolder, downloadURL)
|
err = downloadFile(plugin.Id, pluginFolder, downloadURL)
|
||||||
if err == nil {
|
if err != nil {
|
||||||
log.Infof("Installed %v successfully ✔\n", plugin.Id)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
res, _ := s.ReadPlugin(pluginFolder, pluginName)
|
log.Infof("Installed %v successfully ✔\n", plugin.Id)
|
||||||
|
|
||||||
|
/* Enable once we need support for downloading depedencies
|
||||||
|
res, _ := s.ReadPlugin(pluginFolder, pluginName)
|
||||||
for _, v := range res.Dependency.Plugins {
|
for _, v := range res.Dependency.Plugins {
|
||||||
InstallPlugin(v.Id, version, c)
|
InstallPlugin(v.Id, version, c)
|
||||||
log.Infof("Installed Dependency: %v ✔\n", v.Id)
|
log.Infof("Installed dependency: %v ✔\n", v.Id)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
|
|
||||||
var ls_getPlugins func(path string) []m.InstalledPlugin = s.GetLocalPlugins
|
var ls_getPlugins func(path string) []m.InstalledPlugin = s.GetLocalPlugins
|
||||||
|
|
||||||
var validateLsCommmand = func(pluginDir string) error {
|
var validateLsCommand = func(pluginDir string) error {
|
||||||
if pluginDir == "" {
|
if pluginDir == "" {
|
||||||
return errors.New("missing path flag")
|
return errors.New("missing path flag")
|
||||||
}
|
}
|
||||||
@ -31,7 +31,7 @@ var validateLsCommmand = func(pluginDir string) error {
|
|||||||
|
|
||||||
func lsCommand(c CommandLine) error {
|
func lsCommand(c CommandLine) error {
|
||||||
pluginDir := c.GlobalString("path")
|
pluginDir := c.GlobalString("path")
|
||||||
if err := validateLsCommmand(pluginDir); err != nil {
|
if err := validateLsCommand(pluginDir); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,10 +9,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMissingPath(t *testing.T) {
|
func TestMissingPath(t *testing.T) {
|
||||||
var org = validateLsCommmand
|
var org = validateLsCommand
|
||||||
|
|
||||||
Convey("ls command", t, func() {
|
Convey("ls command", t, func() {
|
||||||
validateLsCommmand = org
|
validateLsCommand = org
|
||||||
|
|
||||||
Convey("Missing path", func() {
|
Convey("Missing path", func() {
|
||||||
commandLine := &commandstest.FakeCommandLine{
|
commandLine := &commandstest.FakeCommandLine{
|
||||||
@ -61,7 +61,7 @@ func TestMissingPath(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
validateLsCommmand = func(pluginDir string) error {
|
validateLsCommand = func(pluginDir string) error {
|
||||||
return errors.New("dummie error")
|
return errors.New("dummie error")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ func main() {
|
|||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "repo",
|
Name: "repo",
|
||||||
Usage: "url to the plugin repository",
|
Usage: "url to the plugin repository",
|
||||||
Value: "https://raw.githubusercontent.com/grafana/grafana-plugin-repository/master/repo.json",
|
Value: "",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
cli.BoolFlag{
|
||||||
Name: "debug, d",
|
Name: "debug, d",
|
||||||
|
@ -12,7 +12,8 @@ import (
|
|||||||
var IoHelper m.IoUtil = IoUtilImp{}
|
var IoHelper m.IoUtil = IoUtilImp{}
|
||||||
|
|
||||||
func ListAllPlugins(repoUrl string) (m.PluginRepo, error) {
|
func ListAllPlugins(repoUrl string) (m.PluginRepo, error) {
|
||||||
res, _ := goreq.Request{Uri: repoUrl}.Do()
|
|
||||||
|
res, _ := goreq.Request{Uri: repoUrl + "/repo", MaxRedirects: 3}.Do()
|
||||||
|
|
||||||
var resp m.PluginRepo
|
var resp m.PluginRepo
|
||||||
err := res.Body.FromJsonTo(&resp)
|
err := res.Body.FromJsonTo(&resp)
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/log"
|
"github.com/grafana/grafana/pkg/log"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
"github.com/grafana/grafana/pkg/util"
|
"github.com/grafana/grafana/pkg/util"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RenderOpts struct {
|
type RenderOpts struct {
|
||||||
@ -18,6 +19,7 @@ type RenderOpts struct {
|
|||||||
Width string
|
Width string
|
||||||
Height string
|
Height string
|
||||||
SessionId string
|
SessionId string
|
||||||
|
Timeout string
|
||||||
}
|
}
|
||||||
|
|
||||||
func RenderToPng(params *RenderOpts) (string, error) {
|
func RenderToPng(params *RenderOpts) (string, error) {
|
||||||
@ -60,8 +62,13 @@ func RenderToPng(params *RenderOpts) (string, error) {
|
|||||||
close(done)
|
close(done)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
timeout, err := strconv.Atoi(params.Timeout)
|
||||||
|
if err != nil {
|
||||||
|
timeout = 15
|
||||||
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-time.After(15 * time.Second):
|
case <-time.After(time.Duration(timeout) * time.Second):
|
||||||
if err := cmd.Process.Kill(); err != nil {
|
if err := cmd.Process.Kill(); err != nil {
|
||||||
log.Error(4, "failed to kill: %v", err)
|
log.Error(4, "failed to kill: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,8 @@ func TestPluginDashboards(t *testing.T) {
|
|||||||
|
|
||||||
Convey("When asking plugin dashboard info", t, func() {
|
Convey("When asking plugin dashboard info", t, func() {
|
||||||
setting.Cfg = ini.Empty()
|
setting.Cfg = ini.Empty()
|
||||||
sec, _ := setting.Cfg.NewSection("plugin.nginx-app")
|
sec, _ := setting.Cfg.NewSection("plugin.test-app")
|
||||||
sec.NewKey("path", "../../examples/nginx-app")
|
sec.NewKey("path", "../../tests/test-app")
|
||||||
err := Init()
|
err := Init()
|
||||||
|
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
@ -31,7 +31,7 @@ func TestPluginDashboards(t *testing.T) {
|
|||||||
return m.ErrDashboardNotFound
|
return m.ErrDashboardNotFound
|
||||||
})
|
})
|
||||||
|
|
||||||
dashboards, err := GetPluginDashboards(1, "nginx-app")
|
dashboards, err := GetPluginDashboards(1, "test-app")
|
||||||
|
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ func TestPluginDashboards(t *testing.T) {
|
|||||||
So(dashboards[0].Title, ShouldEqual, "Nginx Connections")
|
So(dashboards[0].Title, ShouldEqual, "Nginx Connections")
|
||||||
So(dashboards[0].Revision, ShouldEqual, "1.5")
|
So(dashboards[0].Revision, ShouldEqual, "1.5")
|
||||||
So(dashboards[0].InstalledRevision, ShouldEqual, "1.1")
|
So(dashboards[0].InstalledRevision, ShouldEqual, "1.1")
|
||||||
So(dashboards[0].InstalledURI, ShouldEqual, "db/nginx-connections")
|
So(dashboards[0].InstalledUri, ShouldEqual, "db/nginx-connections")
|
||||||
|
|
||||||
So(dashboards[1].Revision, ShouldEqual, "2.0")
|
So(dashboards[1].Revision, ShouldEqual, "2.0")
|
||||||
So(dashboards[1].InstalledRevision, ShouldEqual, "")
|
So(dashboards[1].InstalledRevision, ShouldEqual, "")
|
||||||
|
@ -28,14 +28,14 @@ func TestPluginScans(t *testing.T) {
|
|||||||
Convey("When reading app plugin definition", t, func() {
|
Convey("When reading app plugin definition", t, func() {
|
||||||
setting.Cfg = ini.Empty()
|
setting.Cfg = ini.Empty()
|
||||||
sec, _ := setting.Cfg.NewSection("plugin.nginx-app")
|
sec, _ := setting.Cfg.NewSection("plugin.nginx-app")
|
||||||
sec.NewKey("path", "../../examples/nginx-app")
|
sec.NewKey("path", "../../tests/test-app")
|
||||||
err := Init()
|
err := Init()
|
||||||
|
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
So(len(Apps), ShouldBeGreaterThan, 0)
|
So(len(Apps), ShouldBeGreaterThan, 0)
|
||||||
|
|
||||||
So(Apps["nginx-app"].Info.Logos.Large, ShouldEqual, "public/plugins/nginx-app/img/logo_large.png")
|
So(Apps["test-app"].Info.Logos.Large, ShouldEqual, "public/plugins/test-app/img/logo_large.png")
|
||||||
So(Apps["nginx-app"].Info.Screenshots[1].Path, ShouldEqual, "public/plugins/nginx-app/img/screenshot2.png")
|
So(Apps["test-app"].Info.Screenshots[1].Path, ShouldEqual, "public/plugins/test-app/img/screenshot2.png")
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ function (angular, _, kbn) {
|
|||||||
if (urlValue !== void 0) {
|
if (urlValue !== void 0) {
|
||||||
return self.setVariableFromUrl(variable, urlValue).then(lock.resolve);
|
return self.setVariableFromUrl(variable, urlValue).then(lock.resolve);
|
||||||
}
|
}
|
||||||
else if (variable.refresh === 'On Dashboard Load' || variable.refresh === 'On Time Change and Dashboard Load') {
|
else if (variable.refresh === 1 || variable.refresh === 2) {
|
||||||
return self.updateOptions(variable).then(function() {
|
return self.updateOptions(variable).then(function() {
|
||||||
if (_.isEmpty(variable.current) && variable.options.length) {
|
if (_.isEmpty(variable.current) && variable.options.length) {
|
||||||
console.log("setting current for %s", variable.name);
|
console.log("setting current for %s", variable.name);
|
||||||
|
@ -143,7 +143,7 @@ function (angular, _, moment, dateMath, CloudWatchAnnotationQuery) {
|
|||||||
return this.awsRequest({
|
return this.awsRequest({
|
||||||
region: region,
|
region: region,
|
||||||
action: 'DescribeInstances',
|
action: 'DescribeInstances',
|
||||||
parameters: { filter: filters, instanceIds: instanceIds }
|
parameters: { filters: filters, instanceIds: instanceIds }
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -205,6 +205,28 @@ function (angular, _, moment, dateMath, CloudWatchAnnotationQuery) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ec2InstanceAttributeQuery = query.match(/^ec2_instance_attribute\(([^,]+?),\s?([^,]+?),\s?(.+?)\)/);
|
||||||
|
if (ec2InstanceAttributeQuery) {
|
||||||
|
region = templateSrv.replace(ec2InstanceAttributeQuery[1]);
|
||||||
|
var filterJson = JSON.parse(templateSrv.replace(ec2InstanceAttributeQuery[3]));
|
||||||
|
var filters = _.map(filterJson, function(values, name) {
|
||||||
|
return {
|
||||||
|
Name: name,
|
||||||
|
Values: values
|
||||||
|
};
|
||||||
|
});
|
||||||
|
var targetAttributeName = templateSrv.replace(ec2InstanceAttributeQuery[2]);
|
||||||
|
|
||||||
|
return this.performEC2DescribeInstances(region, filters, null).then(function(result) {
|
||||||
|
var attributes = _.chain(result.Reservations)
|
||||||
|
.map(function(reservations) {
|
||||||
|
return _.pluck(reservations.Instances, targetAttributeName);
|
||||||
|
})
|
||||||
|
.flatten().value();
|
||||||
|
return transformSuggestData(attributes);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return $q.when([]);
|
return $q.when([]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ export function InfluxDatasource(instanceSettings, $q, backendSrv, templateSrv)
|
|||||||
this.metricFindQuery = function (query) {
|
this.metricFindQuery = function (query) {
|
||||||
var interpolated;
|
var interpolated;
|
||||||
try {
|
try {
|
||||||
interpolated = templateSrv.replace(query);
|
interpolated = templateSrv.replace(query, null, 'regex');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return $q.reject(err);
|
return $q.reject(err);
|
||||||
}
|
}
|
||||||
|
@ -258,6 +258,6 @@
|
|||||||
"annotations": {
|
"annotations": {
|
||||||
"enable": false
|
"enable": false
|
||||||
},
|
},
|
||||||
"refresh": "Never",
|
"refresh": 0,
|
||||||
"version": 6
|
"version": 6
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"type": "app",
|
"type": "app",
|
||||||
"name": "Nginx",
|
"name": "Test App",
|
||||||
"id": "nginx-app",
|
"id": "test-app",
|
||||||
|
|
||||||
"staticRoot": ".",
|
"staticRoot": ".",
|
||||||
|
|
||||||
@ -16,12 +16,12 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
"info": {
|
"info": {
|
||||||
"description": "Official Grafana Nginx App & Dashboard bundle",
|
"description": "Official Grafana Test App & Dashboard bundle",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Nginx Inc.",
|
"name": "Test Inc.",
|
||||||
"url": "http://nginx.com"
|
"url": "http://test.com"
|
||||||
},
|
},
|
||||||
"keywords": ["nginx"],
|
"keywords": ["test"],
|
||||||
"logos": {
|
"logos": {
|
||||||
"small": "img/logo_small.png",
|
"small": "img/logo_small.png",
|
||||||
"large": "img/logo_large.png"
|
"large": "img/logo_large.png"
|
Reference in New Issue
Block a user