Class: Grafana::Grafana

Inherits:
Object
  • Object
show all
Defined in:
lib/grafana/grafana.rb

Overview

Main class for handling the interaction with one specific Grafana instance.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(base_uri, key = nil, opts = {}) ⇒ Grafana

Returns a new instance of Grafana.

Parameters:

  • base_uri (String)

    full URI pointing to the specific grafana instance without trailing slash, e.g. https://localhost:3000.

  • key (String) (defaults to: nil)

    API key for the grafana instance, if required

  • opts (Hash) (defaults to: {})

    additional options. Currently supporting :logger and :ssl_disable_verify.



19
20
21
22
23
24
25
26
27
28
29
# File 'lib/grafana/grafana.rb', line 19

def initialize(base_uri, key = nil, opts = {})
  @base_uri = base_uri
  @key = key
  @dashboards = {}
  @organization = {}
  @logger = opts[:logger] || ::Logger.new(nil)
  @ssl_disable_verify = opts[:ssl_disable_verify] || false
  @ssl_cert = opts[:ssl_cert]

  initialize_datasources unless @base_uri.empty?
end

Instance Attribute Details

#loggerObject (readonly)

Returns the value of attribute logger.



12
13
14
# File 'lib/grafana/grafana.rb', line 12

def logger
  @logger
end

Instance Method Details

#dashboard(dashboard_uid) ⇒ Dashboard

Returns dashboard object, if it has been found.

Parameters:

  • dashboard_uid (String)

    UID of the searched Dashboard

Returns:

  • (Dashboard)

    dashboard object, if it has been found

Raises:



153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/grafana/grafana.rb', line 153

def dashboard(dashboard_uid)
  return @dashboards[dashboard_uid] if @dashboards[dashboard_uid]

  response = prepare_request({ relative_url: "/api/dashboards/uid/#{dashboard_uid}" }).execute
  raise DashboardDoesNotExistError, dashboard_uid unless response.is_a?(Net::HTTPOK)

  # cache dashboard for reuse
  model = JSON.parse(response.body)['dashboard']
  @dashboards[dashboard_uid] = Dashboard.new(model, self)

  @dashboards[dashboard_uid]
end

#dashboard_idsArray

Returns Array of dashboard uids within the current grafana object.

Returns:

  • (Array)

    Array of dashboard uids within the current grafana object



138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/grafana/grafana.rb', line 138

def dashboard_ids
  response = prepare_request({ relative_url: '/api/search' }).execute
  return [] unless response.is_a?(Net::HTTPOK)

  dashboards = JSON.parse(response.body)

  dashboards.each do |dashboard|
    @dashboards[dashboard['uid']] = nil unless @dashboards[dashboard['uid']]
  end

  @dashboards.keys
end

#datasource_by_id(datasource_id) ⇒ Datasource

Returns the datasource, which has been queried by the datasource id.

Parameters:

  • datasource_id (Integer)

    id of the searched datasource

Returns:

  • (Datasource)

    Datasource for the specified datasource id

Raises:



129
130
131
132
133
134
135
# File 'lib/grafana/grafana.rb', line 129

def datasource_by_id(datasource_id)
  clean_nil_datasources
  datasource = @datasources.select { |name, ds| ds.id == datasource_id.to_i }.values.first
  raise DatasourceDoesNotExistError.new('id', datasource_id) unless datasource

  datasource
end

#datasource_by_model_entry(model_entry) ⇒ Datasource

Returns the datasource, which has been queried by model entry in the panel model.

Parameters:

  • model_entry (Object)

    model entry of the searched datasource (e.g. String or Hash)

Returns:

  • (Datasource)

    Datasource for the specified datasource model entry

Raises:



85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/grafana/grafana.rb', line 85

def datasource_by_model_entry(model_entry)
  datasource = nil
  if model_entry.is_a?(String)
    datasource = datasource_by_name(model_entry)
  elsif model_entry.is_a?(Hash)
    datasource = datasource_by_uid(model_entry['uid'])
  end

  raise DatasourceDoesNotExistError.new('model entry', model_entry) unless datasource

  datasource
end

#datasource_by_name(datasource_name) ⇒ Datasource

Returns the datasource, which has been queried by the datasource name.

