Skip to content

Commit

Permalink
Merge branch 'master' into docs_v5.0
Browse files Browse the repository at this point in the history
  • Loading branch information
marefr committed Feb 12, 2018
2 parents 4eec4bf + 12a6de7 commit 2b31465
Show file tree
Hide file tree
Showing 65 changed files with 997 additions and 416 deletions.
13 changes: 12 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# 5.0.0-beta1 (2018-02-05)

Grafana v5.0 is going to be the biggest and most foundational release Grafana has ever had, coming with a ton of UX improvements, a new dashboard grid engine, dashboard folders, user teams and permissions. Checkout out this [video preview](https://www.youtube.com/watch?v=BC_YRNpqj5k) of Grafana v5.
Grafana v5.0 is going to be the biggest and most foundational release Grafana has ever had, coming with a ton of UX improvements, a new dashboard grid engine, dashboard folders, user teams and permissions. Checkout out this [video preview](https://www.youtube.com/watch?v=Izr0IBgoTZQ) of Grafana v5.

### New Major Features
- **Dashboards** Dashboard folders, [#1611](https://github.com/grafana/grafana/issues/1611)
Expand Down Expand Up @@ -69,6 +69,17 @@ Dashboard panels and rows are positioned using a gridPos object `{x: 0, y: 0, w:
## Tech
* **RabbitMq**: Remove support for publishing events to RabbitMQ [#9645](https://github.com/grafana/grafana/issues/9645)

## Deprecation notes

### HTTP API
The following operations have been deprecated and will be removed in a future release:
- `GET /api/dashboards/db/:slug` -> Use `GET /api/dashboards/uid/:uid` instead
- `DELETE /api/dashboards/db/:slug` -> Use `DELETE /api/dashboards/uid/:uid` instead

The following properties have been deprecated and will be removed in a future release:
- `uri` property in `GET /api/search` -> Use new `url` or `uid` property instead
- `meta.slug` property in `GET /api/dashboards/uid/:uid` and `GET /api/dashboards/db/:slug` -> Use new `meta.url` or `dashboard.uid` property instead

# 4.6.3 (2017-12-14)

## Fixes
Expand Down
19 changes: 17 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,11 @@ In your custom.ini uncomment (remove the leading `;`) sign. And set `app_mode =

### Running tests

- You can run backend Golang tests using "go test ./pkg/...".
- Execute all frontend tests with "npm run test"
#### Frontend
Execute all frontend tests
```bash
npm run test
```

Writing & watching frontend tests (we have two test runners)

Expand All @@ -92,6 +95,18 @@ Writing & watching frontend tests (we have two test runners)
- Start watcher: `npm run karma`
- Karma+Mocha runs all files that end with the name "_specs.ts".

#### Backend
```bash
# Run Golang tests using sqlite3 as database (default)
go test ./pkg/...

# Run Golang tests using mysql as database - convenient to use /docker/blocks/mysql_tests
GRAFANA_TEST_DB=mysql go test ./pkg/...

# Run Golang tests using postgres as database - convenient to use /docker/blocks/postgres_tests
GRAFANA_TEST_DB=postgres go test ./pkg/...
```

## Contribute

If you have any idea for an improvement or found a bug, do not hesitate to open an issue.
Expand Down
41 changes: 31 additions & 10 deletions docs/sources/guides/whats-new-in-v5.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ weight = -6

# What's New in Grafana v5.0

> Out in beta: [Download now!](https://www.youtube.com/watch?v=Izr0IBgoTZQ)
> Out in beta: [Download now!](https://grafana.com/grafana/download/5.0.0-beta1)
This is the most substantial update that Grafana has ever seen. This article will detail the major new features and enhancements.

Expand All @@ -24,10 +24,12 @@ This is the most substantial update that Grafana has ever seen. This article wil
- [Group users into teams]({{< relref "#teams" >}}) and use them in the new permission system.
- [Datasource provisioning]({{< relref "#data-sources" >}}) makes it possible to setup datasources via config files.
- [Dashboard provisioning]({{< relref "#dashboards" >}}) makes it possible to setup dashboards via config files.
- [Persistent dashboard url's]({{< relref "#dashboard-model-persistent-url-s-and-api-changes" >}}) makes it possible to rename dashboards without breaking links.
- [Graphite Tags & Integrated Function Docs]({{< relref "#graphite-tags-integrated-function-docs" >}}).

### Video showing new features

<iframe height="215" src="https://www.youtube.com/embed/BC_YRNpqj5k?rel=0&amp;showinfo=0" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
<iframe width="450" height="270" src="https://www.youtube.com/embed/Izr0IBgoTZQ?rel=0&amp;" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
<br />

## New Dashboard Layout Engine
Expand All @@ -51,7 +53,7 @@ Almost every page has seen significant UX improvements. All pages (except dashbo

<div class="clearfix"></div>

### Dashboard Settings
## Dashboard Settings

{{< docs-imagebox img="/img/docs/v50/dashboard_settings.png" max-width="1000px" class="docs-image--right" >}}
Dashboard pages have a new header toolbar where buttons and actions are now all moved to the right. All the dashboard
Expand Down Expand Up @@ -95,7 +97,7 @@ data sources a user can access nor what queries a user can issue.

<div class="clearfix"></div>

# Provisioning from configuration
## Provisioning from configuration

In previous versions of Grafana, you could only use the API for provisioning data sources and dashboards.
But that required the service to be running before you started creating dashboards and you also needed to
Expand All @@ -117,17 +119,36 @@ in sync with dashboards in Grafana's database. The dashboard provisioner has mul
which makes it possible to star them, use one as the home dashboard, set permissions and other features in Grafana that
expects the dashboards to exist in the database. More info in the [dashboard provisioning docs](/administration/provisioning/#dashboards)

# Dashboard model, new url structure & API changes

## Graphite Tags & Integrated Function Docs

{{< docs-imagebox img="/img/docs/v50/graphite_tags.png" max-width="1000px" class="docs-image--right" >}}

The Graphite query editor has been updated to support the latest Graphite version (v1.2) that adds
many new functions and support for querying by tags. You can now also view function documentation right in the query editor!

Read more on [Graphite Tag Support](http://graphite.readthedocs.io/en/latest/tags.html?highlight=tags).

<div class="clearfix"></div>

## Dashboard model, persistent url's and API changes

We are introducing a new unique identifier (`uid`) in the dashboard JSON model. It's automatically
generated if not provided when creating a dashboard and will have a length of 9-12 characters.

The unique identifier allows having consistent URL's for accessing dashboards and sharing them
between instances. The new routes and API's for accessing dashboards will use the `uid` instead
of the `slug`. We'll keep supporting the old routes for accessing dashboards for backward
compatibility, but please note that we'll deprecate the old slug-based routes in the future.
This means that changing the title of dashboards will not break any bookmarked links.
The unique identifier allows having persistent URL's for accessing dashboards, sharing them
between instances and when using [dashboard provisioning](#dashboards). This means that dashboard can
be renamed without breaking any links. We're changing the url format for dashboards
from `/dashboard/db/:slug` to `/d/:uid/:slug`. We'll keep supporting the old slug-based url's for dashboards
and redirects to the new one for backward compatibility. Please note that the old slug-based url's
have been deprecated and will be removed in a future release.

Sharing dashboards between instances becomes much easier since the `uid` is unique (unique enough).
This might seem like a small change, but we are incredibly excited about it since it will make it
much easier to manage, collaborate and navigate between dashboards.

### API changes
New uid-based routes in the dashboard API have been introduced to retrieve and delete dashboards.
The corresponding slug-based routes have been deprecated and will be removed in a future release.


136 changes: 97 additions & 39 deletions docs/sources/index.md
Original file line number Diff line number Diff line change
@@ -1,49 +1,107 @@
+++
title = "Docs Home"
description = "Install guide for Grafana"
title = "Grafana documentation"
description = "Guides, Installation & Feature Documentation"
keywords = ["grafana", "installation", "documentation"]
type = "docs"
aliases = ["v1.1", "guides/reference/admin"]
+++

# Welcome to the Grafana Documentation
# Grafana Documentation

Grafana is an open source metric analytics & visualization suite. It is most commonly used for
visualizing time series data for infrastructure and application analytics but many use it in
other domains including industrial sensors, home automation, weather, and process control.
<h2>Installing Grafana</h2>
<div class="nav-cards">
<a href="{{< relref "installation/debian.md" >}}" class="nav-cards__item nav-cards__item--install">
<div class="nav-cards__icon fa fa-linux">
</div>
<h5>Installing on Linux</h5>
</a>
<a href="{{< relref "installation/mac.md" >}}" class="nav-cards__item nav-cards__item--install">
<div class="nav-cards__icon fa fa-apple">
</div>
<h5>Installing on Mac OS X</h5>
</a>
<a href="{{< relref "installation/windows.md" >}}" class="nav-cards__item nav-cards__item--install">
<div class="nav-cards__icon fa fa-windows">
</div>
<h5>Installing on Windows</h5>
</a>
<a href="https://grafana.com/cloud/grafana" class="nav-cards__item nav-cards__item--install">
<div class="nav-cards__icon fa fa-cloud">
</div>
<h5>Grafana Cloud</h5>
</a>
<a href="https://grafana.com/grafana/download" class="nav-cards__item nav-cards__item--install">
<div class="nav-cards__icon fa fa-moon-o">
</div>
<h5>Nightly Builds</h5>
</a>
<div class="nav-cards__item nav-cards__item--install">
<h5>For other platforms Read the <a href="{{< relref "project/building_from_source.md" >}}">build from source</a>
instructions for more information.</h5>
</div>
</div>

## Installing Grafana
- [Installing on Debian / Ubuntu](installation/debian)
- [Installing on RPM-based Linux (CentOS, Fedora, OpenSuse, RedHat)](installation/rpm)
- [Installing on Mac OS X](installation/mac)
- [Installing on Windows](installation/windows)
- [Installing on Docker](installation/docker)
- [Installing using Provisioning (Chef, Puppet, Salt, Ansible, etc)](administration/provisioning#configuration-management-tools)
- [Nightly Builds](https://grafana.com/grafana/download)
<h2>Guides</h2>

For other platforms Read the [build from source]({{< relref "project/building_from_source.md" >}})
instructions for more information.
<div class="nav-cards">
<a href="https://grafana.com/grafana" class="nav-cards__item nav-cards__item--guide">
<h4>What is Grafana?</h4>
<p>Grafana feature highlights.</p>
</a>
<a href="{{< relref "installation/configuration.md" >}}" class="nav-cards__item nav-cards__item--guide">
<h4>Configure Grafana</h4>
<p>Article on all the Grafana configuration and setup options.</p>
</a>
<a href="{{< relref "guides/getting_started.md" >}}" class="nav-cards__item nav-cards__item--guide">
<h4>Getting Started</h4>
<p>A guide that walks you through the basics of using Grafana</p>
</a>
<a href="{{< relref "administration/provisioning.md" >}}" class="nav-cards__item nav-cards__item--guide">
<h4>Provisioning</h4>
<p>A guide to help you automate your Grafana setup & configuration.</p>
</a>
<a href="{{< relref "guides/whats-new-in-v5.md" >}}" class="nav-cards__item nav-cards__item--guide">
<h4>What's new in v5.0</h4>
<p>Article on all the new cool features and enhancements in v5.0</p>
</a>
<a href="{{< relref "tutorials/screencasts.md" >}}" class="nav-cards__item nav-cards__item--guide">
<h4>Screencasts</h4>
<p>Video tutorials & guides</p>
</a>
</div>

## Configuring Grafana

The back-end web server has a number of configuration options. Go the
[Configuration]({{< relref "installation/configuration.md" >}}) page for details on all
those options.


## Getting Started

- [Getting Started]({{< relref "guides/getting_started.md" >}})
- [Basic Concepts]({{< relref "guides/basic_concepts.md" >}})
- [Screencasts]({{< relref "tutorials/screencasts.md" >}})

## Data Source Guides

- [Graphite]({{< relref "features/datasources/graphite.md" >}})
- [Elasticsearch]({{< relref "features/datasources/elasticsearch.md" >}})
- [InfluxDB]({{< relref "features/datasources/influxdb.md" >}})
- [Prometheus]({{< relref "features/datasources/prometheus.md" >}})
- [OpenTSDB]({{< relref "features/datasources/opentsdb.md" >}})
- [MySQL]({{< relref "features/datasources/mysql.md" >}})
- [Postgres]({{< relref "features/datasources/postgres.md" >}})
- [Cloudwatch]({{< relref "features/datasources/cloudwatch.md" >}})
<h2>Data Source Guides</h2>
<div class="nav-cards">
<a href="{{< relref "features/datasources/graphite.md" >}}" class="nav-cards__item nav-cards__item--ds">
<img src="/img/docs/logos/icon_graphite.svg" >
<h5>Graphite</h5>
</a>
<a href="{{< relref "features/datasources/elasticsearch.md" >}}" class="nav-cards__item nav-cards__item--ds">
<img src="/img/docs/logos/icon_elasticsearch.svg" >
<h5>Elasticsearch</h5>
</a>
<a href="{{< relref "features/datasources/influxdb.md" >}}" class="nav-cards__item nav-cards__item--ds">
<img src="/img/docs/logos/icon_influxdb.svg" >
<h5>InfluxDB</h5>
</a>
<a href="{{< relref "features/datasources/prometheus.md" >}}" class="nav-cards__item nav-cards__item--ds">
<img src="/img/docs/logos/icon_prometheus.svg" >
<h5>Prometheus</h5>
</a>
<a href="{{< relref "features/datasources/opentsdb.md" >}}" class="nav-cards__item nav-cards__item--ds">
<img src="/img/docs/logos/icon_opentsdb.png" >
<h5>OpenTSDB</h5>
</a>
<a href="{{< relref "features/datasources/mysql.md" >}}" class="nav-cards__item nav-cards__item--ds">
<img src="/img/docs/logos/icon_mysql.png" >
<h5>MySQL</h5>
</a>
<a href="{{< relref "features/datasources/postgres.md" >}}" class="nav-cards__item nav-cards__item--ds">
<img src="/img/docs/logos/icon_postgres.svg" >
<h5>Postgres</h5>
</a>
<a href="{{< relref "features/datasources/cloudwatch.md" >}}" class="nav-cards__item nav-cards__item--ds">
<img src="/img/docs/logos/icon_cloudwatch.svg">
<h5>Cloudwatch</h5>
</a>
</div>
14 changes: 7 additions & 7 deletions pkg/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,13 @@ func (hs *HttpServer) registerRoutes() {
apiRoute.Group("/teams", func(teamsRoute RouteRegister) {
teamsRoute.Get("/:teamId", wrap(GetTeamById))
teamsRoute.Get("/search", wrap(SearchTeams))
teamsRoute.Post("/", quota("teams"), reqOrgAdmin, bind(m.CreateTeamCommand{}), wrap(CreateTeam))
teamsRoute.Put("/:teamId", reqOrgAdmin, bind(m.UpdateTeamCommand{}), wrap(UpdateTeam))
teamsRoute.Delete("/:teamId", reqOrgAdmin, wrap(DeleteTeamById))
teamsRoute.Get("/:teamId/members", reqOrgAdmin, wrap(GetTeamMembers))
teamsRoute.Post("/:teamId/members", reqOrgAdmin, quota("teams"), bind(m.AddTeamMemberCommand{}), wrap(AddTeamMember))
teamsRoute.Delete("/:teamId/members/:userId", reqOrgAdmin, wrap(RemoveTeamMember))
})
teamsRoute.Post("/", quota("teams"), bind(m.CreateTeamCommand{}), wrap(CreateTeam))
teamsRoute.Put("/:teamId", bind(m.UpdateTeamCommand{}), wrap(UpdateTeam))
teamsRoute.Delete("/:teamId", wrap(DeleteTeamById))
teamsRoute.Get("/:teamId/members", wrap(GetTeamMembers))
teamsRoute.Post("/:teamId/members", quota("teams"), bind(m.AddTeamMemberCommand{}), wrap(AddTeamMember))
teamsRoute.Delete("/:teamId/members/:userId", wrap(RemoveTeamMember))
}, reqOrgAdmin)

// org information available to all users.
apiRoute.Group("/org", func(orgRoute RouteRegister) {
Expand Down
12 changes: 10 additions & 2 deletions pkg/api/dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"os"
"path"
"strings"

"github.com/grafana/grafana/pkg/services/dashboards"

Expand Down Expand Up @@ -217,6 +218,10 @@ func PostDashboard(c *middleware.Context, cmd m.SaveDashboardCommand) Response {
return ApiError(400, m.ErrDashboardTitleEmpty.Error(), nil)
}

if dash.IsFolder && strings.ToLower(dash.Title) == strings.ToLower(m.RootFolderName) {
return ApiError(400, "A folder already exists with that name", nil)
}

if dash.Id == 0 {
limitReached, err := middleware.QuotaReached(c, "dashboard")
if err != nil {
Expand All @@ -237,8 +242,11 @@ func PostDashboard(c *middleware.Context, cmd m.SaveDashboardCommand) Response {

dashboard, err := dashboards.GetRepository().SaveDashboard(dashItem)

if err == m.ErrDashboardTitleEmpty {
return ApiError(400, m.ErrDashboardTitleEmpty.Error(), nil)
if err == m.ErrDashboardTitleEmpty ||
err == m.ErrDashboardWithSameNameAsFolder ||
err == m.ErrDashboardFolderWithSameNameAsDashboard ||
err == m.ErrDashboardTypeMismatch {
return ApiError(400, err.Error(), nil)
}

if err == m.ErrDashboardContainsInvalidAlertData {
Expand Down
15 changes: 15 additions & 0 deletions pkg/api/dashboard_acl.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ import (
func GetDashboardAclList(c *middleware.Context) Response {
dashId := c.ParamsInt64(":dashboardId")

_, rsp := getDashboardHelper(c.OrgId, "", dashId, "")
if rsp != nil {
return rsp
}

guardian := guardian.NewDashboardGuardian(dashId, c.OrgId, c.SignedInUser)

if canAdmin, err := guardian.CanAdmin(); err != nil || !canAdmin {
Expand All @@ -36,6 +41,11 @@ func GetDashboardAclList(c *middleware.Context) Response {
func UpdateDashboardAcl(c *middleware.Context, apiCmd dtos.UpdateDashboardAclCommand) Response {
dashId := c.ParamsInt64(":dashboardId")

_, rsp := getDashboardHelper(c.OrgId, "", dashId, "")
if rsp != nil {
return rsp
}

guardian := guardian.NewDashboardGuardian(dashId, c.OrgId, c.SignedInUser)
if canAdmin, err := guardian.CanAdmin(); err != nil || !canAdmin {
return dashboardGuardianResponse(err)
Expand Down Expand Up @@ -79,6 +89,11 @@ func DeleteDashboardAcl(c *middleware.Context) Response {
dashId := c.ParamsInt64(":dashboardId")
aclId := c.ParamsInt64(":aclId")

_, rsp := getDashboardHelper(c.OrgId, "", dashId, "")
if rsp != nil {
return rsp
}

guardian := guardian.NewDashboardGuardian(dashId, c.OrgId, c.SignedInUser)
if canAdmin, err := guardian.CanAdmin(); err != nil || !canAdmin {
return dashboardGuardianResponse(err)
Expand Down
Loading

0 comments on commit 2b31465

Please sign in to comment.