Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expand organization property for dashboards #94

Merged
merged 2 commits into from
Mar 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -382,13 +382,14 @@ grafana_dashboard { 'example_dashboard':
grafana_user => 'admin',
grafana_password => '5ecretPassw0rd',
grafana_api_path => '/grafana/api'
organization => 'NewOrg',
content => template('path/to/exported/file.json'),
}
```

`content` must be valid JSON, and is parsed before imported.
`grafana_user` and `grafana_password` are optional, and required when
authentication is enabled in Grafana. `grafana_api_path` is optional, and only used when using sub-paths for the API.
authentication is enabled in Grafana. `grafana_api_path` is optional, and only used when using sub-paths for the API. `organization` is optional, and used when creating a dashboard for a specific organization.

Example:
Make sure the `grafana-server` service is up and running before creating the `grafana_dashboard` definition. One option is to use the `http_conn_validator` from the [healthcheck](https://forge.puppet.com/puppet/healthcheck) module
Expand Down Expand Up @@ -420,7 +421,7 @@ grafana_datasource { 'influxdb':
grafana_password => '5ecretPassw0rd',
grafana_api_path => '/grafana/api'
type => 'influxdb',
org_name => 'NewOrg',
organization => 'NewOrg',
url => 'http://localhost:8086',
user => 'admin',
password => '1nFlux5ecret',
Expand All @@ -433,7 +434,7 @@ grafana_datasource { 'influxdb':

Available types are: influxdb, elasticsearch, graphite, cloudwatch, mysql, opentsdb, and prometheus

`org_name` is used to set which organization a datasource will be created on. If this parameter is not set, it will default to organization ID 1 (Main Org. by default). If the default org is deleted, organizations will need to be specified.
`organization` is used to set which organization a datasource will be created on. If this parameter is not set, it will default to organization ID 1 (Main Org. by default). If the default org is deleted, organizations will need to be specified.

Access mode determines how Grafana connects to the datasource, either `direct`
from the browser, or `proxy` to send requests via grafana.
Expand Down
55 changes: 54 additions & 1 deletion lib/puppet/provider/grafana_dashboard/grafana.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,53 @@

defaultfor kernel: 'Linux'

def organization
resource[:organization]
end

def grafana_api_path
resource[:grafana_api_path]
end

def fetch_organizations
response = send_request('GET', format('%s/orgs', resource[:grafana_api_path]))
if response.code != '200'
raise format('Fail to retrieve organizations (HTTP response: %s/%s)', response.code, response.body)
end

begin
fetch_organizations = JSON.parse(response.body)

fetch_organizations.map { |x| x['id'] }.map do |id|
response = send_request 'GET', format('%s/orgs/%s', resource[:grafana_api_path], id)
if response.code != '200'
raise format('Failed to retrieve organization %d (HTTP response: %s/%s)', id, response.code, response.body)
end

fetch_organization = JSON.parse(response.body)

{
id: fetch_organization['id'],
name: fetch_organization['name']
}
end
rescue JSON::ParserError
raise format('Failed to parse response: %s', response.body)
end
end

def fetch_organization
unless @fetch_organization
@fetch_organization =
if resource[:organization].is_a?(Numeric) || resource[:organization].match(%r{^[0-9]*$})
fetch_organizations.find { |x| x[:id] == resource[:organization] }
else
fetch_organizations.find { |x| x[:name] == resource[:organization] }
end
end
@fetch_organization
end

# Return the list of dashboards
def dashboards
response = send_request('GET', format('%s/search', resource[:grafana_api_path]), nil, q: '', starred: false)
Expand Down Expand Up @@ -44,6 +91,12 @@ def find_dashboard
end

def save_dashboard(dashboard)
# change organizations
response = send_request 'POST', format('%s/user/using/%s', resource[:grafana_api_path], fetch_organization[:id])
unless response.code == '200'
raise format('Failed to switch to org %s (HTTP response: %s/%s)', fetch_organization[:id], response.code, response.body)
end

data = {
dashboard: dashboard.merge('title' => resource[:title],
'id' => @dashboard ? @dashboard['id'] : nil,
Expand All @@ -52,7 +105,7 @@ def save_dashboard(dashboard)
}

response = send_request('POST', format('%s/dashboards/db', resource[:grafana_api_path]), data)
return unless response.code != '200'
return unless (response.code != '200') && (response.code != '412')
raise format('Fail to save dashboard %s (HTTP response: %s/%s', resource[:name], response.code, response.body)
end

Expand Down
37 changes: 18 additions & 19 deletions lib/puppet/provider/grafana_datasource/grafana.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ def organization
resource[:organization]
end

def grafana_api_path
resource[:grafana_api_path]
end

def fetch_organizations
response = send_request('GET', format('%s/orgs', resource[:grafana_api_path]))
if response.code != '200'
Expand All @@ -21,9 +25,8 @@ def fetch_organizations

begin
fetch_organizations = JSON.parse(response.body)

fetch_organizations.map { |x| x['id'] }.map do |id|
response = send_request('GET', format('%s/orgs/%s', resource[:grafana_api_path], id))
response = send_request 'GET', format('%s/orgs/%s', resource[:grafana_api_path], id)
if response.code != '200'
raise format('Failed to retrieve organization %d (HTTP response: %s/%s)', id, response.code, response.body)
end
Expand All @@ -42,9 +45,13 @@ def fetch_organizations

def fetch_organization
unless @fetch_organization
@fetch_organization = fetch_organizations.find { |x| x[:name] == resource[:organization] }
@fetch_organization = if resource[:organization].is_a?(Numeric) || resource[:organization].match(%r{^[0-9]*$})
fetch_organizations.find { |x| x[:id] == resource[:organization] }
else
fetch_organizations.find { |x| x[:name] == resource[:organization] }
end
end
@organization
@fetch_organization
end

def datasources
Expand All @@ -57,7 +64,7 @@ def datasources
datasources = JSON.parse(response.body)

datasources.map { |x| x['id'] }.map do |id|
response = send_request('GET', format('%s/datasources/%s', resource[:grafana_api_path], id))
response = send_request 'GET', format('%s/datasources/%s', resource[:grafana_api_path], id)
if response.code != '200'
raise format('Failed to retrieve datasource %d (HTTP response: %s/%s)', id, response.code, response.body)
end
Expand Down Expand Up @@ -206,17 +213,10 @@ def json_data=(value)
end

def save_datasource
if fetch_organization.nil?
response = send_request('POST', format('%s/user/using/1', resource[:grafana_api_path]))
if response.code != '200'
raise format('Failed to switch to org 1 (HTTP response: %s/%s)', response.code, response.body)
end
else
organization_id = fetch_organization[:id]
response = send_request 'POST', format('%s/user/using/%s', resource[:grafana_api_path], organization_id)
if response.code != '200'
raise format('Failed to switch to org %s (HTTP response: %s/%s)', organization_id, response.code, response.body)
end
# change organizations
response = send_request 'POST', format('%s/user/using/%s', resource[:grafana_api_path], fetch_organization[:id])
unless response.code == '200'
raise format('Failed to switch to org %s (HTTP response: %s/%s)', fetch_organization[:id], response.code, response.body)
end

data = {
Expand All @@ -239,17 +239,16 @@ def save_datasource
response = send_request('POST', format('%s/datasources', resource[:grafana_api_path]), data)
else
data[:id] = datasource[:id]
response = send_request('PUT', format('%s/datasources/%s', resource[:grafana_api_path], datasource[:id]), data)
response = send_request 'PUT', format('%s/datasources/%s', resource[:grafana_api_path], datasource[:id]), data
end

if response.code != '200'
raise format('Failed to create save %s (HTTP response: %s/%s)', resource[:name], response.code, response.body)
end
self.datasource = nil
end

def delete_datasource
response = send_request('DELETE', format('%s/datasources/%s', resource[:grafana_api_path], datasource[:id]))
response = send_request 'DELETE', format('%s/datasources/%s', resource[:grafana_api_path], datasource[:id])

if response.code != '200'
raise format('Failed to delete datasource %s (HTTP response: %s/%s', resource[:name], response.code, response.body)
Expand Down
2 changes: 1 addition & 1 deletion lib/puppet/provider/grafana_organization/grafana.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def save_organization
end

def delete_organization
response = send_request('DELETE', format('%s/orgs/%s', resource[:grafana_api_path], organization[:id]))
response = send_request 'DELETE', format('%s/orgs/%s', resource[:grafana_api_path], organization[:id])

if response.code != '200'
raise format('Failed to delete organization %s (HTTP response: %s/%s)', resource[:name], response.code, response.body)
Expand Down
5 changes: 5 additions & 0 deletions lib/puppet/type/grafana_dashboard.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ def should_to_s(value)
end
end

newparam(:organization) do
desc 'The organization name to create the datasource on'
defaultto 1
end

# rubocop:disable Style/SignalException
validate do
fail('content is required when ensure is present') if self[:ensure] == :present && self[:content].nil?
Expand Down
4 changes: 2 additions & 2 deletions lib/puppet/type/grafana_datasource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@
newvalues(:influxdb, :elasticsearch, :graphite, :kairosdb, :opentsdb, :prometheus)
end

newproperty(:organization) do
newparam(:organization) do
desc 'The organization name to create the datasource on'
defaultto '1'
defaultto 1
end

newproperty(:user) do
Expand Down