mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
parent
fc43ce657c
commit
e2f6633d57
@ -21,6 +21,7 @@
|
|||||||
- [Issue #1928](https://github.com/grafana/grafana/issues/1928). HTTP API: GET /api/dashboards/db/:slug response changed property `model` to `dashboard` to match the POST request nameing
|
- [Issue #1928](https://github.com/grafana/grafana/issues/1928). HTTP API: GET /api/dashboards/db/:slug response changed property `model` to `dashboard` to match the POST request nameing
|
||||||
- Backend render URL changed from `/render/dashboard/solo` `render/dashboard-solo/` (in order to have consistent dashboard url `/dashboard/:type/:slug`)
|
- Backend render URL changed from `/render/dashboard/solo` `render/dashboard-solo/` (in order to have consistent dashboard url `/dashboard/:type/:slug`)
|
||||||
- Search HTTP API response has changed (simplified), tags list moved to seperate HTTP resource URI
|
- Search HTTP API response has changed (simplified), tags list moved to seperate HTTP resource URI
|
||||||
|
- Datasource HTTP api breaking change, ADD datasource is now POST /api/datasources/, update is now PUT /api/datasources/:id
|
||||||
|
|
||||||
# 2.0.3 (unreleased - 2.0.x branch)
|
# 2.0.3 (unreleased - 2.0.x branch)
|
||||||
|
|
||||||
|
@ -107,10 +107,9 @@ func Register(r *macaron.Macaron) {
|
|||||||
|
|
||||||
// Data sources
|
// Data sources
|
||||||
r.Group("/datasources", func() {
|
r.Group("/datasources", func() {
|
||||||
r.Combo("/").
|
r.Get("/", GetDataSources)
|
||||||
Get(GetDataSources).
|
r.Post("/", bind(m.AddDataSourceCommand{}), AddDataSource)
|
||||||
Put(bind(m.AddDataSourceCommand{}), AddDataSource).
|
r.Put("/:id", bind(m.UpdateDataSourceCommand{}), UpdateDataSource)
|
||||||
Post(bind(m.UpdateDataSourceCommand{}), UpdateDataSource)
|
|
||||||
r.Delete("/:id", DeleteDataSource)
|
r.Delete("/:id", DeleteDataSource)
|
||||||
r.Get("/:id", GetDataSourceById)
|
r.Get("/:id", GetDataSourceById)
|
||||||
r.Get("/plugins", GetDataSourcePlugins)
|
r.Get("/plugins", GetDataSourcePlugins)
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/middleware"
|
"github.com/grafana/grafana/pkg/middleware"
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/plugins"
|
"github.com/grafana/grafana/pkg/plugins"
|
||||||
|
"github.com/grafana/grafana/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetDataSources(c *middleware.Context) {
|
func GetDataSources(c *middleware.Context) {
|
||||||
@ -94,11 +95,12 @@ func AddDataSource(c *middleware.Context, cmd m.AddDataSourceCommand) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JsonOK("Datasource added")
|
c.JSON(200, util.DynMap{"message": "Datasource added", "id": cmd.Result.Id})
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdateDataSource(c *middleware.Context, cmd m.UpdateDataSourceCommand) {
|
func UpdateDataSource(c *middleware.Context, cmd m.UpdateDataSourceCommand) {
|
||||||
cmd.OrgId = c.OrgId
|
cmd.OrgId = c.OrgId
|
||||||
|
cmd.Id = c.ParamsInt64(":id")
|
||||||
|
|
||||||
err := bus.Dispatch(&cmd)
|
err := bus.Dispatch(&cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -69,7 +69,6 @@ type AddDataSourceCommand struct {
|
|||||||
|
|
||||||
// Also acts as api DTO
|
// Also acts as api DTO
|
||||||
type UpdateDataSourceCommand struct {
|
type UpdateDataSourceCommand struct {
|
||||||
Id int64 `json:"id" binding:"Required"`
|
|
||||||
Name string `json:"name" binding:"Required"`
|
Name string `json:"name" binding:"Required"`
|
||||||
Type string `json:"type" binding:"Required"`
|
Type string `json:"type" binding:"Required"`
|
||||||
Access DsAccess `json:"access" binding:"Required"`
|
Access DsAccess `json:"access" binding:"Required"`
|
||||||
@ -84,6 +83,7 @@ type UpdateDataSourceCommand struct {
|
|||||||
JsonData map[string]interface{} `json:"jsonData"`
|
JsonData map[string]interface{} `json:"jsonData"`
|
||||||
|
|
||||||
OrgId int64 `json:"-"`
|
OrgId int64 `json:"-"`
|
||||||
|
Id int64 `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeleteDataSourceCommand struct {
|
type DeleteDataSourceCommand struct {
|
||||||
|
@ -25,7 +25,6 @@ function (angular, config) {
|
|||||||
|
|
||||||
$scope.loadDatasourceTypes().then(function() {
|
$scope.loadDatasourceTypes().then(function() {
|
||||||
if ($routeParams.id) {
|
if ($routeParams.id) {
|
||||||
$scope.isNew = false;
|
|
||||||
$scope.getDatasourceById($routeParams.id);
|
$scope.getDatasourceById($routeParams.id);
|
||||||
} else {
|
} else {
|
||||||
$scope.current = angular.copy(defaults);
|
$scope.current = angular.copy(defaults);
|
||||||
@ -48,6 +47,7 @@ function (angular, config) {
|
|||||||
|
|
||||||
$scope.getDatasourceById = function(id) {
|
$scope.getDatasourceById = function(id) {
|
||||||
backendSrv.get('/api/datasources/' + id).then(function(ds) {
|
backendSrv.get('/api/datasources/' + id).then(function(ds) {
|
||||||
|
$scope.isNew = false;
|
||||||
$scope.current = ds;
|
$scope.current = ds;
|
||||||
$scope.typeChanged();
|
$scope.typeChanged();
|
||||||
});
|
});
|
||||||
@ -65,26 +65,46 @@ function (angular, config) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.update = function() {
|
$scope.testDatasource = function() {
|
||||||
if (!$scope.editForm.$valid) {
|
$scope.testing = { done: false };
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
backendSrv.post('/api/datasources', $scope.current).then(function() {
|
datasourceSrv.get($scope.current.name).then(function(datasource) {
|
||||||
$scope.updateFrontendSettings();
|
if (!datasource.testDatasource) {
|
||||||
$location.path("datasources");
|
$scope.testing.message = 'Data source does not support test connection feature.';
|
||||||
|
$scope.testing.status = 'warning';
|
||||||
|
$scope.testing.title = 'Unknown';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return datasource.testDatasource().then(function(result) {
|
||||||
|
$scope.testing.message = result.message;
|
||||||
|
$scope.testing.status = result.status;
|
||||||
|
$scope.testing.title = result.title;
|
||||||
|
});
|
||||||
|
}).finally(function() {
|
||||||
|
$scope.testing.done = true;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.add = function() {
|
$scope.saveChanges = function(test) {
|
||||||
if (!$scope.editForm.$valid) {
|
if (!$scope.editForm.$valid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
backendSrv.put('/api/datasources', $scope.current).then(function() {
|
if ($scope.current.id) {
|
||||||
$scope.updateFrontendSettings();
|
return backendSrv.put('/api/datasources/' + $scope.current.id, $scope.current).then(function() {
|
||||||
$location.path("datasources");
|
$scope.updateFrontendSettings();
|
||||||
});
|
if (test) {
|
||||||
|
$scope.testDatasource();
|
||||||
|
} else {
|
||||||
|
$location.path('datasources');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return backendSrv.post('/api/datasources', $scope.current).then(function(result) {
|
||||||
|
$scope.updateFrontendSettings();
|
||||||
|
$location.path('datasources/edit/' + result.id);
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.init();
|
$scope.init();
|
||||||
|
@ -43,11 +43,22 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div ng-include="datasourceMeta.partials.config" ng-if="datasourceMeta.partials.config"></div>
|
<div ng-include="datasourceMeta.partials.config" ng-if="datasourceMeta.partials.config"></div>
|
||||||
<br>
|
|
||||||
<br>
|
<div ng-if="testing" style="margin-top: 25px">
|
||||||
<div class="pull-right">
|
<h5 ng-show="!testing.done">Testing.... <i class="fa fa-spiner fa-spin"></i></h5>
|
||||||
<button type="submit" class="btn btn-success" ng-show="isNew" ng-click="add()">Add</button>
|
<h5 ng-show="testing.done">Test results</h5>
|
||||||
<button type="submit" class="btn btn-success" ng-show="!isNew" ng-click="update()">Update</button>
|
<div class="alert-{{testing.status}} alert">
|
||||||
|
<div class="alert-title">{{testing.title}}</div>
|
||||||
|
<div ng-bind='testing.message'></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pull-right" style="margin-top: 35px">
|
||||||
|
<button type="submit" class="btn btn-success" ng-show="isNew" ng-click="saveChanges()">Add</button>
|
||||||
|
<button type="submit" class="btn btn-success" ng-show="!isNew" ng-click="saveChanges()">Save</button>
|
||||||
|
<button type="submit" class="btn btn-inverse" ng-show="!isNew" ng-click="saveChanges(true)">
|
||||||
|
Test Connection
|
||||||
|
</button>
|
||||||
<a class="btn btn-inverse" ng-show="!isNew" href="datasources">Cancel</a>
|
<a class="btn btn-inverse" ng-show="!isNew" href="datasources">Cancel</a>
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
|
@ -196,6 +196,22 @@ function (angular, _, $, config, kbn, moment) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
GraphiteDatasource.prototype.testDatasource = function() {
|
||||||
|
return this.metricFindQuery('*').then(function () {
|
||||||
|
return { status: "success", message: "Data source is working", title: "Success" };
|
||||||
|
}, function(err) {
|
||||||
|
var message, title;
|
||||||
|
if (err.statusText) {
|
||||||
|
message = err.statusText;
|
||||||
|
title = "HTTP Error";
|
||||||
|
} else {
|
||||||
|
message = err;
|
||||||
|
title = "Unknown error";
|
||||||
|
}
|
||||||
|
return { status: "error", message: message, title: title };
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
GraphiteDatasource.prototype.listDashboards = function(query) {
|
GraphiteDatasource.prototype.listDashboards = function(query) {
|
||||||
return this.doGraphiteRequest({ method: 'GET', url: '/dashboard/find/', params: {query: query || ''} })
|
return this.doGraphiteRequest({ method: 'GET', url: '/dashboard/find/', params: {query: query || ''} })
|
||||||
.then(function(results) {
|
.then(function(results) {
|
||||||
|
@ -315,38 +315,37 @@ div.flot-text {
|
|||||||
position: fixed;
|
position: fixed;
|
||||||
right: 20px;
|
right: 20px;
|
||||||
top: 56px;
|
top: 56px;
|
||||||
|
}
|
||||||
|
|
||||||
.alert {
|
.alert {
|
||||||
color: @white;
|
color: @white;
|
||||||
padding-bottom: 13px;
|
padding-bottom: 13px;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.alert-close {
|
.alert-close {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: -4px;
|
top: -4px;
|
||||||
right: -2px;
|
right: -2px;
|
||||||
width: 19px;
|
width: 19px;
|
||||||
height: 19px;
|
height: 19px;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
background: @grayLighter;
|
background: @grayLighter;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
border: none;
|
border: none;
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
color: @grayDarker;
|
color: @grayDarker;
|
||||||
}
|
}
|
||||||
|
|
||||||
.alert-title {
|
.alert-title {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
padding-bottom: 2px;
|
padding-bottom: 2px;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.alert-warning {
|
.alert-warning {
|
||||||
background-color: @warningBackground;
|
background-color: @warningBackground;
|
||||||
border-color: @warningBorder;
|
border-color: @warningBorder;
|
||||||
color: @warningText;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ===================================================
|
/* ===================================================
|
||||||
|
Loading…
Reference in New Issue
Block a user