grafana-client 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/workflows/main.yml +22 -0
- data/.github/workflows/release.yml +44 -0
- data/.gitignore +59 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +6 -0
- data/LICENSE +21 -0
- data/README.md +67 -0
- data/Rakefile +12 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/grafana-client.gemspec +39 -0
- data/lib/grafana/client.rb +24 -0
- data/lib/grafana/client/base_client.rb +43 -0
- data/lib/grafana/client/version.rb +5 -0
- data/lib/grafana/modules.rb +9 -0
- data/lib/grafana/modules/alert.rb +50 -0
- data/lib/grafana/modules/alert_notification_channel.rb +42 -0
- data/lib/grafana/modules/dashboard.rb +96 -0
- data/lib/grafana/modules/data_source.rb +31 -0
- data/lib/grafana/modules/folder.rb +41 -0
- metadata +156 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: feef62d5dcc9495d04c3a012537f79488416e08a64d4ade27c43bc608adc055d
|
4
|
+
data.tar.gz: 2d01176ce013313d5cf9b618f85000a66d84a9c4a4c766c563c1ab9d038a3f48
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: '04993d0c515a02e0c91e24196d5e0c7a7616056715095290418436b29da3eb3824bb14c40b00b08cfadf259d85418b12d9085dff87b57d452e015710a4a550dd'
|
7
|
+
data.tar.gz: e070532c25999ae481447b5d39a0db69ff44832046b119c641582d3d3f112e63f621838841f67d8a63645c7d6ffc9a6c90dd2c49306d0e79ff13054e665e1680
|
@@ -0,0 +1,22 @@
|
|
1
|
+
name: CI
|
2
|
+
on: [push, pull_request]
|
3
|
+
jobs:
|
4
|
+
test:
|
5
|
+
name: Test
|
6
|
+
strategy:
|
7
|
+
fail-fast: false
|
8
|
+
matrix:
|
9
|
+
os: [ubuntu-latest, macos-latest]
|
10
|
+
# due to https://github.com/actions/runner/issues/849, we need quotes for '3.0'
|
11
|
+
ruby: [2.5, 2.6, 2.7, '3.0', head, jruby, jruby-head, truffleruby, truffleruby-head]
|
12
|
+
runs-on: ${{ matrix.os }}
|
13
|
+
steps:
|
14
|
+
- name: "Checkout"
|
15
|
+
uses: actions/checkout@v2
|
16
|
+
- name: "Setup Ruby"
|
17
|
+
uses: ruby/setup-ruby@v1
|
18
|
+
with:
|
19
|
+
ruby-version: ${{ matrix.ruby }}
|
20
|
+
bundler-cache: true
|
21
|
+
- name: "Run RSpec"
|
22
|
+
run: bundle exec rspec
|
@@ -0,0 +1,44 @@
|
|
1
|
+
name: Release
|
2
|
+
on:
|
3
|
+
workflow_run:
|
4
|
+
workflows: ["CI"]
|
5
|
+
branches:
|
6
|
+
- 'v*'
|
7
|
+
types:
|
8
|
+
- completed
|
9
|
+
|
10
|
+
jobs:
|
11
|
+
release:
|
12
|
+
runs-on: ubuntu-latest
|
13
|
+
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
14
|
+
steps:
|
15
|
+
- name: "Checkout"
|
16
|
+
uses: actions/checkout@v2
|
17
|
+
- name: "Setup Ruby"
|
18
|
+
uses: ruby/setup-ruby@v1
|
19
|
+
with:
|
20
|
+
ruby-version: 3.0
|
21
|
+
bundler-cache: true
|
22
|
+
|
23
|
+
- name: Publish to GPR
|
24
|
+
run: |
|
25
|
+
mkdir -p $HOME/.gem
|
26
|
+
touch $HOME/.gem/credentials
|
27
|
+
chmod 0600 $HOME/.gem/credentials
|
28
|
+
printf -- "---\n:github: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
29
|
+
gem build *.gemspec
|
30
|
+
gem push --KEY github --host https://rubygems.pkg.github.com/${OWNER} *.gem
|
31
|
+
env:
|
32
|
+
GEM_HOST_API_KEY: "Bearer ${{secrets.GITHUB_TOKEN}}"
|
33
|
+
OWNER: ${{ github.repository_owner }}
|
34
|
+
|
35
|
+
- name: Publish to RubyGems
|
36
|
+
run: |
|
37
|
+
mkdir -p $HOME/.gem
|
38
|
+
touch $HOME/.gem/credentials
|
39
|
+
chmod 0600 $HOME/.gem/credentials
|
40
|
+
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
41
|
+
gem build *.gemspec
|
42
|
+
gem push *.gem
|
43
|
+
env:
|
44
|
+
GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
|
data/.gitignore
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
/.config
|
4
|
+
/coverage/
|
5
|
+
/InstalledFiles
|
6
|
+
/pkg/
|
7
|
+
/spec/reports/
|
8
|
+
/spec/examples.txt
|
9
|
+
/test/tmp/
|
10
|
+
/test/version_tmp/
|
11
|
+
/tmp/
|
12
|
+
|
13
|
+
# Used by dotenv library to load environment variables.
|
14
|
+
# .env
|
15
|
+
|
16
|
+
# Ignore Byebug command history file.
|
17
|
+
.byebug_history
|
18
|
+
|
19
|
+
# Ignore RSpec history file
|
20
|
+
.rspec_status
|
21
|
+
|
22
|
+
## Specific to RubyMotion:
|
23
|
+
.dat*
|
24
|
+
.repl_history
|
25
|
+
build/
|
26
|
+
*.bridgesupport
|
27
|
+
build-iPhoneOS/
|
28
|
+
build-iPhoneSimulator/
|
29
|
+
|
30
|
+
## Specific to RubyMotion (use of CocoaPods):
|
31
|
+
#
|
32
|
+
# We recommend against adding the Pods directory to your .gitignore. However
|
33
|
+
# you should judge for yourself, the pros and cons are mentioned at:
|
34
|
+
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
|
35
|
+
#
|
36
|
+
# vendor/Pods/
|
37
|
+
|
38
|
+
## Documentation cache and generated files:
|
39
|
+
/.yardoc/
|
40
|
+
/_yardoc/
|
41
|
+
/doc/
|
42
|
+
/rdoc/
|
43
|
+
|
44
|
+
## Environment normalization:
|
45
|
+
/.bundle/
|
46
|
+
/vendor/bundle
|
47
|
+
/lib/bundler/man/
|
48
|
+
|
49
|
+
# for a library or gem, you might want to ignore these files since the code is
|
50
|
+
# intended to run in multiple environments; otherwise, check them in:
|
51
|
+
Gemfile.lock
|
52
|
+
.ruby-version
|
53
|
+
.ruby-gemset
|
54
|
+
|
55
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
56
|
+
.rvmrc
|
57
|
+
|
58
|
+
# Used by RuboCop. Remote config files pulled in from inherit_from directive.
|
59
|
+
.rubocop-https?--*
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2021 Matt Tanous
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# Grafana::Client
|
2
|
+
|
3
|
+
Provide a Faraday-backed API client to interface with Grafana APIs to view and manage configurations of dashboards, data sources, and other means of collecting, querying and viewing data in Grafana.
|
4
|
+
## Installation
|
5
|
+
|
6
|
+
Add this line to your application's Gemfile:
|
7
|
+
|
8
|
+
```ruby
|
9
|
+
gem 'grafana-client'
|
10
|
+
```
|
11
|
+
|
12
|
+
And then execute:
|
13
|
+
|
14
|
+
$ bundle install
|
15
|
+
|
16
|
+
Or install it yourself as:
|
17
|
+
|
18
|
+
$ gem install grafana-client
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
|
22
|
+
`Grafana::Client` is configured initially by providing an API key and URL for the Grafana instance to connect with:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
Grafana::Client.config do |c|
|
26
|
+
c.api_key = YOUR_GRAFANA_API_KEY
|
27
|
+
c.grafana_url = YOUR_GRAFANA_INSTANCE_URL
|
28
|
+
end
|
29
|
+
```
|
30
|
+
|
31
|
+
This can then be used in a direct client instance, as for instance:
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
client = Grafana::Client.new
|
35
|
+
client.dashboard(uid: DASHBOARD_UID)
|
36
|
+
```
|
37
|
+
|
38
|
+
An instance can also be created with specified credentials:
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
client = Grafana::Client.new(grafana_url: url, api_key: API_KEY)
|
42
|
+
```
|
43
|
+
|
44
|
+
Clients can also be created with more limited scope, as with:
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
dashboard_client = Grafana::Dashboards.new
|
48
|
+
alert_client = Grafana::Alerts.new
|
49
|
+
```
|
50
|
+
|
51
|
+
This can be used to provide more clear understanding of what resources are intended to be viewed or managed with the specified client.
|
52
|
+
|
53
|
+
## Development
|
54
|
+
|
55
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
56
|
+
|
57
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
58
|
+
|
59
|
+
## Contributing
|
60
|
+
|
61
|
+
NOTE: THIS API CLIENT IS A WORK IN PROGRESS, WHICH CURRENTLY EXISTS AS A MINIMUM VIABLE PRODUCT FOR RELATED WORK PROJECTS. It may not currently meet your needs, as not all Grafana APIs are covered with the current implementation.
|
62
|
+
|
63
|
+
However, bug reports and pull requests are welcome on GitHub at https://github.com/CodingAnarchy/grafana-client, and a best effort will be made to respond in a timely manner.
|
64
|
+
|
65
|
+
## License
|
66
|
+
|
67
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require "grafana/client"
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require "irb"
|
15
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/grafana/client/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "grafana-client"
|
7
|
+
spec.version = Grafana::CLIENT_VERSION
|
8
|
+
spec.authors = ["Matt Tanous"]
|
9
|
+
spec.email = ["mtanous22@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = "Client library for connections to Grafana API"
|
12
|
+
spec.homepage = "https://github.com/CodingAnarchy/grafana-client"
|
13
|
+
spec.license = "MIT"
|
14
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
|
15
|
+
|
16
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
17
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
18
|
+
spec.metadata["changelog_uri"] = "https://github.com/CodingAnarchy/grafana-client/blob/main/CHANGELOG.md"
|
19
|
+
|
20
|
+
# Specify which files should be added to the gem when it is released.
|
21
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
22
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
23
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
|
24
|
+
end
|
25
|
+
spec.bindir = 'exe'
|
26
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
27
|
+
spec.require_paths = ['lib']
|
28
|
+
|
29
|
+
spec.add_dependency 'faraday', '~> 1.1'
|
30
|
+
spec.add_dependency 'faraday_middleware', '~> 1.0'
|
31
|
+
|
32
|
+
spec.add_development_dependency 'activesupport', '>= 5.2', '< 6.2'
|
33
|
+
spec.add_development_dependency 'rspec', '~> 3.10'
|
34
|
+
spec.add_development_dependency 'webmock', '~> 3.13'
|
35
|
+
|
36
|
+
unless RUBY_PLATFORM == 'java'
|
37
|
+
spec.add_development_dependency 'pry-byebug', '~> 3.9'
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'client/base_client'
|
4
|
+
Dir[File.join(__dir__, 'modules', '*.rb')].sort.each { |file| require file }
|
5
|
+
|
6
|
+
module Grafana
|
7
|
+
class Client < Grafana::BaseClient
|
8
|
+
VERSION = Grafana::CLIENT_VERSION
|
9
|
+
|
10
|
+
class << self
|
11
|
+
attr_accessor :api_key, :grafana_url
|
12
|
+
|
13
|
+
def config
|
14
|
+
yield self
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Include all modules into main Client class
|
19
|
+
client_modules = Grafana::Modules.constants.select { |c| Grafana::Modules.const_get(c).is_a?(Module) }
|
20
|
+
client_modules.each do |module_const|
|
21
|
+
include Grafana::Modules.const_get(module_const)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'faraday'
|
4
|
+
require 'faraday_middleware'
|
5
|
+
|
6
|
+
require_relative 'version'
|
7
|
+
|
8
|
+
module Grafana
|
9
|
+
class BaseClient
|
10
|
+
def initialize(grafana_url: Grafana::Client.grafana_url, api_key: Grafana::Client.api_key)
|
11
|
+
retry_options = {
|
12
|
+
max: 2,
|
13
|
+
retry_statuses: [429]
|
14
|
+
}
|
15
|
+
|
16
|
+
@conn = Faraday.new(url: grafana_url) do |f|
|
17
|
+
f.request :authorization, :Bearer, api_key
|
18
|
+
f.request :json # encode req bodies as JSON
|
19
|
+
f.request :retry, retry_options # retry transient failures
|
20
|
+
f.response :follow_redirects # follow redirects
|
21
|
+
f.response :json, content_type: /\bjson$/ # decode response bodies as JSON
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def get(url, **options)
|
26
|
+
# TODO: error handling
|
27
|
+
JSON.parse(@conn.get(url, **options).body)
|
28
|
+
end
|
29
|
+
|
30
|
+
def post(url, body, **options)
|
31
|
+
response = @conn.post(url, body, **options)
|
32
|
+
|
33
|
+
# TODO: handle errors in the response
|
34
|
+
JSON.parse(response.body)
|
35
|
+
end
|
36
|
+
|
37
|
+
def delete(url, **options)
|
38
|
+
response = @conn.delete(url, **options)
|
39
|
+
|
40
|
+
JSON.parse(response.body)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
module Grafana
|
4
|
+
module Modules
|
5
|
+
module Alert
|
6
|
+
def alerts(**options)
|
7
|
+
options = options.slice(:folder_id, :dashboard_id, :panel_id, :query, :state,
|
8
|
+
:limit, :dashboard_query, :dasboard_tag).compact
|
9
|
+
|
10
|
+
valid_alert_states = ['ALL', 'no_data', 'paused', 'alerting', 'ok', 'pending']
|
11
|
+
|
12
|
+
options[:panelId] = options.delete(:panel_id) if options[:panel_id].present?
|
13
|
+
options[:folderId] = Array.wrap(options.delete(:folder_id)) if options[:folder_id].present?
|
14
|
+
options[:dashboardId] = Array.wrap(options.delete(:dashboard_id)) if options[:dashboard_id].present?
|
15
|
+
options[:dasboardQuery] = options.delete(:dahsboard_query) if options[:dashboard_query].present?
|
16
|
+
options[:dashboardTag] = Array.wrap(options.delete(:dashboard_tag)) if options[:dashboard_tag].present?
|
17
|
+
options[:state] = Array.wrap(options[:state] || 'ALL') & valid_alert_states
|
18
|
+
|
19
|
+
options.delete(:limit) unless options[:limit].is_a?(Integer)
|
20
|
+
|
21
|
+
alert_url = '/api/alerts'
|
22
|
+
alert_url += "?#{URI.encode_www_form(options)}" if options.any?
|
23
|
+
get(alert_url)
|
24
|
+
end
|
25
|
+
|
26
|
+
def alert(id:)
|
27
|
+
get("/api/alerts/#{id}")
|
28
|
+
end
|
29
|
+
|
30
|
+
# CRUD actions are done in alerts via modifying the associated dashboard
|
31
|
+
# TODO: create CRUD actions in client that will do the appropriate lookups and changes more directly
|
32
|
+
|
33
|
+
def pause_alert(id:, paused: true)
|
34
|
+
post("/api/alerts/#{id}/pause", { paused: paused })
|
35
|
+
end
|
36
|
+
|
37
|
+
# Helper method to unpause an alert as
|
38
|
+
# passing paused: false is not as intuitive
|
39
|
+
def unpause_alert(id:)
|
40
|
+
pause_alert(id: id, paused: false)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
module Grafana
|
47
|
+
class Alerts < BaseClient
|
48
|
+
include Grafana::Modules::Alert
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Grafana
|
2
|
+
module Modules
|
3
|
+
module AlertNotificationChannel
|
4
|
+
def notification_channels
|
5
|
+
get('/api/alert-notifications')
|
6
|
+
end
|
7
|
+
|
8
|
+
def notification_channel(uid:)
|
9
|
+
get("/api/alert-notifications/uid/#{uid}")
|
10
|
+
end
|
11
|
+
|
12
|
+
def create_notification_channel(channel)
|
13
|
+
# TODO: verify channel is a hash and has the expected values
|
14
|
+
|
15
|
+
post('/api/alert-notifications', channel)
|
16
|
+
end
|
17
|
+
|
18
|
+
def update_notification_channel(channel, uid:)
|
19
|
+
# TODO: verify channel is a hash and has the expected values
|
20
|
+
|
21
|
+
post("/api/alert-notifications/uid/#{uid}", channel)
|
22
|
+
end
|
23
|
+
|
24
|
+
def delete_notification_channel(uid:)
|
25
|
+
@conn.delete("/api/alert-notifications/uid/#{uid}")
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_notification_channel(type:, settings:)
|
29
|
+
# TODO: verify settings is a hash
|
30
|
+
# TODO: verify type is supported notifier
|
31
|
+
|
32
|
+
post('/api/alert-notifications/test', { type: type, settings: settings })
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
module Grafana
|
39
|
+
class NotificationChannels < BaseClient
|
40
|
+
include Grafana::Modules::AlertNotificationChannel
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Grafana
|
4
|
+
module Modules
|
5
|
+
module Dashboard
|
6
|
+
def home_dashboard
|
7
|
+
get('/api/dashboards/home')
|
8
|
+
end
|
9
|
+
|
10
|
+
def create_dashboard(dashboard:, **options)
|
11
|
+
# TODO: Error if dashboard is not hash specification
|
12
|
+
# TODO: error if dashboard IDs are set (should be an update if so)
|
13
|
+
|
14
|
+
req_body = {
|
15
|
+
dashboard: dashboard,
|
16
|
+
message: options[:message],
|
17
|
+
folderId: options[:folder_id],
|
18
|
+
overwrite: false # Creating new dashboard should not overwrite existing dashboards
|
19
|
+
}
|
20
|
+
|
21
|
+
post('/api/dashboards/db', req_body)
|
22
|
+
end
|
23
|
+
|
24
|
+
def update_dashboard(uid:, **options)
|
25
|
+
message = options.delete(:message)
|
26
|
+
folder_id = options.delete(:folder_id)
|
27
|
+
|
28
|
+
old_dashboard = dashboard(uid: uid)
|
29
|
+
|
30
|
+
req_body = {
|
31
|
+
dashboard: old_dashboard.merge(options),
|
32
|
+
message: message,
|
33
|
+
folderId: folder_id,
|
34
|
+
overwrite: true # Updating dashboard should overwrite existing dashboards
|
35
|
+
}
|
36
|
+
|
37
|
+
post('/api/dashboards/db', req_body)
|
38
|
+
end
|
39
|
+
|
40
|
+
def dashboard(uid:)
|
41
|
+
get("/api/dashboards/uid/#{uid}")
|
42
|
+
end
|
43
|
+
|
44
|
+
def delete_dashboard(uid:)
|
45
|
+
delete("/api/dashboards/uid/#{uid}")
|
46
|
+
end
|
47
|
+
|
48
|
+
def dashboard_tags
|
49
|
+
get('/api/dashboards/tags')
|
50
|
+
end
|
51
|
+
|
52
|
+
def dashboard_permissions(dashboard_id:)
|
53
|
+
get("/api/dashboards/id/#{dashboard_id}/permissions")
|
54
|
+
end
|
55
|
+
|
56
|
+
def update_dashboard_permissions(dashboard_id:, permissions:)
|
57
|
+
# TODO: error if permissions is not array of hashes
|
58
|
+
post("/api/dashboards/id/#{dashboard_id}/permissions", { items: permissions })
|
59
|
+
end
|
60
|
+
|
61
|
+
def dashboard_versions(dashboard_id:)
|
62
|
+
get("/api/dashboards/id/#{dashboard_id}/versions")
|
63
|
+
end
|
64
|
+
|
65
|
+
def dashboard_version(dashboard_id:, version_id:)
|
66
|
+
get("/api/dashboards/id/#{dashboard_id}/versions/#{version_id}")
|
67
|
+
end
|
68
|
+
|
69
|
+
def restore_dashboard_version(dashboard_id:, version_id:)
|
70
|
+
post("/api/dashboards/id/#{dashboard_id}/restore", { version: version_id })
|
71
|
+
end
|
72
|
+
|
73
|
+
def diff_dashboards(base_id:, base_version:, new_version:, new_id: nil, diff_type: 'json')
|
74
|
+
req_body = {
|
75
|
+
base: {
|
76
|
+
dashboardId: base_id,
|
77
|
+
version: base_version
|
78
|
+
},
|
79
|
+
new: {
|
80
|
+
dashboardId: new_id || base_id,
|
81
|
+
version: new_version
|
82
|
+
},
|
83
|
+
diffType: diff_type
|
84
|
+
}
|
85
|
+
|
86
|
+
post('/api/dashboards/calculate-diff', req_body)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
module Grafana
|
93
|
+
class Dashboards < BaseClient
|
94
|
+
include Grafana::Modules::Dashboard
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Grafana
|
2
|
+
module Modules
|
3
|
+
module DataSource
|
4
|
+
def data_sources
|
5
|
+
get('/api/datasources')
|
6
|
+
end
|
7
|
+
|
8
|
+
def data_source(uid:)
|
9
|
+
get("/api/datasources/uid/#{uid}")
|
10
|
+
end
|
11
|
+
|
12
|
+
def named_data_source(name:)
|
13
|
+
get("/api/datasources/name/#{name}")
|
14
|
+
end
|
15
|
+
|
16
|
+
def create_data_source(data_source)
|
17
|
+
post('/api/datasources', data_source)
|
18
|
+
end
|
19
|
+
|
20
|
+
def delete_data_source(uid:)
|
21
|
+
delete("/api/datasources/uid/#{uid}")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
module Grafana
|
28
|
+
class DataSources < BaseClient
|
29
|
+
include Grafana::Modules::DataSource
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Grafana
|
2
|
+
module Modules
|
3
|
+
module Folder
|
4
|
+
def folders
|
5
|
+
get('/api/folders')
|
6
|
+
end
|
7
|
+
|
8
|
+
def folder(uid:)
|
9
|
+
get("/api/folders/#{uid}")
|
10
|
+
end
|
11
|
+
|
12
|
+
def create_folder(title:, uid: nil)
|
13
|
+
req_body = {
|
14
|
+
title: title
|
15
|
+
}
|
16
|
+
|
17
|
+
req_body.merge(uid: uid) if uid.present?
|
18
|
+
|
19
|
+
post('/api/folders', req_body)
|
20
|
+
end
|
21
|
+
|
22
|
+
def update_folder(uid:, **options)
|
23
|
+
# Drop any keys that are not valid for the request
|
24
|
+
options = options.slice(:title, :new_uid, :version, :overwrite)
|
25
|
+
options[:uid] = options.delete(:new_uid) if options.key(:new_uid)
|
26
|
+
|
27
|
+
post("/api/folders/#{uid}", options)
|
28
|
+
end
|
29
|
+
|
30
|
+
def delete_folder(uid:)
|
31
|
+
delete("/api/folders#{uid}")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
module Grafana
|
38
|
+
class Folders < BaseClient
|
39
|
+
include Grafana::Modules::Folder
|
40
|
+
end
|
41
|
+
end
|
metadata
ADDED
@@ -0,0 +1,156 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: grafana-client
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Matt Tanous
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-05-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: faraday
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: faraday_middleware
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: activesupport
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '5.2'
|
48
|
+
- - "<"
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '6.2'
|
51
|
+
type: :development
|
52
|
+
prerelease: false
|
53
|
+
version_requirements: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '5.2'
|
58
|
+
- - "<"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '6.2'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: rspec
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '3.10'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '3.10'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: webmock
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '3.13'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '3.13'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: pry-byebug
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - "~>"
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '3.9'
|
96
|
+
type: :development
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - "~>"
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '3.9'
|
103
|
+
description:
|
104
|
+
email:
|
105
|
+
- mtanous22@gmail.com
|
106
|
+
executables: []
|
107
|
+
extensions: []
|
108
|
+
extra_rdoc_files: []
|
109
|
+
files:
|
110
|
+
- ".github/workflows/main.yml"
|
111
|
+
- ".github/workflows/release.yml"
|
112
|
+
- ".gitignore"
|
113
|
+
- CHANGELOG.md
|
114
|
+
- Gemfile
|
115
|
+
- LICENSE
|
116
|
+
- README.md
|
117
|
+
- Rakefile
|
118
|
+
- bin/console
|
119
|
+
- bin/setup
|
120
|
+
- grafana-client.gemspec
|
121
|
+
- lib/grafana/client.rb
|
122
|
+
- lib/grafana/client/base_client.rb
|
123
|
+
- lib/grafana/client/version.rb
|
124
|
+
- lib/grafana/modules.rb
|
125
|
+
- lib/grafana/modules/alert.rb
|
126
|
+
- lib/grafana/modules/alert_notification_channel.rb
|
127
|
+
- lib/grafana/modules/dashboard.rb
|
128
|
+
- lib/grafana/modules/data_source.rb
|
129
|
+
- lib/grafana/modules/folder.rb
|
130
|
+
homepage: https://github.com/CodingAnarchy/grafana-client
|
131
|
+
licenses:
|
132
|
+
- MIT
|
133
|
+
metadata:
|
134
|
+
homepage_uri: https://github.com/CodingAnarchy/grafana-client
|
135
|
+
source_code_uri: https://github.com/CodingAnarchy/grafana-client
|
136
|
+
changelog_uri: https://github.com/CodingAnarchy/grafana-client/blob/main/CHANGELOG.md
|
137
|
+
post_install_message:
|
138
|
+
rdoc_options: []
|
139
|
+
require_paths:
|
140
|
+
- lib
|
141
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 2.5.0
|
146
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
|
+
requirements:
|
148
|
+
- - ">="
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: '0'
|
151
|
+
requirements: []
|
152
|
+
rubygems_version: 3.2.8
|
153
|
+
signing_key:
|
154
|
+
specification_version: 4
|
155
|
+
summary: Client library for connections to Grafana API
|
156
|
+
test_files: []
|