[v3.2] Add grafana dashboard importing API (#11)

* Add API to import grafana templates to kubesphere dashboard
* Merge and fix the latest codes from kubesphere #2501

Signed-off-by: zhu733756 <talonzhu@yunify.com>
This commit is contained in:
zhu733756
2021-08-16 11:41:29 +08:00
committed by zhu733756
parent 9df6df5544
commit 242ceb54f6
217 changed files with 119028 additions and 96 deletions

2
vendor/github.com/gosimple/slug/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,2 @@
_*
cover*.out

373
vendor/github.com/gosimple/slug/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,373 @@
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.

54
vendor/github.com/gosimple/slug/README.md generated vendored Normal file
View File

@@ -0,0 +1,54 @@
slug
====
Package `slug` generate slug from unicode string, URL-friendly slugify with
multiple languages support.
[![GoDoc](https://godoc.org/github.com/gosimple/slug?status.png)](https://godoc.org/github.com/gosimple/slug)
[![Build Status](https://drone.io/github.com/gosimple/slug/status.png)](https://drone.io/github.com/gosimple/slug/latest)
[Documentation online](http://godoc.org/github.com/gosimple/slug)
## Example
package main
import(
"github.com/gosimple/slug"
"fmt"
)
func main () {
text := slug.Make("Hellö Wörld хелло ворлд")
fmt.Println(text) // Will print: "hello-world-khello-vorld"
someText := slug.Make("影師")
fmt.Println(someText) // Will print: "ying-shi"
enText := slug.MakeLang("This & that", "en")
fmt.Println(enText) // Will print: "this-and-that"
deText := slug.MakeLang("Diese & Dass", "de")
fmt.Println(deText) // Will print: "diese-und-dass"
slug.CustomSub = map[string]string{
"water": "sand",
}
textSub := slug.Make("water is hot")
fmt.Println(textSub) // Will print: "sand-is-hot"
}
### Requests or bugs?
<https://github.com/gosimple/slug/issues>
## Installation
go get -u github.com/gosimple/slug
## License
The source files are distributed under the
[Mozilla Public License, version 2.0](http://mozilla.org/MPL/2.0/),
unless otherwise noted.
Please read the [FAQ](http://www.mozilla.org/MPL/2.0/FAQ.html)
if you have further questions regarding the license.

43
vendor/github.com/gosimple/slug/doc.go generated vendored Normal file
View File

@@ -0,0 +1,43 @@
// Copyright 2013 by Dobrosław Żybort. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
/*
Package slug generate slug from unicode string, URL-friendly slugify with
multiple languages support.
Example:
package main
import(
"github.com/gosimple/slug"
"fmt"
)
func main () {
text := slug.Make("Hellö Wörld хелло ворлд")
fmt.Println(text) // Will print hello-world-khello-vorld
someText := slug.Make("影師")
fmt.Println(someText) // Will print: ying-shi
enText := slug.MakeLang("This & that", "en")
fmt.Println(enText) // Will print 'this-and-that'
deText := slug.MakeLang("Diese & Dass", "de")
fmt.Println(deText) // Will print 'diese-und-dass'
slug.CustomSub = map[string]string{
"water": "sand",
}
textSub := slug.Make("water is hot")
fmt.Println(textSub) // Will print 'sand-is-hot'
}
Requests or bugs?
https://github.com/gosimple/slug/issues
*/
package slug

View File

@@ -0,0 +1,57 @@
// Copyright 2013 by Dobrosław Żybort. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package slug
func init() {
// Merge language subs with the default one
for _, sub := range []*map[rune]string{&deSub, &enSub, &plSub, &esSub} {
for key, value := range defaultSub {
(*sub)[key] = value
}
}
}
var defaultSub = map[rune]string{
'"': "",
'\'': "",
'': "",
'': "-", // figure dash
'': "-", // en dash
'—': "-", // em dash
'―': "-", // horizontal bar
}
var deSub = map[rune]string{
'&': "und",
'@': "an",
}
var enSub = map[rune]string{
'&': "and",
'@': "at",
}
var plSub = map[rune]string{
'&': "i",
'@': "na",
}
var esSub = map[rune]string{
'&': "y",
'@': "en",
}
var grSub = map[rune]string{
'&': "kai",
'η': "i",
'ή': "i",
'Η': "i",
'ι': "i",
'ί': "i",
'Ι': "i",
'χ': "x",
'Χ': "x",
}

157
vendor/github.com/gosimple/slug/slug.go generated vendored Normal file
View File

@@ -0,0 +1,157 @@
// Copyright 2013 by Dobrosław Żybort. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package slug
import (
"bytes"
"regexp"
"sort"
"strings"
"github.com/rainycape/unidecode"
)
var (
// CustomSub stores custom substitution map
CustomSub map[string]string
// CustomRuneSub stores custom rune substitution map
CustomRuneSub map[rune]string
// MaxLength stores maximum slug length.
// It's smart so it will cat slug after full word.
// By default slugs aren't shortened.
// If MaxLength is smaller than length of the first word, then returned
// slug will contain only substring from the first word truncated
// after MaxLength.
MaxLength int
regexpNonAuthorizedChars = regexp.MustCompile("[^a-z0-9-_]")
regexpMultipleDashes = regexp.MustCompile("-+")
)
//=============================================================================
// Make returns slug generated from provided string. Will use "en" as language
// substitution.
func Make(s string) (slug string) {
return MakeLang(s, "en")
}
// MakeLang returns slug generated from provided string and will use provided
// language for chars substitution.
func MakeLang(s string, lang string) (slug string) {
slug = strings.TrimSpace(s)
// Custom substitutions
// Always substitute runes first
slug = SubstituteRune(slug, CustomRuneSub)
slug = Substitute(slug, CustomSub)
// Process string with selected substitution language
switch lang {
case "de":
slug = SubstituteRune(slug, deSub)
case "en":
slug = SubstituteRune(slug, enSub)
case "pl":
slug = SubstituteRune(slug, plSub)
case "es":
slug = SubstituteRune(slug, esSub)
case "gr":
slug = SubstituteRune(slug, grSub)
default: // fallback to "en" if lang not found
slug = SubstituteRune(slug, enSub)
}
// Process all non ASCII symbols
slug = unidecode.Unidecode(slug)
slug = strings.ToLower(slug)
// Process all remaining symbols
slug = regexpNonAuthorizedChars.ReplaceAllString(slug, "-")
slug = regexpMultipleDashes.ReplaceAllString(slug, "-")
slug = strings.Trim(slug, "-")
if MaxLength > 0 {
slug = smartTruncate(slug)
}
return slug
}
// Substitute returns string with superseded all substrings from
// provided substitution map. Substitution map will be applied in alphabetic
// order. Many passes, on one substitution another one could apply.
func Substitute(s string, sub map[string]string) (buf string) {
buf = s
var keys []string
for k := range sub {
keys = append(keys, k)
}
sort.Strings(keys)
for _, key := range keys {
buf = strings.Replace(buf, key, sub[key], -1)
}
return
}
// SubstituteRune substitutes string chars with provided rune
// substitution map. One pass.
func SubstituteRune(s string, sub map[rune]string) string {
var buf bytes.Buffer
for _, c := range s {
if d, ok := sub[c]; ok {
buf.WriteString(d)
} else {
buf.WriteRune(c)
}
}
return buf.String()
}
func smartTruncate(text string) string {
if len(text) < MaxLength {
return text
}
var truncated string
words := strings.SplitAfter(text, "-")
// If MaxLength is smaller than length of the first word return word
// truncated after MaxLength.
if len(words[0]) > MaxLength {
return words[0][:MaxLength]
}
for _, word := range words {
if len(truncated)+len(word)-1 <= MaxLength {
truncated = truncated + word
} else {
break
}
}
return strings.Trim(truncated, "-")
}
// IsSlug returns True if provided text does not contain white characters,
// punctuation, all letters are lower case and only from ASCII range.
// It could contain `-` and `_` but not at the beginning or end of the text.
// It should be in range of the MaxLength var if specified.
// All output from slug.Make(text) should pass this test.
func IsSlug(text string) bool {
if text == "" ||
(MaxLength > 0 && len(text) > MaxLength) ||
text[0] == '-' || text[0] == '_' ||
text[len(text)-1] == '-' || text[len(text)-1] == '_' {
return false
}
for _, c := range text {
if (c < 'a' || c > 'z') && c != '-' && c != '_' && (c < '0' || c > '9') {
return false
}
}
return true
}

30
vendor/github.com/grafana-tools/sdk/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,30 @@
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
*.test
*.prof
# Tests
coverage.out
# IDE
.idea

110
vendor/github.com/grafana-tools/sdk/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,110 @@
---
language: go
services:
- docker
# Different Grafana + Go versions that will be tested.
jobs:
include:
- name: "Grafana 6.7.1 1.14.x"
env:
- "GRAFANA_VERSION=6.7.1"
- "GRAFANA_INTEGRATION=1"
go: "1.14.x"
- name: "Grafana 6.6.2 1.14.x"
env:
- "GRAFANA_VERSION=6.6.2"
- "GRAFANA_INTEGRATION=1"
go: "1.14.x"
- name: "Grafana 6.5.3 1.14.x"
env:
- "GRAFANA_VERSION=6.5.3"
- "GRAFANA_INTEGRATION=1"
go: "1.14.x"
- name: "Grafana 6.4.5 1.14.x"
env:
- "GRAFANA_VERSION=6.4.5 1.13.x"
- "GRAFANA_INTEGRATION=1"
go: "1.13.x"
- name: "Grafana 6.7.1 1.13.x"
env:
- "GRAFANA_VERSION=6.7.1"
- "GRAFANA_INTEGRATION=1"
go: "1.13.x"
- name: "Grafana 6.6.2 1.13.x"
env:
- "GRAFANA_VERSION=6.6.2"
- "GRAFANA_INTEGRATION=1"
go: "1.13.x"
- name: "Grafana 6.5.3 1.13.x"
env:
- "GRAFANA_VERSION=6.5.3"
- "GRAFANA_INTEGRATION=1"
go: "1.13.x"
- name: "Grafana 6.4.5 1.13.x"
env:
- "GRAFANA_VERSION=6.4.5 1.13.x"
- "GRAFANA_INTEGRATION=1"
go: "1.13.x"
- name: "Grafana 6.7.1 1.12.x"
env:
- "GRAFANA_VERSION=6.7.1"
- "GRAFANA_INTEGRATION=1"
go: "1.12.x"
- name: "Grafana 6.6.2 1.12.x"
env:
- "GRAFANA_VERSION=6.6.2"
- "GRAFANA_INTEGRATION=1"
go: "1.12.x"
- name: "Grafana 6.5.3 1.12.x"
env:
- "GRAFANA_VERSION=6.5.3"
- "GRAFANA_INTEGRATION=1"
go: "1.12.x"
- name: "Grafana 6.4.5 1.12.x"
env:
- "GRAFANA_VERSION=6.4.5"
- "GRAFANA_INTEGRATION=1"
go: "1.12.x"
- name: "Grafana 6.7.1 1.11.x"
env:
- "GRAFANA_VERSION=6.7.1"
- "GRAFANA_INTEGRATION=1"
go: "1.11.x"
- name: "Grafana 6.6.2 1.11.x"
env:
- "GRAFANA_VERSION=6.6.2"
- "GRAFANA_INTEGRATION=1"
go: "1.11.x"
- name: "Grafana 6.5.3 1.11.x"
env:
- "GRAFANA_VERSION=6.5.3"
- "GRAFANA_INTEGRATION=1"
go: "1.11.x"
- name: "Grafana 6.4.5 1.11.x"
env:
- "GRAFANA_VERSION=6.4.5"
- "GRAFANA_INTEGRATION=1"
go: "1.11.x"
# Required for coverage.
before_install:
- go get golang.org/x/tools/cmd/cover
- go get github.com/mattn/goveralls
# Run Grafana
- "docker pull grafana/grafana:$GRAFANA_VERSION"
- "docker network create grafana"
- "docker run -d -p 9222:9222 --network grafana --rm --name headless-shell --shm-size 2G chromedp/headless-shell"
- "docker run --network grafana -e GF_AUTH_ANONYMOUS_ENABLED=true --rm -d -p 3000:3000 grafana/grafana:$GRAFANA_VERSION"
before_script:
- curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $GOPATH/bin
# only one subpackage tested yet
script:
- go build -a -v ./...
- golangci-lint run
- go test -v -covermode=count -coverprofile=coverage.out
- $GOPATH/bin/goveralls -coverprofile=coverage.out -service=travis-ci

201
vendor/github.com/grafana-tools/sdk/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

138
vendor/github.com/grafana-tools/sdk/README.md generated vendored Normal file
View File

@@ -0,0 +1,138 @@
<!--*- mode:markdown -*-->
# Grafana SDK [![Go Report Card](https://goreportcard.com/badge/github.com/grafana-tools/sdk)](https://goreportcard.com/report/github.com/grafana-tools/sdk)
SDK for Go language offers a library for interacting with
[Grafana](http://grafana.org) server from Go applications. It
realizes many of
[HTTP REST API](https://grafana.com/docs/grafana/latest/http_api/) calls for
administration, client, organizations. Beside of them it allows
creating of Grafana objects (dashboards, panels, datasources) locally
and manipulating them for constructing dashboards programmatically.
It would be helpful for massive operations on a large set of
Grafana objects.
It was made foremost for
[autograf](https://github.com/grafana-tools/autograf) project but
later separated from it and moved to this new repository because the
library is useful per se.
## Library design principles
1. SDK offers client functionality so it covers Grafana REST API with
its requests and responses as close as possible.
1. SDK maps Grafana objects (dashboard, row, panel, datasource) to
similar Go structures but not follows exactly all Grafana
abstractions.
1. It doesn't use any logger, instead API functions could return errors
where it need.
1. Prefere no external deps except Go stdlib.
1. Cover SDK calls with unit tests.
## Examples [![GoDoc](https://godoc.org/github.com/grafana-tools/sdk?status.svg)](https://godoc.org/github.com/grafana-tools/sdk)
```go
board := sdk.NewBoard("Sample dashboard title")
board.ID = 1
board.Time.From = "now-30m"
board.Time.To = "now"
row1 := board.AddRow("Sample row title")
row1.Add(sdk.NewGraph("Sample graph"))
graph := sdk.NewGraph("Sample graph 2")
target := sdk.Target{
RefID: "A",
Datasource: "Sample Source 1",
Expr: "sample request 1"}
graph.AddTarget(&target)
row1.Add(graph)
grafanaURL := "http://grafana.host"
c := sdk.NewClient(grafanaURL, "grafana-api-key", sdk.DefaultHTTPClient)
response, err := c.SetDashboard(context.TODO() ,*board, sdk.SetDashboardParams{
Overwrite: false,
})
if err != nil {
fmt.Printf("error on uploading dashboard %s", board.Title)
} else {
fmt.Printf("dashboard URL: %v", grafanaURL+*response.URL)
}
```
The library includes several demo apps for showing API usage:
* [backup-dashboards](cmd/backup-dashboards) — saves all your dashboards as JSON-files.
* [backup-datasources](cmd/backup-datasources) — saves all your datasources as JSON-files.
* [import-datasources](cmd/import-datasources) — imports datasources from JSON-files.
* [import-dashboards](cmd/import-dashboards) — imports dashboards from JSON-files.
You need Grafana API key with _admin rights_ for using these utilities.
## Installation [![Build Status](https://travis-ci.org/grafana-tools/sdk.svg?branch=master)](https://travis-ci.org/grafana-tools/sdk)
Of course Go development environment should be set up first. Then:
go get github.com/grafana-tools/sdk
Dependency packages have included into
distro. [govendor](https://github.com/kardianos/govendor) utility used
for vendoring. The single dependency now is:
go get github.com/gosimple/slug
The "slugify" for URLs is a simple task but this package used in
Grafana server so it used in the SDK for the compatibility reasons.
## Status of REST API realization [![Coverage Status](https://coveralls.io/repos/github/grafana-tools/sdk/badge.svg?branch=master)](https://coveralls.io/github/grafana-tools/sdk?branch=master)
Work on full API implementation still in progress. Currently
implemented only create/update/delete operations for dashboards and
datasources. State of support for misc API parts noted below.
| API | Status |
|-----------------------------|---------------------------|
| Authorization | API tokens and Basic Auth |
| Annotations | partially |
| Dashboards | partially |
| Datasources | + |
| Alert notification channels | + |
| Organization (current) | partially |
| Organizations | partially |
| Users | partially |
| User (actual) | partially |
| Snapshots | partially |
| Frontend settings | - |
| Admin | partially |
There is no exact roadmap. The integration tests are being run against the
following Grafana versions:
* [6.7.1](./travis.yml)
* [6.6.2](/.travis.yml)
* [6.5.3](/.travis.yml)
* [6.4.5](/.travis.yml)
With the following Go versions:
* 1.14.x
* 1.13.x
* 1.12.x
* 1.11.x
I still have interest to this library development but not always have
time for it. So I gladly accept new contributions. Drop an issue or
[contact me](grafov@gmail.com).
## Licence
Distributed under Apache v2.0. All rights belong to the SDK
authors. There is no authors list yet, you can see the full list of
the contributors in the git history. Official repository is
https://github.com/grafana-tools/sdk
## Collection of Grafana tools in Golang
* [github.com/nytm/go-grafana-api](https://github.com/nytm/go-grafana-api) — a golang client of Grafana project currently that realizes parts of the REST API, used for the Grafana Terraform provider.
* [github.com/adejoux/grafanaclient](https://github.com/adejoux/grafanaclient) — API to manage Grafana 2.0 datasources and dashboards. It lacks features from 2.5 and later Grafana versions.
* [github.com/mgit-at/grafana-backup](https://github.com/mgit-at/grafana-backup) — just saves dashboards localy.
* [github.com/raintank/memo](https://github.com/raintank/memo) — send slack mentions to Grafana annotations.
* [github.com/retzkek/grafctl](https://github.com/retzkek/grafctl) — backup/restore/track dashboards with git.
* [github.com/grafana/grizzly](https://github.com/grafana/grizzly) — manage Grafana dashboards via CLI and libsonnet/jsonnet

29
vendor/github.com/grafana-tools/sdk/address.go generated vendored Normal file
View File

@@ -0,0 +1,29 @@
package sdk
/*
Copyright 2016 Alexander I.Grafov <grafov@gmail.com>
Copyright 2016-2019 The Grafana SDK authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
ॐ तारे तुत्तारे तुरे स्व
*/
type Address struct {
Address1 string `json:"address1"`
Address2 string `json:"address2"`
City string `json:"city"`
ZipCode string `json:"zipCode"`
State string `json:"state"`
Country string `json:"country"`
}

View File

@@ -0,0 +1,31 @@
package sdk
/*
Copyright 2016-2020 The Grafana SDK authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// AlertNotification as described in the doc
// https://grafana.com/docs/grafana/latest/http_api/alerting_notification_channels/
type AlertNotification struct {
ID int64 `json:"id,omitempty"`
Name string `json:"name"`
Type string `json:"type"`
IsDefault bool `json:"isDefault"`
DisableResolveMessage bool `json:"disableResolveMessage"`
SendReminder bool `json:"sendReminder"`
Frequency string `json:"frequency"`
Settings interface{} `json:"settings"`
UID string `json:"uid,omitempty"`
}

37
vendor/github.com/grafana-tools/sdk/annotation.go generated vendored Normal file
View File

@@ -0,0 +1,37 @@
package sdk
// AnnotationResponse is representation of an existing annotation
type AnnotationResponse struct {
ID uint `json:"id"`
AlertID uint `json:"alertId"`
DashboardID uint `json:"dashboardId,omitempty"`
PanelID uint `json:"panelId,omitempty"`
UserID uint `json:"userId,omitempty"`
UserName string `json:"userName,omitempty"`
NewState string `json:"newState,omitempty"`
PrevState string `json:"prevState,omitempty"`
Time int64 `json:"time,omitempty"`
TimeEnd int64 `json:"timeEnd,omitempty"`
Tags []string `json:"tags,omitempty"`
Text string `json:"text,omitempty"`
Type string `json:"type"`
Data map[string]interface{} `json:"data"`
}
// CreateAnnotationRequest is a request to create a new annotation
type CreateAnnotationRequest struct {
DashboardID uint `json:"dashboardId,omitempty"`
PanelID uint `json:"panelId,omitempty"`
Time int64 `json:"time,omitempty"`
TimeEnd int64 `json:"timeEnd,omitempty"`
Tags []string `json:"tags,omitempty"`
Text string `json:"text,omitempty"`
}
// PatchAnnotationRequest is a request to patch an existing annotation
type PatchAnnotationRequest struct {
Time int64 `json:"time,omitempty"`
TimeEnd int64 `json:"timeEnd,omitempty"`
Tags []string `json:"tags,omitempty"`
Text string `json:"text,omitempty"`
}

240
vendor/github.com/grafana-tools/sdk/board.go generated vendored Normal file
View File

@@ -0,0 +1,240 @@
package sdk
/*
Copyright 2016 Alexander I.Grafov <grafov@gmail.com>
Copyright 2016-2019 The Grafana SDK authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
ॐ तारे तुत्तारे तुरे स्व
*/
import (
"bytes"
"encoding/json"
"strings"
"github.com/gosimple/slug"
)
var (
boardID uint
)
// Constants for templating
const (
TemplatingHideNone = iota
TemplatingHideLabel
TemplatingHideVariable
)
type (
// Board represents Grafana dashboard.
Board struct {
ID uint `json:"id,omitempty"`
UID string `json:"uid,omitempty"`
Slug string `json:"slug"`
Title string `json:"title"`
OriginalTitle string `json:"originalTitle"`
Tags []string `json:"tags"`
Style string `json:"style"`
Timezone string `json:"timezone"`
Editable bool `json:"editable"`
HideControls bool `json:"hideControls" graf:"hide-controls"`
SharedCrosshair bool `json:"sharedCrosshair" graf:"shared-crosshair"`
Panels []*Panel `json:"panels"`
Rows []*Row `json:"rows"`
Templating Templating `json:"templating"`
Annotations struct {
List []Annotation `json:"list"`
} `json:"annotations"`
Refresh *BoolString `json:"refresh,omitempty"`
SchemaVersion uint `json:"schemaVersion"`
Version uint `json:"version"`
Links []Link `json:"links"`
Time Time `json:"time"`
Timepicker Timepicker `json:"timepicker"`
GraphTooltip int `json:"graphTooltip,omitempty"`
}
Time struct {
From string `json:"from"`
To string `json:"to"`
}
Timepicker struct {
Now *bool `json:"now,omitempty"`
RefreshIntervals []string `json:"refresh_intervals"`
TimeOptions []string `json:"time_options"`
}
Templating struct {
List []TemplateVar `json:"list"`
}
TemplateVar struct {
Name string `json:"name"`
Type string `json:"type"`
Auto bool `json:"auto,omitempty"`
AutoCount *int `json:"auto_count,omitempty"`
Datasource *string `json:"datasource"`
Refresh BoolInt `json:"refresh"`
Options []Option `json:"options"`
IncludeAll bool `json:"includeAll"`
AllFormat string `json:"allFormat"`
AllValue string `json:"allValue"`
Multi bool `json:"multi"`
MultiFormat string `json:"multiFormat"`
Query interface{} `json:"query"`
Regex string `json:"regex"`
Current Current `json:"current"`
Label string `json:"label"`
Hide uint8 `json:"hide"`
Sort int `json:"sort"`
}
// for templateVar
Option struct {
Text string `json:"text"`
Value string `json:"value"`
Selected bool `json:"selected"`
}
// for templateVar
Current struct {
Tags []*string `json:"tags,omitempty"`
Text *StringSliceString `json:"text"`
Value interface{} `json:"value"` // TODO select more precise type
}
Annotation struct {
Name string `json:"name"`
Datasource *string `json:"datasource"`
ShowLine bool `json:"showLine"`
IconColor string `json:"iconColor"`
LineColor string `json:"lineColor"`
IconSize uint `json:"iconSize"`
Enable bool `json:"enable"`
Query string `json:"query"`
Expr string `json:"expr"`
Step string `json:"step"`
TextField string `json:"textField"`
TextFormat string `json:"textFormat"`
TitleFormat string `json:"titleFormat"`
TagsField string `json:"tagsField"`
Tags []string `json:"tags"`
TagKeys string `json:"tagKeys"`
Type string `json:"type"`
}
// Link represents link to another dashboard or external weblink
Link struct {
Title string `json:"title"`
Type string `json:"type"`
AsDropdown *bool `json:"asDropdown,omitempty"`
DashURI *string `json:"dashUri,omitempty"`
Dashboard *string `json:"dashboard,omitempty"`
Icon *string `json:"icon,omitempty"`
IncludeVars bool `json:"includeVars"`
KeepTime *bool `json:"keepTime,omitempty"`
Params *string `json:"params,omitempty"`
Tags []string `json:"tags,omitempty"`
TargetBlank *bool `json:"targetBlank,omitempty"`
Tooltip *string `json:"tooltip,omitempty"`
URL *string `json:"url,omitempty"`
}
)
// Height of rows maybe passed as number (ex 200) or
// as string (ex "200px") or empty string
type Height string
func (h *Height) UnmarshalJSON(raw []byte) error {
if raw == nil || bytes.Equal(raw, []byte(`"null"`)) {
return nil
}
if raw[0] != '"' {
tmp := []byte{'"'}
raw = append(tmp, raw...)
raw = append(raw, byte('"'))
}
var tmp string
err := json.Unmarshal(raw, &tmp)
*h = Height(tmp)
return err
}
func NewBoard(title string) *Board {
boardID++
return &Board{
ID: boardID,
Title: title,
Style: "dark",
Timezone: "browser",
Editable: true,
HideControls: false,
Rows: []*Row{},
}
}
func (b *Board) AddLink(link Link) {
b.Links = append(b.Links, link)
}
func (b *Board) RemoveTags(tags ...string) {
// order might change after removing the tags
for _, toRemoveTag := range tags {
tagLen := len(b.Tags)
for i, tag := range b.Tags {
if tag == toRemoveTag {
b.Tags[tagLen-1], b.Tags[i] = b.Tags[i], b.Tags[tagLen-1]
b.Tags = b.Tags[:tagLen-1]
break
}
}
}
}
func (b *Board) AddTags(tags ...string) {
tagFound := make(map[string]bool, len(b.Tags))
for _, tag := range b.Tags {
tagFound[tag] = true
}
for _, tag := range tags {
if tagFound[tag] {
continue
}
b.Tags = append(b.Tags, tag)
tagFound[tag] = true
}
}
func (b *Board) HasTag(tag string) bool {
for _, t := range b.Tags {
if t == tag {
return true
}
}
return false
}
func (b *Board) AddRow(title string) *Row {
if title == "" {
title = "New row"
}
row := &Row{
Title: title,
Collapse: false,
Editable: true,
Height: "250px",
}
b.Rows = append(b.Rows, row)
return row
}
func (b *Board) UpdateSlug() string {
b.Slug = strings.ToLower(slug.Make(b.Title))
return b.Slug
}

235
vendor/github.com/grafana-tools/sdk/custom-types.go generated vendored Normal file
View File

@@ -0,0 +1,235 @@
package sdk
/*
Copyright 2016 Alexander I.Grafov <grafov@gmail.com>
Copyright 2016-2019 The Grafana SDK authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
ॐ तारे तुत्तारे तुरे स्व
*/
import (
"bytes"
"encoding/json"
"errors"
"strconv"
"strings"
)
type BoolString struct {
Flag bool
Value string
}
func (s *BoolString) UnmarshalJSON(raw []byte) error {
if raw == nil || bytes.Equal(raw, []byte(`"null"`)) {
return nil
}
var (
tmp string
err error
)
if raw[0] != '"' {
if bytes.Equal(raw, []byte("true")) {
s.Flag = true
return nil
}
if bytes.Equal(raw, []byte("false")) {
return nil
}
return errors.New("bad boolean value provided")
}
if err = json.Unmarshal(raw, &tmp); err != nil {
return err
}
s.Value = tmp
return nil
}
func (s BoolString) MarshalJSON() ([]byte, error) {
if s.Value != "" {
var buf bytes.Buffer
buf.WriteRune('"')
buf.WriteString(s.Value)
buf.WriteRune('"')
return buf.Bytes(), nil
}
return strconv.AppendBool([]byte{}, s.Flag), nil
}
type BoolInt struct {
Flag bool
Value *int64
}
func (s *BoolInt) UnmarshalJSON(raw []byte) error {
if raw == nil || bytes.Equal(raw, []byte(`"null"`)) {
return nil
}
var (
tmp int64
err error
)
if tmp, err = strconv.ParseInt(string(raw), 10, 64); err != nil {
if bytes.Equal(raw, []byte("true")) {
s.Flag = true
return nil
}
if bytes.Equal(raw, []byte("false")) {
return nil
}
return errors.New("bad value provided")
}
s.Value = &tmp
return nil
}
func (s BoolInt) MarshalJSON() ([]byte, error) {
if s.Value != nil {
return strconv.AppendInt([]byte{}, *s.Value, 10), nil
}
return strconv.AppendBool([]byte{}, s.Flag), nil
}
func NewIntString(i int64) *IntString {
return &IntString{
Value: i,
Valid: true,
}
}
// IntString represents special type for json values that could be strings or ints: 100 or "100"
type IntString struct {
Value int64
Valid bool
}
// UnmarshalJSON implements custom unmarshalling for IntString type
func (v *IntString) UnmarshalJSON(raw []byte) error {
if raw == nil || bytes.Equal(raw, []byte(`"null"`)) || bytes.Equal(raw, []byte(`""`)) {
return nil
}
strVal := string(raw)
if rune(raw[0]) == '"' {
strVal = strings.Trim(strVal, `"`)
}
i, err := strconv.ParseInt(strVal, 10, 64)
if err != nil {
return err
}
v.Value = i
v.Valid = true
return nil
}
// MarshalJSON implements custom marshalling for IntString type
func (v *IntString) MarshalJSON() ([]byte, error) {
if v.Valid {
strVal := strconv.FormatInt(v.Value, 10)
return []byte(strVal), nil
}
return []byte(`"null"`), nil
}
func NewFloatString(i float64) *FloatString {
return &FloatString{
Value: i,
Valid: true,
}
}
// FloatString represents special type for json values that could be strings or ints: 100 or "100"
type FloatString struct {
Value float64
Valid bool
}
// UnmarshalJSON implements custom unmarshalling for FloatString type
func (v *FloatString) UnmarshalJSON(raw []byte) error {
if raw == nil || bytes.Equal(raw, []byte(`"null"`)) || bytes.Equal(raw, []byte(`""`)) {
return nil
}
strVal := string(raw)
if rune(raw[0]) == '"' {
strVal = strings.Trim(strVal, `"`)
}
i, err := strconv.ParseFloat(strVal, 64)
if err != nil {
return err
}
v.Value = i
v.Valid = true
return nil
}
// MarshalJSON implements custom marshalling for FloatString type
func (v *FloatString) MarshalJSON() ([]byte, error) {
if v.Valid {
strVal := strconv.FormatFloat(v.Value, 'g', -1, 64)
return []byte(strVal), nil
}
return []byte(`"null"`), nil
}
// StringSliceString represents special type for json values that could be
// strings or slice of strings: "something" or ["something"].
type StringSliceString struct {
Value []string
Valid bool
}
// UnmarshalJSON implements custom unmarshalling for StringSliceString type.
func (v *StringSliceString) UnmarshalJSON(raw []byte) error {
if raw == nil || bytes.Equal(raw, []byte(`"null"`)) {
return nil
}
// First try with string.
var str string
if err := json.Unmarshal(raw, &str); err == nil {
v.Value = []string{str}
v.Valid = true
return nil
}
// Lastly try with string slice.
var strSlice []string
err := json.Unmarshal(raw, &strSlice)
if err != nil {
return err
}
v.Value = strSlice
v.Valid = true
return nil
}
// MarshalJSON implements custom marshalling for StringSliceString type.
func (v *StringSliceString) MarshalJSON() ([]byte, error) {
if !v.Valid {
return []byte(`"null"`), nil
}
return json.Marshal(v.Value)
}

54
vendor/github.com/grafana-tools/sdk/datasource.go generated vendored Normal file
View File

@@ -0,0 +1,54 @@
package sdk
/*
Copyright 2016 Alexander I.Grafov <grafov@gmail.com>
Copyright 2016-2019 The Grafana SDK authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
ॐ तारे तुत्तारे तुरे स्व
*/
// Datasource as described in the doc
// http://docs.grafana.org/reference/http_api/#get-all-datasources
type Datasource struct {
ID uint `json:"id"`
OrgID uint `json:"orgId"`
Name string `json:"name"`
Type string `json:"type"`
Access string `json:"access"` // direct or proxy
URL string `json:"url"`
Password *string `json:"password,omitempty"`
User *string `json:"user,omitempty"`
Database *string `json:"database,omitempty"`
BasicAuth *bool `json:"basicAuth,omitempty"`
BasicAuthUser *string `json:"basicAuthUser,omitempty"`
BasicAuthPassword *string `json:"basicAuthPassword,omitempty"`
IsDefault bool `json:"isDefault"`
JSONData interface{} `json:"jsonData"`
SecureJSONData interface{} `json:"secureJsonData"`
}
// Datasource type as described in
// http://docs.grafana.org/reference/http_api/#available-data-source-types
type DatasourceType struct {
Metrics bool `json:"metrics"`
Module string `json:"module"`
Name string `json:"name"`
Partials struct {
Query string `json:"query"`
} `json:"datasource"`
PluginType string `json:"pluginType"`
ServiceName string `json:"serviceName"`
Type string `json:"type"`
}

39
vendor/github.com/grafana-tools/sdk/folder.go generated vendored Normal file
View File

@@ -0,0 +1,39 @@
package sdk
/*
Copyright 2016 Alexander I.Grafov <grafov@gmail.com>
Copyright 2016-2019 The Grafana SDK authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
ॐ तारे तुत्तारे तुरे स्व
*/
// Folder as described in the doc
// https://grafana.com/docs/grafana/latest/http_api/folder/#get-all-folders
type Folder struct {
ID int `json:"id"`
UID string `json:"uid"`
Title string `json:"title"`
URL string `json:"url"`
HasAcl bool `json:"hasAcl"`
CanSave bool `json:"canSave"`
CanEdit bool `json:"canEdit"`
CanAdmin bool `json:"canAdmin"`
CreatedBy string `json:"createdBy"`
Created string `json:"created"`
UpdatedBy string `json:"updatedBy"`
Updated string `json:"updated"`
Version int `json:"version"`
Overwrite bool `json:"overwrite"`
}

11
vendor/github.com/grafana-tools/sdk/go.mod generated vendored Normal file
View File

@@ -0,0 +1,11 @@
module github.com/grafana-tools/sdk
go 1.13
require (
github.com/chromedp/cdproto v0.0.0-20210122124816-7a656c010d57
github.com/chromedp/chromedp v0.6.5
github.com/gosimple/slug v1.1.1
github.com/pkg/errors v0.9.1
github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be // indirect
)

23
vendor/github.com/grafana-tools/sdk/go.sum generated vendored Normal file
View File

@@ -0,0 +1,23 @@
github.com/chromedp/cdproto v0.0.0-20210122124816-7a656c010d57 h1:htpyTFarq7OHx9SpkQ+7x20thTQA6JAsgnuMGoPbH4E=
github.com/chromedp/cdproto v0.0.0-20210122124816-7a656c010d57/go.mod h1:55pim6Ht4LJKdVLlyFJV/g++HsEA1hQxPbB5JyNdZC0=
github.com/chromedp/chromedp v0.6.5 h1:hPaDYBpvD2WFicln0ByzV+XRhSOtLgAgsu39O455iWY=
github.com/chromedp/chromedp v0.6.5/go.mod h1:/Q6h52DkrFuvOgmCuR6O3xT5g0bZYoPqjANKBEvQGEY=
github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic=
github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww=
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gobwas/ws v1.0.4 h1:5eXU1CZhpQdq5kXbKb+sECH5Ia5KiO6CYzIzdlVx6Bs=
github.com/gobwas/ws v1.0.4/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
github.com/gosimple/slug v1.1.1 h1:fRu/digW+NMwBIP+RmviTK97Ho/bEj/C9swrCspN3D4=
github.com/gosimple/slug v1.1.1/go.mod h1:ER78kgg1Mv0NQGlXiDe57DpCyfbNywXXZ9mIorhxAf0=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be h1:ta7tUOvsPHVHGom5hKW5VXNc2xZIkfCKP8iaqOyYtUQ=
github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be/go.mod h1:MIDFMn7db1kT65GmV94GzpX9Qdi7N/pQlwb+AN8wh+Q=
golang.org/x/sys v0.0.0-20210122093101-04d7465088b8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

33
vendor/github.com/grafana-tools/sdk/org.go generated vendored Normal file
View File

@@ -0,0 +1,33 @@
package sdk
/*
Copyright 2016-2017 Alexander I.Grafov <grafov@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
ॐ तारे तुत्तारे तुरे स्व
*/
type Org struct {
ID uint `json:"id"`
Name string `json:"name"`
Address Address `json:"address"`
}
type OrgUser struct {
ID uint `json:"userId"`
OrgId uint `json:"orgId"`
Email string `json:"email"`
Login string `json:"login"`
Role string `json:"role"`
}

1070
vendor/github.com/grafana-tools/sdk/panel.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

26
vendor/github.com/grafana-tools/sdk/preferences.go generated vendored Normal file
View File

@@ -0,0 +1,26 @@
package sdk
/*
Copyright 2016 Alexander I.Grafov <grafov@gmail.com>
Copyright 2016-2019 The Grafana SDK authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
ॐ तारे तुत्तारे तुरे स्व
*/
type Preferences struct {
Theme string `json:"theme,omitempty"`
HomeDashboardId uint `json:"homeDashboardId,omitempty"`
Timezone string `json:"timezone,omitempty"`
}

66
vendor/github.com/grafana-tools/sdk/rest-admin.go generated vendored Normal file
View File

@@ -0,0 +1,66 @@
package sdk
import (
"context"
"encoding/json"
"fmt"
)
// CreateUser creates a new global user.
// Requires basic authentication and that the authenticated user is a Grafana Admin.
// Reflects POST /api/admin/users API call.
func (r *Client) CreateUser(ctx context.Context, user User) (StatusMessage, error) {
var (
raw []byte
resp StatusMessage
err error
)
if raw, err = json.Marshal(user); err != nil {
return StatusMessage{}, err
}
if raw, _, err = r.post(ctx, "api/admin/users", nil, raw); err != nil {
return StatusMessage{}, err
}
if err = json.Unmarshal(raw, &resp); err != nil {
return StatusMessage{}, err
}
return resp, nil
}
// UpdateUserPermissions updates the permissions of a global user.
// Requires basic authentication and that the authenticated user is a Grafana Admin.
// Reflects PUT /api/admin/users/:userId/password API call.
func (r *Client) UpdateUserPermissions(ctx context.Context, permissions UserPermissions, uid uint) (StatusMessage, error) {
var (
raw []byte
reply StatusMessage
err error
)
if raw, err = json.Marshal(permissions); err != nil {
return StatusMessage{}, err
}
if raw, _, err = r.put(ctx, fmt.Sprintf("api/admin/users/%d/permissions", uid), nil, raw); err != nil {
return StatusMessage{}, err
}
err = json.Unmarshal(raw, &reply)
return reply, err
}
// SwitchUserContext switches user context to the given organization.
// Requires basic authentication and that the authenticated user is a Grafana Admin.
// Reflects POST /api/users/:userId/using/:organizationId API call.
func (r *Client) SwitchUserContext(ctx context.Context, uid uint, oid uint) (StatusMessage, error) {
var (
raw []byte
resp StatusMessage
err error
)
if raw, _, err = r.post(ctx, fmt.Sprintf("/api/users/%d/using/%d", uid, oid), nil, raw); err != nil {
return StatusMessage{}, err
}
if err = json.Unmarshal(raw, &resp); err != nil {
return StatusMessage{}, err
}
return resp, nil
}

View File

@@ -0,0 +1,178 @@
package sdk
/*
Copyright 2016-2020 The Grafana SDK authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import (
"context"
"encoding/json"
"fmt"
)
// GetAllAlertNotifications gets all alert notification channels.
// Reflects GET /api/alert-notifications API call.
func (c *Client) GetAllAlertNotifications(ctx context.Context) ([]AlertNotification, error) {
var (
raw []byte
an []AlertNotification
code int
err error
)
if raw, code, err = c.get(ctx, "api/alert-notifications", nil); err != nil {
return nil, err
}
if code != 200 {
return nil, fmt.Errorf("HTTP error %d: returns %s", code, raw)
}
err = json.Unmarshal(raw, &an)
return an, err
}
// GetAlertNotificationUID gets the alert notification channel which has the specified uid.
// Reflects GET /api/alert-notifications/uid/:uid API call.
func (c *Client) GetAlertNotificationUID(ctx context.Context, uid string) (AlertNotification, error) {
var (
raw []byte
an AlertNotification
code int
err error
)
if raw, code, err = c.get(ctx, fmt.Sprintf("api/alert-notifications/uid/%s", uid), nil); err != nil {
return an, err
}
if code != 200 {
return an, fmt.Errorf("HTTP error %d: returns %s", code, raw)
}
err = json.Unmarshal(raw, &an)
return an, err
}
// GetAlertNotificationID gets the alert notification channel which has the specified id.
// Reflects GET /api/alert-notifications/:id API call.
func (c *Client) GetAlertNotificationID(ctx context.Context, id uint) (AlertNotification, error) {
var (
raw []byte
an AlertNotification
code int
err error
)
if raw, code, err = c.get(ctx, fmt.Sprintf("api/alert-notifications/%d", id), nil); err != nil {
return an, err
}
if code != 200 {
return an, fmt.Errorf("HTTP error %d: returns %s", code, raw)
}
err = json.Unmarshal(raw, &an)
return an, err
}
// CreateAlertNotification creates a new alert notification channel.
// Reflects POST /api/alert-notifications API call.
func (c *Client) CreateAlertNotification(ctx context.Context, an AlertNotification) (int64, error) {
var (
raw []byte
code int
err error
)
if raw, err = json.Marshal(an); err != nil {
return -1, err
}
if raw, code, err = c.post(ctx, "api/alert-notifications", nil, raw); err != nil {
return -1, err
}
if code != 200 {
return -1, fmt.Errorf("HTTP error %d: returns %s", code, raw)
}
result := struct {
ID int64 `json:"id"`
}{}
err = json.Unmarshal(raw, &result)
return result.ID, err
}
// UpdateAlertNotificationUID updates the specified alert notification channel.
// Reflects PUT /api/alert-notifications/uid/:uid API call.
func (c *Client) UpdateAlertNotificationUID(ctx context.Context, an AlertNotification, uid string) error {
var (
raw []byte
code int
err error
)
if raw, err = json.Marshal(an); err != nil {
return err
}
if raw, code, err = c.put(ctx, fmt.Sprintf("api/alert-notifications/uid/%s", uid), nil, raw); err != nil {
return err
}
if code != 200 {
return fmt.Errorf("HTTP error %d: returns %s", code, raw)
}
return nil
}
// UpdateAlertNotificationID updates the specified alert notification channel.
// Reflects PUT /api/alert-notifications/:id API call.
func (c *Client) UpdateAlertNotificationID(ctx context.Context, an AlertNotification, id uint) error {
var (
raw []byte
code int
err error
)
if raw, err = json.Marshal(an); err != nil {
return err
}
if raw, code, err = c.put(ctx, fmt.Sprintf("api/alert-notifications/%d", id), nil, raw); err != nil {
return err
}
if code != 200 {
return fmt.Errorf("HTTP error %d: returns %s", code, raw)
}
return nil
}
// DeleteAlertNotificationUID deletes the specified alert notification channel.
// Reflects DELETE /api/alert-notifications/uid/:uid API call.
func (c *Client) DeleteAlertNotificationUID(ctx context.Context, uid string) error {
var (
raw []byte
code int
err error
)
if raw, code, err = c.delete(ctx, fmt.Sprintf("api/alert-notifications/uid/%s", uid)); err != nil {
return err
}
if code != 200 {
return fmt.Errorf("HTTP error %d: returns %s", code, raw)
}
return nil
}
// DeleteAlertNotificationID deletes the specified alert notification channel.
// Reflects DELETE /api/alert-notifications/:id API call.
func (c *Client) DeleteAlertNotificationID(ctx context.Context, id uint) error {
var (
raw []byte
code int
err error
)
if raw, code, err = c.delete(ctx, fmt.Sprintf("api/alert-notifications/%d", id)); err != nil {
return err
}
if code != 200 {
return fmt.Errorf("HTTP error %d: returns %s", code, raw)
}
return nil
}

162
vendor/github.com/grafana-tools/sdk/rest-annotation.go generated vendored Normal file
View File

@@ -0,0 +1,162 @@
package sdk
import (
"context"
"encoding/json"
"fmt"
"net/url"
"strconv"
"time"
"github.com/pkg/errors"
)
// https://grafana.com/docs/grafana/latest/http_api/annotations/
// CreateAnnotation creates a new annotation from the annotation request
func (r *Client) CreateAnnotation(ctx context.Context, a CreateAnnotationRequest) (StatusMessage, error) {
var (
raw []byte
resp StatusMessage
err error
)
if raw, err = json.Marshal(a); err != nil {
return StatusMessage{}, errors.Wrap(err, "marshal request")
}
if raw, _, err = r.post(ctx, "api/annotations", nil, raw); err != nil {
return StatusMessage{}, errors.Wrap(err, "create annotation")
}
if err = json.Unmarshal(raw, &resp); err != nil {
return StatusMessage{}, errors.Wrap(err, "unmarshal response message")
}
return resp, nil
}
// PatchAnnotation patches the annotation with id with the request
func (r *Client) PatchAnnotation(ctx context.Context, id uint, a PatchAnnotationRequest) (StatusMessage, error) {
var (
raw []byte
resp StatusMessage
err error
)
if raw, err = json.Marshal(a); err != nil {
return StatusMessage{}, errors.Wrap(err, "marshal request")
}
if raw, _, err = r.patch(ctx, fmt.Sprintf("api/annotations/%d", id), nil, raw); err != nil {
return StatusMessage{}, errors.Wrap(err, "patch annotation")
}
if err = json.Unmarshal(raw, &resp); err != nil {
return StatusMessage{}, errors.Wrap(err, "unmarshal response message")
}
return resp, nil
}
// GetAnnotations gets annotations matching the annotation parameters
func (r *Client) GetAnnotations(ctx context.Context, params ...GetAnnotationsParams) ([]AnnotationResponse, error) {
var (
raw []byte
err error
resp []AnnotationResponse
requestParams = make(url.Values)
)
for _, p := range params {
p(requestParams)
}
if raw, _, err = r.get(ctx, "api/annotations", requestParams); err != nil {
return nil, errors.Wrap(err, "get annotations")
}
if err = json.Unmarshal(raw, &resp); err != nil {
return nil, errors.Wrap(err, "unmarshal response message")
}
return resp, nil
}
// DeleteAnnotation deletes the annotation with id
func (r *Client) DeleteAnnotation(ctx context.Context, id uint) (StatusMessage, error) {
var (
raw []byte
err error
resp StatusMessage
)
if raw, _, err = r.delete(ctx, fmt.Sprintf("api/annotations/%d", id)); err != nil {
return StatusMessage{}, errors.Wrap(err, "delete annotation")
}
if err = json.Unmarshal(raw, &resp); err != nil {
return StatusMessage{}, errors.Wrap(err, "unmarshal response message")
}
return resp, nil
}
// GetAnnotationsParams is the type for all options implementing query parameters
// https://grafana.com/docs/grafana/latest/http_api/annotations/#find-annotations
type GetAnnotationsParams func(values url.Values)
// WithTag adds the tag to the
func WithTag(tag string) GetAnnotationsParams {
return func(v url.Values) {
v.Add("tags", tag)
}
}
// WithLimit sets the max number of alerts to return
func WithLimit(limit uint) GetAnnotationsParams {
return func(v url.Values) {
v.Set("limit", strconv.FormatUint(uint64(limit), 10))
}
}
// WithAnnotationType filters the type to annotations
func WithAnnotationType() GetAnnotationsParams {
return func(v url.Values) {
v.Set("type", "annotation")
}
}
// WithAlertType filters the type to alerts
func WithAlertType() GetAnnotationsParams {
return func(v url.Values) {
v.Set("type", "alert")
}
}
// WithDashboard filters the response to the specified dashboard ID
func WithDashboard(id uint) GetAnnotationsParams {
return func(v url.Values) {
v.Set("dashboardId", strconv.FormatUint(uint64(id), 10))
}
}
// WithPanel filters the response to the specified panel ID
func WithPanel(id uint) GetAnnotationsParams {
return func(v url.Values) {
v.Set("panelId", strconv.FormatUint(uint64(id), 10))
}
}
// WithUser filters the annotations to only be made by the specified user ID
func WithUser(id uint) GetAnnotationsParams {
return func(v url.Values) {
v.Set("userId", strconv.FormatUint(uint64(id), 10))
}
}
// WithStartTime filters the annotations to after the specified time
func WithStartTime(t time.Time) GetAnnotationsParams {
return func(v url.Values) {
v.Set("from", strconv.FormatInt(toMilliseconds(t), 10))
}
}
// WithEndTime filters the annotations to before the specified time
func WithEndTime(t time.Time) GetAnnotationsParams {
return func(v url.Values) {
v.Set("to", strconv.FormatInt(toMilliseconds(t), 10))
}
}
func toMilliseconds(t time.Time) int64 {
return t.UnixNano() / 1000000
}

456
vendor/github.com/grafana-tools/sdk/rest-dashboard.go generated vendored Normal file
View File

@@ -0,0 +1,456 @@
package sdk
/*
Copyright 2016 Alexander I.Grafov <grafov@gmail.com>
Copyright 2016-2019 The Grafana SDK authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
ॐ तारे तुत्तारे तुरे स्व
*/
import (
"bytes"
"context"
"encoding/json"
"fmt"
"net/url"
"strconv"
"strings"
"time"
"github.com/pkg/errors"
)
// DefaultFolderId is the id of the general folder
// that is pre-created and cannot be removed.
const DefaultFolderId = 0
// BoardProperties keeps metadata of a dashboard.
type BoardProperties struct {
IsStarred bool `json:"isStarred,omitempty"`
IsHome bool `json:"isHome,omitempty"`
IsSnapshot bool `json:"isSnapshot,omitempty"`
Type string `json:"type,omitempty"`
CanSave bool `json:"canSave"`
CanEdit bool `json:"canEdit"`
CanStar bool `json:"canStar"`
Slug string `json:"slug"`
Expires time.Time `json:"expires"`
Created time.Time `json:"created"`
Updated time.Time `json:"updated"`
UpdatedBy string `json:"updatedBy"`
CreatedBy string `json:"createdBy"`
Version int `json:"version"`
FolderID int `json:"folderId"`
FolderTitle string `json:"folderTitle"`
FolderURL string `json:"folderUrl"`
}
// GetDashboardByUID loads a dashboard and its metadata from Grafana by dashboard uid.
//
// Reflects GET /api/dashboards/uid/:uid API call.
func (r *Client) GetDashboardByUID(ctx context.Context, uid string) (Board, BoardProperties, error) {
return r.getDashboard(ctx, "uid/"+uid)
}
// GetDashboardBySlug loads a dashboard and its metadata from Grafana by dashboard slug.
//
// For dashboards from a filesystem set "file/" prefix for slug. By default dashboards from
// a database assumed. Database dashboards may have "db/" prefix or may have not, it will
// be appended automatically.
//
// Reflects GET /api/dashboards/db/:slug API call.
// Deprecated: since Grafana v5 you should use uids. Use GetDashboardByUID() for that.
func (r *Client) GetDashboardBySlug(ctx context.Context, slug string) (Board, BoardProperties, error) {
path := setPrefix(slug)
return r.getDashboard(ctx, path)
}
// getDashboard loads a dashboard from Grafana instance along with metadata for a dashboard.
// For dashboards from a filesystem set "file/" prefix for slug. By default dashboards from
// a database assumed. Database dashboards may have "db/" prefix or may have not, it will
// be appended automatically.
//
// Reflects GET /api/dashboards/db/:slug API call.
func (r *Client) getDashboard(ctx context.Context, path string) (Board, BoardProperties, error) {
raw, bp, err := r.getRawDashboard(ctx, path)
if err != nil {
return Board{}, BoardProperties{}, errors.Wrap(err, "get raw dashboard")
}
var (
result struct {
Meta BoardProperties `json:"meta"`
Board Board `json:"dashboard"`
}
)
dec := json.NewDecoder(bytes.NewReader(raw))
dec.UseNumber()
if err := dec.Decode(&result.Board); err != nil {
return Board{}, BoardProperties{}, errors.Wrap(err, "unmarshal board")
}
return result.Board, bp, err
}
// GetRawDashboard loads a dashboard JSON from Grafana instance along with metadata for a dashboard.
// Contrary to GetDashboard() it not unpack loaded JSON to Board structure. Instead it
// returns it as byte slice. It guarantee that data of dashboard returned untouched by conversion
// with Board so no matter how properly fields from a current version of Grafana mapped to
// our Board fields. It useful for backuping purposes when you want a dashboard exactly with
// same data as it exported by Grafana.
//
// For dashboards from a filesystem set "file/" prefix for slug. By default dashboards from
// a database assumed. Database dashboards may have "db/" prefix or may have not, it will
// be appended automatically.
//
// Reflects GET /api/dashboards/db/:slug API call.
// Deprecated: since Grafana v5 you should use uids. Use GetRawDashboardByUID() for that.
func (r *Client) getRawDashboard(ctx context.Context, path string) ([]byte, BoardProperties, error) {
var (
raw []byte
result struct {
Meta BoardProperties `json:"meta"`
Board json.RawMessage `json:"dashboard"`
}
code int
err error
)
if raw, code, err = r.get(ctx, fmt.Sprintf("api/dashboards/%s", path), nil); err != nil {
return nil, BoardProperties{}, err
}
if code != 200 {
return nil, BoardProperties{}, fmt.Errorf("HTTP error %d: returns %s", code, raw)
}
dec := json.NewDecoder(bytes.NewReader(raw))
dec.UseNumber()
if err := dec.Decode(&result); err != nil {
return nil, BoardProperties{}, errors.Wrap(err, "unmarshal board")
}
return []byte(result.Board), result.Meta, err
}
// GetRawDashboardByUID loads a dashboard and its metadata from Grafana by dashboard uid.
//
// Reflects GET /api/dashboards/uid/:uid API call.
func (r *Client) GetRawDashboardByUID(ctx context.Context, uid string) ([]byte, BoardProperties, error) {
return r.getRawDashboard(ctx, "uid/"+uid)
}
// GetRawDashboardBySlug loads a dashboard and its metadata from Grafana by dashboard slug.
//
// For dashboards from a filesystem set "file/" prefix for slug. By default dashboards from
// a database assumed. Database dashboards may have "db/" prefix or may have not, it will
// be appended automatically.
//
// Reflects GET /api/dashboards/db/:slug API call.
// Deprecated: since Grafana v5 you should use uids. Use GetRawDashboardByUID() for that.
func (r *Client) GetRawDashboardBySlug(ctx context.Context, slug string) ([]byte, BoardProperties, error) {
path := setPrefix(slug)
return r.getRawDashboard(ctx, path)
}
// FoundBoard keeps result of search with metadata of a dashboard.
type FoundBoard struct {
ID uint `json:"id"`
UID string `json:"uid"`
Title string `json:"title"`
URI string `json:"uri"`
URL string `json:"url"`
Slug string `json:"slug"`
Type string `json:"type"`
Tags []string `json:"tags"`
IsStarred bool `json:"isStarred"`
FolderID int `json:"folderId"`
FolderUID string `json:"folderUid"`
FolderTitle string `json:"folderTitle"`
FolderURL string `json:"folderUrl"`
}
// SearchDashboards search dashboards by substring of their title. It allows restrict the result set with
// only starred dashboards and only for tags (logical OR applied to multiple tags).
//
// Reflects GET /api/search API call.
// Deprecated: This interface does not allow for API extension and is out of date.
// Please use Search(SearchType(SearchTypeDashboard))
func (r *Client) SearchDashboards(ctx context.Context, query string, starred bool, tags ...string) ([]FoundBoard, error) {
params := []SearchParam{
SearchType(SearchTypeDashboard),
SearchQuery(query),
SearchStarred(starred),
}
for _, tag := range tags {
params = append(params, SearchTag(tag))
}
return r.Search(ctx, params...)
}
// Search searches folders and dashboards with query params specified.
//
// Reflects GET /api/search API call.
func (r *Client) Search(ctx context.Context, params ...SearchParam) ([]FoundBoard, error) {
var (
raw []byte
boards []FoundBoard
code int
err error
)
u := url.URL{}
q := u.Query()
for _, p := range params {
p(&q)
}
if raw, code, err = r.get(ctx, "api/search", q); err != nil {
return nil, err
}
if code != 200 {
return nil, fmt.Errorf("HTTP error %d: returns %s", code, raw)
}
err = json.Unmarshal(raw, &boards)
return boards, err
}
// SetDashboardParams contains the extra parameteres
// that affects where and how the dashboard will be stored
type SetDashboardParams struct {
FolderID int
Overwrite bool
}
// SetDashboard updates existing dashboard or creates a new one.
// Set dasboard ID to nil to create a new dashboard.
// Set overwrite to true if you want to overwrite existing dashboard with
// newer version or with same dashboard title.
// Grafana only can create or update a dashboard in a database. File dashboards
// may be only loaded with HTTP API but not created or updated.
//
// Reflects POST /api/dashboards/db API call.
func (r *Client) SetDashboard(ctx context.Context, board Board, params SetDashboardParams) (StatusMessage, error) {
var (
isBoardFromDB bool
newBoard struct {
Dashboard Board `json:"dashboard"`
FolderID int `json:"folderId"`
Overwrite bool `json:"overwrite"`
}
raw []byte
resp StatusMessage
code int
err error
)
if board.Slug, isBoardFromDB = cleanPrefix(board.Slug); !isBoardFromDB {
return StatusMessage{}, errors.New("only database dashboard (with 'db/' prefix in a slug) can be set")
}
newBoard.Dashboard = board
newBoard.FolderID = params.FolderID
newBoard.Overwrite = params.Overwrite
if !params.Overwrite {
newBoard.Dashboard.ID = 0
}
if raw, err = json.Marshal(newBoard); err != nil {
return StatusMessage{}, err
}
if raw, code, err = r.post(ctx, "api/dashboards/db", nil, raw); err != nil {
return StatusMessage{}, err
}
if err = json.Unmarshal(raw, &resp); err != nil {
return StatusMessage{}, err
}
if code != 200 {
return resp, fmt.Errorf("HTTP error %d: returns %s", code, *resp.Message)
}
return resp, nil
}
// SetRawDashboard updates existing dashboard or creates a new one.
// Contrary to SetDashboard() it accepts raw JSON instead of Board structure.
// Grafana only can create or update a dashboard in a database. File dashboards
// may be only loaded with HTTP API but not created or updated.
//
// Reflects POST /api/dashboards/db API call.
func (r *Client) SetRawDashboard(ctx context.Context, raw []byte) (StatusMessage, error) {
var (
rawResp []byte
resp StatusMessage
code int
err error
buf bytes.Buffer
plain = make(map[string]interface{})
)
if err = json.Unmarshal(raw, &plain); err != nil {
return StatusMessage{}, err
}
// TODO(axel) fragile place, refactor it
plain["id"] = 0
raw, _ = json.Marshal(plain)
buf.WriteString(`{"dashboard":`)
buf.Write(raw)
buf.WriteString(`, "overwrite": true}`)
if rawResp, code, err = r.post(ctx, "api/dashboards/db", nil, buf.Bytes()); err != nil {
return StatusMessage{}, err
}
if err = json.Unmarshal(rawResp, &resp); err != nil {
return StatusMessage{}, err
}
if code != 200 {
return StatusMessage{}, fmt.Errorf("HTTP error %d: returns %s", code, *resp.Message)
}
return resp, nil
}
// DeleteDashboard deletes dashboard that selected by slug string.
// Grafana only can delete a dashboard in a database. File dashboards
// may be only loaded with HTTP API but not deteled.
//
// Reflects DELETE /api/dashboards/db/:slug API call.
func (r *Client) DeleteDashboard(ctx context.Context, slug string) (StatusMessage, error) {
var (
isBoardFromDB bool
raw []byte
reply StatusMessage
err error
)
if slug, isBoardFromDB = cleanPrefix(slug); !isBoardFromDB {
return StatusMessage{}, errors.New("only database dashboards (with 'db/' prefix in a slug) can be removed")
}
if raw, _, err = r.delete(ctx, fmt.Sprintf("api/dashboards/db/%s", slug)); err != nil {
return StatusMessage{}, err
}
err = json.Unmarshal(raw, &reply)
return reply, err
}
// DeleteDashboard deletes dashboard by UID
// Reflects DELETE /api/dashboards/uid/:uid API call.
func (r *Client) DeleteDashboardByUID(ctx context.Context, uid string) (StatusMessage, error) {
var (
raw []byte
reply StatusMessage
err error
)
if raw, _, err = r.delete(ctx, fmt.Sprintf("api/dashboards/uid/%s", uid)); err != nil {
return StatusMessage{}, err
}
err = json.Unmarshal(raw, &reply)
return reply, err
}
type (
// SearchParam is a type for specifying Search params.
SearchParam func(*url.Values)
// SearchParamType is a type accepted by SearchType func.
SearchParamType string
)
// Search entities to be used with SearchType().
const (
SearchTypeFolder SearchParamType = "dash-folder"
SearchTypeDashboard SearchParamType = "dash-db"
)
// SearchQuery specifies Search search query.
// Empty query is silently ignored.
// Specifying it multiple times is futile, only last one will be sent.
func SearchQuery(query string) SearchParam {
return func(v *url.Values) {
if query != "" {
v.Set("query", query)
}
}
}
// SearchTag specifies Search tag to search for.
// Empty tag is silently ignored.
// Can be specified multiple times, logical OR is applied.
func SearchTag(tag string) SearchParam {
return func(v *url.Values) {
if tag != "" {
v.Add("tag", tag)
}
}
}
// SearchType specifies Search type to search for.
// Specifying it multiple times is futile, only last one will be sent.
func SearchType(searchType SearchParamType) SearchParam {
return func(v *url.Values) {
v.Set("type", string(searchType))
}
}
// SearchDashboardID specifies Search dashboard id's to search for.
// Can be specified multiple times, logical OR is applied.
func SearchDashboardID(dashboardID int) SearchParam {
return func(v *url.Values) {
v.Add("dashboardIds", strconv.Itoa(dashboardID))
}
}
// SearchFolderID specifies Search folder id's to search for.
// Can be specified multiple times, logical OR is applied.
func SearchFolderID(folderID int) SearchParam {
return func(v *url.Values) {
v.Add("folderIds", strconv.Itoa(folderID))
}
}
// SearchStarred specifies if Search should search for starred dashboards only.
// Specifying it multiple times is futile, only last one will be sent.
func SearchStarred(starred bool) SearchParam {
return func(v *url.Values) {
v.Set("starred", strconv.FormatBool(starred))
}
}
// SearchLimit specifies maximum number of results from Search query.
// As of grafana 6.7 it has to be <= 5000. 0 stands for absence of parameter in a query.
// Specifying it multiple times is futile, only last one will be sent.
func SearchLimit(limit uint) SearchParam {
return func(v *url.Values) {
if limit > 0 {
v.Set("limit", strconv.FormatUint(uint64(limit), 10))
}
}
}
// SearchPage specifies Search page number to be queried for.
// Zero page is silently ignored, page numbers start from one.
// Specifying it multiple times is futile, only last one will be sent.
func SearchPage(page uint) SearchParam {
return func(v *url.Values) {
if page > 0 {
v.Set("page", strconv.FormatUint(uint64(page), 10))
}
}
}
// implicitly use dashboards from Grafana DB not from a file system
func setPrefix(slug string) string {
if strings.HasPrefix(slug, "db") {
return slug
}
if strings.HasPrefix(slug, "file/") {
return slug
}
return fmt.Sprintf("db/%s", slug)
}
// assume we use database dashboard by default
func cleanPrefix(slug string) (string, bool) {
if strings.HasPrefix(slug, "db") {
return slug[3:], true
}
if strings.HasPrefix(slug, "file") {
return slug[3:], false
}
return slug, true
}

172
vendor/github.com/grafana-tools/sdk/rest-datasource.go generated vendored Normal file
View File

@@ -0,0 +1,172 @@
package sdk
/*
Copyright 2016 Alexander I.Grafov <grafov@gmail.com>
Copyright 2016-2019 The Grafana SDK authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
ॐ तारे तुत्तारे तुरे स्व
*/
import (
"context"
"encoding/json"
"fmt"
)
// GetAllDatasources gets all datasources.
// Reflects GET /api/datasources API call.
func (r *Client) GetAllDatasources(ctx context.Context) ([]Datasource, error) {
var (
raw []byte
ds []Datasource
code int
err error
)
if raw, code, err = r.get(ctx, "api/datasources", nil); err != nil {
return nil, err
}
if code != 200 {
return nil, fmt.Errorf("HTTP error %d: returns %s", code, raw)
}
err = json.Unmarshal(raw, &ds)
return ds, err
}
// GetDatasource gets an datasource by ID.
// Reflects GET /api/datasources/:datasourceId API call.
func (r *Client) GetDatasource(ctx context.Context, id uint) (Datasource, error) {
var (
raw []byte
ds Datasource
code int
err error
)
if raw, code, err = r.get(ctx, fmt.Sprintf("api/datasources/%d", id), nil); err != nil {
return ds, err
}
if code != 200 {
return ds, fmt.Errorf("HTTP error %d: returns %s", code, raw)
}
err = json.Unmarshal(raw, &ds)
return ds, err
}
// GetDatasourceByName gets an datasource by Name.
// Reflects GET /api/datasources/name/:datasourceName API call.
func (r *Client) GetDatasourceByName(ctx context.Context, name string) (Datasource, error) {
var (
raw []byte
ds Datasource
code int
err error
)
if raw, code, err = r.get(ctx, fmt.Sprintf("api/datasources/name/%s", name), nil); err != nil {
return ds, err
}
if code != 200 {
return ds, fmt.Errorf("HTTP error %d: returns %s", code, raw)
}
err = json.Unmarshal(raw, &ds)
return ds, err
}
// CreateDatasource creates a new datasource.
// Reflects POST /api/datasources API call.
func (r *Client) CreateDatasource(ctx context.Context, ds Datasource) (StatusMessage, error) {
var (
raw []byte
resp StatusMessage
err error
)
if raw, err = json.Marshal(ds); err != nil {
return StatusMessage{}, err
}
if raw, _, err = r.post(ctx, "api/datasources", nil, raw); err != nil {
return StatusMessage{}, err
}
if err = json.Unmarshal(raw, &resp); err != nil {
return StatusMessage{}, err
}
return resp, nil
}
// UpdateDatasource updates a datasource from data passed in argument.
// Reflects PUT /api/datasources/:datasourceId API call.
func (r *Client) UpdateDatasource(ctx context.Context, ds Datasource) (StatusMessage, error) {
var (
raw []byte
resp StatusMessage
err error
)
if raw, err = json.Marshal(ds); err != nil {
return StatusMessage{}, err
}
if raw, _, err = r.put(ctx, fmt.Sprintf("api/datasources/%d", ds.ID), nil, raw); err != nil {
return StatusMessage{}, err
}
if err = json.Unmarshal(raw, &resp); err != nil {
return StatusMessage{}, err
}
return resp, nil
}
// DeleteDatasource deletes an existing datasource by ID.
// Reflects DELETE /api/datasources/:datasourceId API call.
func (r *Client) DeleteDatasource(ctx context.Context, id uint) (StatusMessage, error) {
var (
raw []byte
reply StatusMessage
err error
)
if raw, _, err = r.delete(ctx, fmt.Sprintf("api/datasources/%d", id)); err != nil {
return StatusMessage{}, err
}
err = json.Unmarshal(raw, &reply)
return reply, err
}
// DeleteDatasourceByName deletes an existing datasource by Name.
// Reflects DELETE /api/datasources/name/:datasourceName API call.
func (r *Client) DeleteDatasourceByName(ctx context.Context, name string) (StatusMessage, error) {
var (
raw []byte
reply StatusMessage
err error
)
if raw, _, err = r.delete(ctx, fmt.Sprintf("api/datasources/name/%s", name)); err != nil {
return StatusMessage{}, err
}
err = json.Unmarshal(raw, &reply)
return reply, err
}
// GetDatasourceTypes gets all available plugins for the datasources.
// Reflects GET /api/datasources/plugins API call.
func (r *Client) GetDatasourceTypes(ctx context.Context) (map[string]DatasourceType, error) {
var (
raw []byte
dsTypes = make(map[string]DatasourceType)
code int
err error
)
if raw, code, err = r.get(ctx, "api/datasources/plugins", nil); err != nil {
return nil, err
}
if code != 200 {
return nil, fmt.Errorf("HTTP error %d: returns %s", code, raw)
}
err = json.Unmarshal(raw, &dsTypes)
return dsTypes, err
}

167
vendor/github.com/grafana-tools/sdk/rest-folder.go generated vendored Normal file
View File

@@ -0,0 +1,167 @@
package sdk
/*
Copyright 2016 Alexander I.Grafov <grafov@gmail.com>
Copyright 2016-2019 The Grafana SDK authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
ॐ तारे तुत्तारे तुरे स्व
*/
import (
"context"
"encoding/json"
"fmt"
"net/url"
"strconv"
)
// https://grafana.com/docs/grafana/latest/http_api/folder/
// GetAllFolders gets all folders.
// Reflects GET /api/folders API call.
func (r *Client) GetAllFolders(ctx context.Context, params ...GetFolderParams) ([]Folder, error) {
var (
raw []byte
fs []Folder
code int
err error
requestParams = make(url.Values)
)
for _, p := range params {
p(requestParams)
}
if raw, code, err = r.get(ctx, "api/folders", requestParams); err != nil {
return nil, err
}
if code != 200 {
return nil, fmt.Errorf("HTTP error %d: returns %s", code, raw)
}
err = json.Unmarshal(raw, &fs)
return fs, err
}
// GetFolderByUID gets folder by uid.
// Reflects GET /api/folders/:uid API call.
func (r *Client) GetFolderByUID(ctx context.Context, UID string) (Folder, error) {
var (
raw []byte
f Folder
code int
err error
)
if raw, code, err = r.get(ctx, fmt.Sprintf("api/folders/%s", UID), nil); err != nil {
return f, err
}
if code != 200 {
return f, fmt.Errorf("HTTP error %d: returns %s", code, raw)
}
err = json.Unmarshal(raw, &f)
return f, err
}
// CreateFolder create folders.
// Reflects POST /api/folders API call.
func (r *Client) CreateFolder(ctx context.Context, f Folder) (Folder, error) {
var (
raw []byte
rf Folder
code int
err error
)
rf = Folder{}
if raw, err = json.Marshal(f); err != nil {
return rf, err
}
if raw, code, err = r.post(ctx, "api/folders", nil, raw); err != nil {
return rf, err
}
if code != 200 {
return rf, fmt.Errorf("HTTP error %d: returns %s", code, raw)
}
err = json.Unmarshal(raw, &rf)
return rf, err
}
// UpdateFolderByUID update folder by uid
// Reflects PUT /api/folders/:uid API call.
func (r *Client) UpdateFolderByUID(ctx context.Context, f Folder) (Folder, error) {
var (
raw []byte
rf Folder
code int
err error
)
rf = Folder{}
if raw, err = json.Marshal(f); err != nil {
return rf, err
}
if raw, code, err = r.put(ctx, fmt.Sprintf("api/folders/%s", f.UID), nil, raw); err != nil {
return rf, err
}
if code != 200 {
return f, fmt.Errorf("HTTP error %d: returns %s", code, raw)
}
err = json.Unmarshal(raw, &rf)
return rf, err
}
// DeleteFolderByUID deletes an existing folder by uid.
// Reflects DELETE /api/folders/:uid API call.
func (r *Client) DeleteFolderByUID(ctx context.Context, UID string) (bool, error) {
var (
raw []byte
code int
err error
)
if raw, code, err = r.delete(ctx, fmt.Sprintf("api/folders/%s", UID)); err != nil {
return false, err
}
if code != 200 {
return false, fmt.Errorf("HTTP error %d: returns %s", code, raw)
}
return true, err
}
// GetFolderByID gets folder by id.
// Reflects GET /api/folders/id/:id API call.
func (r *Client) GetFolderByID(ctx context.Context, ID int) (Folder, error) {
var (
raw []byte
f Folder
code int
err error
)
if ID <= 0 {
return f, fmt.Errorf("ID cannot be less than zero")
}
if raw, code, err = r.get(ctx, fmt.Sprintf("api/folders/id/%d", ID), nil); err != nil {
return f, err
}
if code != 200 {
return f, fmt.Errorf("HTTP error %d: returns %s", code, raw)
}
err = json.Unmarshal(raw, &f)
return f, err
}
// GetFolderParams is the type for all options implementing query parameters
type GetFolderParams func(values url.Values)
// Limit sets the max number of folders to return
func Limit(limit uint) GetFolderParams {
return func(v url.Values) {
v.Set("limit", strconv.FormatUint(uint64(limit), 10))
}
}

50
vendor/github.com/grafana-tools/sdk/rest-get_health.go generated vendored Normal file
View File

@@ -0,0 +1,50 @@
package sdk
/*
Copyright 2016 Alexander I.Grafov <grafov@gmail.com>
Copyright 2016-2019 The Grafana SDK authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
ॐ तारे तुत्तारे तुरे स्व
*/
import (
"context"
"encoding/json"
)
// HealthResponse represents the health of grafana server
type HealthResponse struct {
Commit string `json:"commit"`
Database string `json:"database"`
Version string `json:"version"`
}
// GetHealth retrieves the health of the grafana server
// Reflects GET BaseURL API call.
func (r *Client) GetHealth(ctx context.Context) (HealthResponse, error) {
var (
raw []byte
err error
)
if raw, _, err = r.get(ctx, "/api/health", nil); err != nil {
return HealthResponse{}, err
}
health := HealthResponse{}
if err := json.Unmarshal(raw, &health); err != nil {
return HealthResponse{}, err
}
return health, nil
}

436
vendor/github.com/grafana-tools/sdk/rest-org.go generated vendored Normal file
View File

@@ -0,0 +1,436 @@
package sdk
/*
Copyright 2016 Alexander I.Grafov <grafov@gmail.com>
Copyright 2016-2019 The Grafana SDK authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
ॐ तारे तुत्तारे तुरे स्व
*/
import (
"bytes"
"context"
"encoding/json"
"fmt"
"net/http"
)
// CreateOrg creates a new organization.
// It reflects POST /api/orgs API call.
func (r *Client) CreateOrg(ctx context.Context, org Org) (StatusMessage, error) {
var (
raw []byte
resp StatusMessage
err error
)
if raw, err = json.Marshal(org); err != nil {
return StatusMessage{}, err
}
if raw, _, err = r.post(ctx, "api/orgs", nil, raw); err != nil {
return StatusMessage{}, err
}
if err = json.Unmarshal(raw, &resp); err != nil {
return StatusMessage{}, err
}
return resp, nil
}
// GetAllOrgs returns all organizations.
// It reflects GET /api/orgs API call.
func (r *Client) GetAllOrgs(ctx context.Context) ([]Org, error) {
var (
raw []byte
orgs []Org
code int
err error
)
if raw, code, err = r.get(ctx, "api/orgs", nil); err != nil {
return orgs, err
}
if code != http.StatusOK {
return orgs, fmt.Errorf("HTTP error %d: returns %s", code, raw)
}
dec := json.NewDecoder(bytes.NewReader(raw))
dec.UseNumber()
if err := dec.Decode(&orgs); err != nil {
return orgs, fmt.Errorf("unmarshal orgs: %s\n%s", err, raw)
}
return orgs, err
}
// GetActualOrg gets current organization.
// It reflects GET /api/org API call.
func (r *Client) GetActualOrg(ctx context.Context) (Org, error) {
var (
raw []byte
org Org
code int
err error
)
if raw, code, err = r.get(ctx, "api/org", nil); err != nil {
return org, err
}
if code != http.StatusOK {
return org, fmt.Errorf("HTTP error %d: returns %s", code, raw)
}
dec := json.NewDecoder(bytes.NewReader(raw))
dec.UseNumber()
if err := dec.Decode(&org); err != nil {
return org, fmt.Errorf("unmarshal org: %s\n%s", err, raw)
}
return org, err
}
// GetOrgById gets organization by organization Id.
// It reflects GET /api/orgs/:orgId API call.
func (r *Client) GetOrgById(ctx context.Context, oid uint) (Org, error) {
var (
raw []byte
org Org
code int
err error
)
if raw, code, err = r.get(ctx, fmt.Sprintf("api/orgs/%d", oid), nil); err != nil {
return org, err
}
if code != http.StatusOK {
return org, fmt.Errorf("HTTP error %d: returns %s", code, raw)
}
dec := json.NewDecoder(bytes.NewReader(raw))
dec.UseNumber()
if err := dec.Decode(&org); err != nil {
return org, fmt.Errorf("unmarshal org: %s\n%s", err, raw)
}
return org, err
}
// GetOrgByOrgName gets organization by organization name.
// It reflects GET /api/orgs/name/:orgName API call.
func (r *Client) GetOrgByOrgName(ctx context.Context, name string) (Org, error) {
var (
raw []byte
org Org
code int
err error
)
if raw, code, err = r.get(ctx, fmt.Sprintf("api/orgs/name/%s", name), nil); err != nil {
return org, err
}
if code != http.StatusOK {
return org, fmt.Errorf("HTTP error %d: returns %s", code, raw)
}
dec := json.NewDecoder(bytes.NewReader(raw))
dec.UseNumber()
if err := dec.Decode(&org); err != nil {
return org, fmt.Errorf("unmarshal org: %s\n%s", err, raw)
}
return org, err
}
// UpdateActualOrg updates current organization.
// It reflects PUT /api/org API call.
func (r *Client) UpdateActualOrg(ctx context.Context, org Org) (StatusMessage, error) {
var (
raw []byte
resp StatusMessage
err error
)
if raw, err = json.Marshal(org); err != nil {
return StatusMessage{}, err
}
if raw, _, err = r.put(ctx, "api/org", nil, raw); err != nil {
return StatusMessage{}, err
}
if err = json.Unmarshal(raw, &resp); err != nil {
return StatusMessage{}, err
}
return resp, nil
}
// UpdateOrg updates the organization identified by oid.
// It reflects PUT /api/orgs/:orgId API call.
func (r *Client) UpdateOrg(ctx context.Context, org Org, oid uint) (StatusMessage, error) {
var (
raw []byte
resp StatusMessage
err error
)
if raw, err = json.Marshal(org); err != nil {
return StatusMessage{}, err
}
if raw, _, err = r.put(ctx, fmt.Sprintf("api/orgs/%d", oid), nil, raw); err != nil {
return StatusMessage{}, err
}
if err = json.Unmarshal(raw, &resp); err != nil {
return StatusMessage{}, err
}
return resp, nil
}
// DeleteOrg deletes the organization identified by the oid.
// Reflects DELETE /api/orgs/:orgId API call.
func (r *Client) DeleteOrg(ctx context.Context, oid uint) (StatusMessage, error) {
var (
raw []byte
resp StatusMessage
err error
)
if raw, _, err = r.delete(ctx, fmt.Sprintf("api/orgs/%d", oid)); err != nil {
return StatusMessage{}, err
}
if err = json.Unmarshal(raw, &resp); err != nil {
return StatusMessage{}, err
}
return resp, nil
}
// GetActualOrgUsers get all users within the actual organisation.
// Reflects GET /api/org/users API call.
func (r *Client) GetActualOrgUsers(ctx context.Context) ([]OrgUser, error) {
var (
raw []byte
users []OrgUser
code int
err error
)
if raw, code, err = r.get(ctx, "api/org/users", nil); err != nil {
return nil, err
}
if code != http.StatusOK {
return nil, fmt.Errorf("HTTP error %d: returns %s", code, raw)
}
dec := json.NewDecoder(bytes.NewReader(raw))
dec.UseNumber()
if err := dec.Decode(&users); err != nil {
return nil, fmt.Errorf("unmarshal org: %s\n%s", err, raw)
}
return users, err
}
// GetOrgUsers gets the users for the organization specified by oid.
// Reflects GET /api/orgs/:orgId/users API call.
func (r *Client) GetOrgUsers(ctx context.Context, oid uint) ([]OrgUser, error) {
var (
raw []byte
users []OrgUser
code int
err error
)
if raw, code, err = r.get(ctx, fmt.Sprintf("api/orgs/%d/users", oid), nil); err != nil {
return nil, err
}
if code != http.StatusOK {
return nil, fmt.Errorf("HTTP error %d: returns %s", code, raw)
}
dec := json.NewDecoder(bytes.NewReader(raw))
dec.UseNumber()
if err := dec.Decode(&users); err != nil {
return nil, fmt.Errorf("unmarshal org: %s\n%s", err, raw)
}
return users, err
}
// AddActualOrgUser adds a global user to the current organization.
// Reflects POST /api/org/users API call.
func (r *Client) AddActualOrgUser(ctx context.Context, userRole UserRole) (StatusMessage, error) {
var (
raw []byte
resp StatusMessage
err error
)
if raw, err = json.Marshal(userRole); err != nil {
return StatusMessage{}, err
}
if raw, _, err = r.post(ctx, "api/org/users", nil, raw); err != nil {
return StatusMessage{}, err
}
if err = json.Unmarshal(raw, &resp); err != nil {
return StatusMessage{}, err
}
return resp, nil
}
// UpdateActualOrgUser updates the existing user.
// Reflects POST /api/org/users/:userId API call.
func (r *Client) UpdateActualOrgUser(ctx context.Context, user UserRole, uid uint) (StatusMessage, error) {
var (
raw []byte
resp StatusMessage
err error
)
if raw, err = json.Marshal(user); err != nil {
return StatusMessage{}, err
}
if raw, _, err = r.post(ctx, fmt.Sprintf("api/org/users/%d", uid), nil, raw); err != nil {
return StatusMessage{}, err
}
if err = json.Unmarshal(raw, &resp); err != nil {
return StatusMessage{}, err
}
return resp, nil
}
// DeleteActualOrgUser delete user in actual organization.
// Reflects DELETE /api/org/users/:userId API call.
func (r *Client) DeleteActualOrgUser(ctx context.Context, uid uint) (StatusMessage, error) {
var (
raw []byte
reply StatusMessage
err error
)
if raw, _, err = r.delete(ctx, fmt.Sprintf("api/org/users/%d", uid)); err != nil {
return StatusMessage{}, err
}
err = json.Unmarshal(raw, &reply)
return reply, err
}
// AddOrgUser add user to organization with oid.
// Reflects POST /api/orgs/:orgId/users API call.
func (r *Client) AddOrgUser(ctx context.Context, user UserRole, oid uint) (StatusMessage, error) {
var (
raw []byte
reply StatusMessage
err error
)
if raw, err = json.Marshal(user); err != nil {
return StatusMessage{}, err
}
if raw, _, err = r.post(ctx, fmt.Sprintf("api/orgs/%d/users", oid), nil, raw); err != nil {
return StatusMessage{}, err
}
err = json.Unmarshal(raw, &reply)
return reply, err
}
// UpdateOrgUser updates the user specified by uid within the organization specified by oid.
// Reflects PATCH /api/orgs/:orgId/users/:userId API call.
func (r *Client) UpdateOrgUser(ctx context.Context, user UserRole, oid, uid uint) (StatusMessage, error) {
var (
raw []byte
reply StatusMessage
err error
)
if raw, err = json.Marshal(user); err != nil {
return StatusMessage{}, err
}
if raw, _, err = r.patch(ctx, fmt.Sprintf("api/orgs/%d/users/%d", oid, uid), nil, raw); err != nil {
return StatusMessage{}, err
}
err = json.Unmarshal(raw, &reply)
return reply, err
}
// DeleteOrgUser deletes the user specified by uid within the organization specified by oid.
// Reflects DELETE /api/orgs/:orgId/users/:userId API call.
func (r *Client) DeleteOrgUser(ctx context.Context, oid, uid uint) (StatusMessage, error) {
var (
raw []byte
reply StatusMessage
err error
)
if raw, _, err = r.delete(ctx, fmt.Sprintf("api/orgs/%d/users/%d", oid, uid)); err != nil {
return StatusMessage{}, err
}
err = json.Unmarshal(raw, &reply)
return reply, err
}
// UpdateActualOrgPreferences updates preferences of the actual organization.
// Reflects PUT /api/org/preferences API call.
func (r *Client) UpdateActualOrgPreferences(ctx context.Context, prefs Preferences) (StatusMessage, error) {
var (
raw []byte
resp StatusMessage
err error
)
if raw, err = json.Marshal(prefs); err != nil {
return StatusMessage{}, err
}
if raw, _, err = r.put(ctx, "api/org/preferences/", nil, raw); err != nil {
return StatusMessage{}, err
}
if err = json.Unmarshal(raw, &resp); err != nil {
return StatusMessage{}, err
}
return resp, nil
}
// GetActualOrgPreferences gets preferences of the actual organization.
// It reflects GET /api/org/preferences API call.
func (r *Client) GetActualOrgPreferences(ctx context.Context) (Preferences, error) {
var (
raw []byte
pref Preferences
code int
err error
)
if raw, code, err = r.get(ctx, "/api/org/preferences", nil); err != nil {
return pref, err
}
if code != http.StatusOK {
return pref, fmt.Errorf("HTTP error %d: returns %s", code, raw)
}
dec := json.NewDecoder(bytes.NewReader(raw))
dec.UseNumber()
if err := dec.Decode(&pref); err != nil {
return pref, fmt.Errorf("unmarshal prefs: %s\n%s", err, raw)
}
return pref, err
}
// UpdateActualOrgAddress updates current organization's address.
// It reflects PUT /api/org/address API call.
func (r *Client) UpdateActualOrgAddress(ctx context.Context, address Address) (StatusMessage, error) {
var (
raw []byte
resp StatusMessage
err error
)
if raw, err = json.Marshal(address); err != nil {
return StatusMessage{}, err
}
if raw, _, err = r.put(ctx, "api/org/address", nil, raw); err != nil {
return StatusMessage{}, err
}
if err = json.Unmarshal(raw, &resp); err != nil {
return StatusMessage{}, err
}
return resp, nil
}
// UpdateOrgAddress updates the address of the organization identified by oid.
// It reflects PUT /api/orgs/:orgId/address API call.
func (r *Client) UpdateOrgAddress(ctx context.Context, address Address, oid uint) (StatusMessage, error) {
var (
raw []byte
resp StatusMessage
err error
)
if raw, err = json.Marshal(address); err != nil {
return StatusMessage{}, err
}
if raw, _, err = r.put(ctx, fmt.Sprintf("api/orgs/%d/address", oid), nil, raw); err != nil {
return StatusMessage{}, err
}
if err = json.Unmarshal(raw, &resp); err != nil {
return StatusMessage{}, err
}
return resp, nil
}

118
vendor/github.com/grafana-tools/sdk/rest-request.go generated vendored Normal file
View File

@@ -0,0 +1,118 @@
package sdk
/*
Copyright 2016 Alexander I.Grafov <grafov@gmail.com>
Copyright 2016-2019 The Grafana SDK authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
ॐ तारे तुत्तारे तुरे स्व
*/
import (
"bytes"
"context"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"path"
"strings"
)
// DefaultHTTPClient initialized Grafana with appropriate conditions.
// It allows you globally redefine HTTP client.
var DefaultHTTPClient = http.DefaultClient
// Client uses Grafana REST API for interacting with Grafana server.
type Client struct {
baseURL string
key string
basicAuth bool
client *http.Client
}
// StatusMessage reflects status message as it returned by Grafana REST API.
type StatusMessage struct {
ID *uint `json:"id"`
OrgID *uint `json:"orgId"`
Message *string `json:"message"`
Slug *string `json:"slug"`
Version *int `json:"version"`
Status *string `json:"status"`
UID *string `json:"uid"`
URL *string `json:"url"`
}
// NewClient initializes client for interacting with an instance of Grafana server;
// apiKeyOrBasicAuth accepts either 'username:password' basic authentication credentials,
// or a Grafana API key
func NewClient(apiURL, apiKeyOrBasicAuth string, client *http.Client) *Client {
key := ""
basicAuth := strings.Contains(apiKeyOrBasicAuth, ":")
baseURL, _ := url.Parse(apiURL)
if !basicAuth {
key = fmt.Sprintf("Bearer %s", apiKeyOrBasicAuth)
} else {
parts := strings.Split(apiKeyOrBasicAuth, ":")
baseURL.User = url.UserPassword(parts[0], parts[1])
}
return &Client{baseURL: baseURL.String(), basicAuth: basicAuth, key: key, client: client}
}
func (r *Client) get(ctx context.Context, query string, params url.Values) ([]byte, int, error) {
return r.doRequest(ctx, "GET", query, params, nil)
}
func (r *Client) patch(ctx context.Context, query string, params url.Values, body []byte) ([]byte, int, error) {
return r.doRequest(ctx, "PATCH", query, params, bytes.NewBuffer(body))
}
func (r *Client) put(ctx context.Context, query string, params url.Values, body []byte) ([]byte, int, error) {
return r.doRequest(ctx, "PUT", query, params, bytes.NewBuffer(body))
}
func (r *Client) post(ctx context.Context, query string, params url.Values, body []byte) ([]byte, int, error) {
return r.doRequest(ctx, "POST", query, params, bytes.NewBuffer(body))
}
func (r *Client) delete(ctx context.Context, query string) ([]byte, int, error) {
return r.doRequest(ctx, "DELETE", query, nil, nil)
}
func (r *Client) doRequest(ctx context.Context, method, query string, params url.Values, buf io.Reader) ([]byte, int, error) {
u, _ := url.Parse(r.baseURL)
u.Path = path.Join(u.Path, query)
if params != nil {
u.RawQuery = params.Encode()
}
req, err := http.NewRequest(method, u.String(), buf)
if err != nil {
return nil, 0, err
}
req = req.WithContext(ctx)
if !r.basicAuth {
req.Header.Set("Authorization", r.key)
}
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
req.Header.Set("User-Agent", "autograf")
resp, err := r.client.Do(req)
if err != nil {
return nil, 0, err
}
data, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
return data, resp.StatusCode, err
}

34
vendor/github.com/grafana-tools/sdk/rest-snapshot.go generated vendored Normal file
View File

@@ -0,0 +1,34 @@
package sdk
import (
"context"
"encoding/json"
"fmt"
"github.com/pkg/errors"
)
// https://grafana.com/docs/grafana/latest/http_api/snapshot/
// CreateAnnotation creates a new snapshot.
func (r *Client) CreateSnapshot(ctx context.Context, a CreateSnapshotRequest) (StatusMessage, error) {
var (
raw []byte
resp StatusMessage
err error
code int
)
if raw, err = json.Marshal(a); err != nil {
return StatusMessage{}, errors.Wrap(err, "marshal request")
}
if raw, code, err = r.post(ctx, "api/snapshots", nil, raw); err != nil {
return StatusMessage{}, errors.Wrap(err, "create snapshot")
}
if code/100 != 2 {
return StatusMessage{}, fmt.Errorf("bad response: %d", code)
}
if err = json.Unmarshal(raw, &resp); err != nil {
return StatusMessage{}, errors.Wrap(err, "unmarshal response message")
}
return resp, nil
}

164
vendor/github.com/grafana-tools/sdk/rest-user.go generated vendored Normal file
View File

@@ -0,0 +1,164 @@
package sdk
/*
Copyright 2016 Alexander I.Grafov <grafov@gmail.com>
Copyright 2016-2019 The Grafana SDK authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
ॐ तारे तुत्तारे तुरे स्व
*/
import (
"bytes"
"context"
"encoding/json"
"fmt"
"net/url"
)
// GetActualUser gets an actual user.
// Reflects GET /api/user API call.
func (r *Client) GetActualUser(ctx context.Context) (User, error) {
var (
raw []byte
user User
code int
err error
)
if raw, code, err = r.get(ctx, "api/user", nil); err != nil {
return user, err
}
if code != 200 {
return user, fmt.Errorf("HTTP error %d: returns %s", code, raw)
}
dec := json.NewDecoder(bytes.NewReader(raw))
dec.UseNumber()
if err := dec.Decode(&user); err != nil {
return user, fmt.Errorf("unmarshal user: %s\n%s", err, raw)
}
return user, err
}
// GetUser gets an user by ID.
// Reflects GET /api/users/:id API call.
func (r *Client) GetUser(ctx context.Context, id uint) (User, error) {
var (
raw []byte
user User
code int
err error
)
if raw, code, err = r.get(ctx, fmt.Sprintf("api/users/%d", id), nil); err != nil {
return user, err
}
if code != 200 {
return user, fmt.Errorf("HTTP error %d: returns %s", code, raw)
}
dec := json.NewDecoder(bytes.NewReader(raw))
dec.UseNumber()
if err := dec.Decode(&user); err != nil {
return user, fmt.Errorf("unmarshal user: %s\n%s", err, raw)
}
return user, err
}
// GetAllUsers gets all users.
// Reflects GET /api/users API call.
func (r *Client) GetAllUsers(ctx context.Context) ([]User, error) {
var (
raw []byte
users []User
code int
err error
)
params := url.Values{}
params.Set("perpage", "99999")
if raw, code, err = r.get(ctx, "api/users", params); err != nil {
return users, err
}
if code != 200 {
return users, fmt.Errorf("HTTP error %d: returns %s", code, raw)
}
dec := json.NewDecoder(bytes.NewReader(raw))
dec.UseNumber()
if err := dec.Decode(&users); err != nil {
return users, fmt.Errorf("unmarshal users: %s\n%s", err, raw)
}
return users, err
}
// SearchUsersWithPaging search users with paging.
// query optional. query value is contained in one of the name, login or email fields. Query values with spaces need to be url encoded e.g. query=Jane%20Doe
// perpage optional. default 1000
// page optional. default 1
// http://docs.grafana.org/http_api/user/#search-users
// http://docs.grafana.org/http_api/user/#search-users-with-paging
//
// Reflects GET /api/users/search API call.
func (r *Client) SearchUsersWithPaging(ctx context.Context, query *string, perpage, page *int) (PageUsers, error) {
var (
raw []byte
pageUsers PageUsers
code int
err error
)
var params url.Values = nil
if perpage != nil && page != nil {
if params == nil {
params = url.Values{}
}
params["perpage"] = []string{fmt.Sprint(*perpage)}
params["page"] = []string{fmt.Sprint(*page)}
}
if query != nil {
if params == nil {
params = url.Values{}
}
params["query"] = []string{*query}
}
if raw, code, err = r.get(ctx, "api/users/search", params); err != nil {
return pageUsers, err
}
if code != 200 {
return pageUsers, fmt.Errorf("HTTP error %d: returns %s", code, raw)
}
dec := json.NewDecoder(bytes.NewReader(raw))
dec.UseNumber()
if err := dec.Decode(&pageUsers); err != nil {
return pageUsers, fmt.Errorf("unmarshal users: %s\n%s", err, raw)
}
return pageUsers, err
}
// SwitchActualUserContext switches current user context to the given organization.
// Reflects POST /api/user/using/:organizationId API call.
func (r *Client) SwitchActualUserContext(ctx context.Context, oid uint) (StatusMessage, error) {
var (
raw []byte
resp StatusMessage
err error
)
if raw, _, err = r.post(ctx, fmt.Sprintf("/api/user/using/%d", oid), nil, raw); err != nil {
return StatusMessage{}, err
}
if err = json.Unmarshal(raw, &resp); err != nil {
return StatusMessage{}, err
}
return resp, nil
}

95
vendor/github.com/grafana-tools/sdk/row.go generated vendored Normal file
View File

@@ -0,0 +1,95 @@
package sdk
/*
Copyright 2016 Alexander I.Grafov <grafov@gmail.com>
Copyright 2016-2019 The Grafana SDK authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
ॐ तारे तुत्तारे तुरे स्व
*/
// Row represents single row of Grafana dashboard.
type Row struct {
Title string `json:"title"`
ShowTitle bool `json:"showTitle"`
Collapse bool `json:"collapse"`
Editable bool `json:"editable"`
Height Height `json:"height"`
Panels []Panel `json:"panels"`
Repeat *string `json:"repeat"`
}
var lastPanelID uint
func (r *Row) Add(panel *Panel) {
lastPanelID++
panel.ID = lastPanelID
r.Panels = append(r.Panels, *panel)
}
func (r *Row) AddDashlist(data *DashlistPanel) {
lastPanelID++
panel := NewDashlist("")
panel.ID = lastPanelID
panel.DashlistPanel = data
r.Panels = append(r.Panels, *panel)
}
func (r *Row) AddGraph(data *GraphPanel) {
lastPanelID++
panel := NewGraph("")
panel.ID = lastPanelID
panel.GraphPanel = data
r.Panels = append(r.Panels, *panel)
}
func (r *Row) AddTable(data *TablePanel) {
lastPanelID++
panel := NewTable("")
panel.ID = lastPanelID
panel.TablePanel = data
r.Panels = append(r.Panels, *panel)
}
func (r *Row) AddText(data *TextPanel) {
lastPanelID++
panel := NewText("")
panel.ID = lastPanelID
panel.TextPanel = data
r.Panels = append(r.Panels, *panel)
}
func (r *Row) AddStat(data *StatPanel) {
lastPanelID++
panel := NewStat("")
panel.ID = lastPanelID
panel.StatPanel = data
r.Panels = append(r.Panels, *panel)
}
func (r *Row) AddSinglestat(data *SinglestatPanel) {
lastPanelID++
panel := NewSinglestat("")
panel.ID = lastPanelID
panel.SinglestatPanel = data
r.Panels = append(r.Panels, *panel)
}
func (r *Row) AddCustom(data *CustomPanel) {
lastPanelID++
panel := NewCustom("")
panel.ID = lastPanelID
panel.CustomPanel = data
r.Panels = append(r.Panels, *panel)
}

7
vendor/github.com/grafana-tools/sdk/snapshot.go generated vendored Normal file
View File

@@ -0,0 +1,7 @@
package sdk
// CreateSnapshotRequest is representation of a snapshot request.
type CreateSnapshotRequest struct {
Expires uint `json:"expires"`
Dashboard Board `json:"dashboard"`
}

51
vendor/github.com/grafana-tools/sdk/user.go generated vendored Normal file
View File

@@ -0,0 +1,51 @@
package sdk
/*
Copyright 2016 Alexander I.Grafov <grafov@gmail.com>
Copyright 2016-2019 The Grafana SDK authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
ॐ तारे तुत्तारे तुरे स्व
*/
type User struct {
ID uint `json:"id"`
Login string `json:"login"`
Name string `json:"name"`
Email string `json:"email"`
OrgID uint `json:"orgId"`
Theme string `json:"theme"`
Password string `json:"password"`
IsDisabled bool `json:"isDisabled"`
AuthLabels []string `json:"authLabels"`
IsGrafanaAdmin bool `json:"isGrafanaAdmin"`
IsExternal bool `json:"isExternal"`
IsAdmin bool `json:"isAdmin"` //Different value used for Search Endpoint
}
type UserRole struct {
LoginOrEmail string `json:"loginOrEmail"`
Role string `json:"role"`
}
type UserPermissions struct {
IsGrafanaAdmin bool `json:"isGrafanaAdmin"`
}
type PageUsers struct {
TotalCount int `json:"totalCount"`
Users []User `json:"users"`
Page int `json:"page"`
PerPage int `json:"perPage"`
}

23
vendor/github.com/rainycape/unidecode/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,23 @@
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
*.test

203
vendor/github.com/rainycape/unidecode/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,203 @@
Copyright 2014 Rainy Cape S.L. <hello@rainycape.com>
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

6
vendor/github.com/rainycape/unidecode/README.md generated vendored Normal file
View File

@@ -0,0 +1,6 @@
unidecode
=========
Unicode transliterator in Golang - Replaces non-ASCII characters with their ASCII approximations.
[![GoDoc](https://godoc.org/github.com/rainycape/unidecode?status.svg)](https://godoc.org/github.com/rainycape/unidecode)

41
vendor/github.com/rainycape/unidecode/decode.go generated vendored Normal file
View File

@@ -0,0 +1,41 @@
package unidecode
import (
"compress/zlib"
"encoding/binary"
"io"
"strings"
)
var (
transliterations [65536][]rune
transCount = rune(len(transliterations))
getUint16 = binary.LittleEndian.Uint16
)
func decodeTransliterations() {
r, err := zlib.NewReader(strings.NewReader(tableData))
if err != nil {
panic(err)
}
defer r.Close()
tmp1 := make([]byte, 2)
tmp2 := tmp1[:1]
for {
if _, err := io.ReadAtLeast(r, tmp1, 2); err != nil {
if err == io.EOF {
break
}
panic(err)
}
chr := getUint16(tmp1)
if _, err := io.ReadAtLeast(r, tmp2, 1); err != nil {
panic(err)
}
b := make([]byte, int(tmp2[0]))
if _, err := io.ReadFull(r, b); err != nil {
panic(err)
}
transliterations[int(chr)] = []rune(string(b))
}
}

71
vendor/github.com/rainycape/unidecode/make_table.go generated vendored Normal file
View File

@@ -0,0 +1,71 @@
// +build none
package main
import (
"bytes"
"compress/zlib"
"encoding/binary"
"fmt"
"go/format"
"io/ioutil"
"strconv"
"strings"
)
func main() {
data, err := ioutil.ReadFile("table.txt")
if err != nil {
panic(err)
}
var buf bytes.Buffer
for _, line := range strings.Split(string(data), "\n") {
if strings.HasPrefix(line, "/*") || line == "" {
continue
}
sep := strings.IndexByte(line, ':')
if sep == -1 {
panic(line)
}
val, err := strconv.ParseInt(line[:sep], 0, 32)
if err != nil {
panic(err)
}
s, err := strconv.Unquote(line[sep+2:])
if err != nil {
panic(err)
}
if s == "" {
continue
}
if err := binary.Write(&buf, binary.LittleEndian, uint16(val)); err != nil {
panic(err)
}
if err := binary.Write(&buf, binary.LittleEndian, uint8(len(s))); err != nil {
panic(err)
}
buf.WriteString(s)
}
var cbuf bytes.Buffer
w, err := zlib.NewWriterLevel(&cbuf, zlib.BestCompression)
if err != nil {
panic(err)
}
if _, err := w.Write(buf.Bytes()); err != nil {
panic(err)
}
if err := w.Close(); err != nil {
panic(err)
}
buf.Reset()
buf.WriteString("package unidecode\n")
buf.WriteString("// AUTOGENERATED - DO NOT EDIT!\n\n")
fmt.Fprintf(&buf, "var tableData = %q;\n", cbuf.String())
dst, err := format.Source(buf.Bytes())
if err != nil {
panic(err)
}
if err := ioutil.WriteFile("table.go", dst, 0644); err != nil {
panic(err)
}
}

5
vendor/github.com/rainycape/unidecode/table.go generated vendored Normal file

File diff suppressed because one or more lines are too long

46731
vendor/github.com/rainycape/unidecode/table.txt generated vendored Normal file

File diff suppressed because it is too large Load Diff

58
vendor/github.com/rainycape/unidecode/unidecode.go generated vendored Normal file
View File

@@ -0,0 +1,58 @@
// Package unidecode implements a unicode transliterator
// which replaces non-ASCII characters with their ASCII
// approximations.
package unidecode
//go:generate go run make_table.go
import (
"sync"
"unicode"
)
const pooledCapacity = 64
var (
slicePool sync.Pool
decodingOnce sync.Once
)
// Unidecode implements a unicode transliterator, which
// replaces non-ASCII characters with their ASCII
// counterparts.
// Given an unicode encoded string, returns
// another string with non-ASCII characters replaced
// with their closest ASCII counterparts.
// e.g. Unicode("áéíóú") => "aeiou"
func Unidecode(s string) string {
decodingOnce.Do(decodeTransliterations)
l := len(s)
var r []rune
if l > pooledCapacity {
r = make([]rune, 0, len(s))
} else {
if x := slicePool.Get(); x != nil {
r = x.([]rune)[:0]
} else {
r = make([]rune, 0, pooledCapacity)
}
}
for _, c := range s {
if c <= unicode.MaxASCII {
r = append(r, c)
continue
}
if c > unicode.MaxRune || c > transCount {
/* Ignore reserved chars */
continue
}
if d := transliterations[c]; d != nil {
r = append(r, d...)
}
}
res := string(r)
if l <= pooledCapacity {
slicePool.Put(r)
}
return res
}