Parameters:

  • datasource_name (String)

    name of the searched datasource

Returns:

  • (Datasource)

    Datasource for the specified datasource name

Raises:



102
103
104
105
106
107
108
109
# File 'lib/grafana/grafana.rb', line 102

def datasource_by_name(datasource_name)
  datasource_name = 'default' if datasource_name.to_s.empty?
  # TODO: PRIO add support for grafana builtin datasource types
  return UnsupportedDatasource.new(nil) if datasource_name.to_s =~ /-- (?:Mixed|Dashboard|Grafana) --/
  raise DatasourceDoesNotExistError.new('name', datasource_name) unless @datasources[datasource_name]

  @datasources[datasource_name]
end

#datasource_by_uid(datasource_uid) ⇒ Datasource

Returns the datasource, which has been queried by the datasource uid.

Parameters:

  • datasource_uid (String)

    unique id of the searched datasource

Returns:

  • (Datasource)

    Datasource for the specified datasource unique id

Raises:



115
116
117
118
119
120
121
122
123
# File 'lib/grafana/grafana.rb', line 115

def datasource_by_uid(datasource_uid)
  raise DatasourceDoesNotExistError.new('uid', datasource_uid) unless datasource_uid

  clean_nil_datasources
  datasource = @datasources.select { |ds_name, ds| ds.uid == datasource_uid }.values.first
  raise DatasourceDoesNotExistError.new('uid', datasource_uid) unless datasource

  datasource
end

#organizationHash

Returns Information about the current organization.

Returns:

  • (Hash)

    Information about the current organization



32
33
34
35
36
37
38
39
40
# File 'lib/grafana/grafana.rb', line 32

def organization
  return @organization unless @organization.empty?

  response = prepare_request({ relative_url: '/api/org/' }).execute
  return @organization unless response.is_a?(Net::HTTPOK)

  @organization = JSON.parse(response.body)
  @organization
end

#prepare_request(options = {}) ⇒ WebRequest

Prepares a WebRequest object for the current Grafana::Grafana instance, which may be enriched with further properties and can then run WebRequest#execute.

Parameters:

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • :relative_url (Hash)

    relative URL with a leading slash, which shall be queried

  • :accept (Hash)
  • :body (Hash)
  • :content_type (Hash)

Returns:

  • (WebRequest)

    webrequest prepared for execution



174
175
176
177
# File 'lib/grafana/grafana.rb', line 174

def prepare_request(options = {})
  auth = @key ? { authorization: "Bearer #{@key}" } : {}
  WebRequest.new(@base_uri, auth.merge({ logger: @logger, ssl_disable_verify: @ssl_disable_verify, ssl_cert: @ssl_cert }).merge(options))
end

#test_connectionString

Used to test a connection to the grafana instance.

Running this function also determines, if the API configured here has Admin or NON-Admin privileges, or even fails on connecting to grafana.

Returns:

  • (String)

    Admin, NON-Admin, SSLError or Failed is returned, depending on the test results



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/grafana/grafana.rb', line 59

def test_connection
  @logger.warn('Reporter disabled the SSL verification for grafana. This is a potential security risk.') if @ssl_disable_verify

  if prepare_request({ relative_url: '/api/datasources' }).execute.is_a?(Net::HTTPOK)
    # we have admin rights
    @logger.warn('Reporter is running with Admin privileges on grafana. This is a potential security risk.')
    return 'Admin'
  end

  # check if we have lower rights or an SSL error occurs
  case prepare_request({ relative_url: '/api/dashboards/home' }).execute(nil, true)
  when Net::HTTPOK
  when OpenSSL::SSL::SSLError
    return 'SSLError'
  else
    return 'Failed'
  end

  @logger.info('Reporter is running with NON-Admin privileges on grafana.')
  'NON-Admin'
end

#versionString

Returns grafana version.

Returns:

  • (String)

    grafana version



43
44
45
46
47
48
49
50
51
# File 'lib/grafana/grafana.rb', line 43

def version
  return @version if @version

  response = prepare_request({ relative_url: '/api/health' }).execute
  return @version unless response.is_a?(Net::HTTPOK)

  @version = JSON.parse(response.body)['version']
  @version
end