Skip to content

Commit

Permalink
Remove address param from grafana_organization
Browse files Browse the repository at this point in the history
Organization Info (ie. its address) was removed from the Grafana UI in
grafana/grafana@21a7f57

According to
https://grafana.com/docs/grafana/v8.4/http_api/org/#update-organization
the API was not fully implemented, so I'm unconvinced this ever worked.

The property `id` is also removed as it's internal to grafana and not
something you could ever update.

Updating a `grafana_organization` never worked as `save_organization`
only implemented POSTs, (and would actually explode if you tried to
update `address`)
  • Loading branch information
alexjfisher committed May 26, 2022
1 parent c1b3289 commit de38763
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 88 deletions.
87 changes: 20 additions & 67 deletions lib/puppet/provider/grafana_organization/grafana.rb
Original file line number Diff line number Diff line change
@@ -1,97 +1,50 @@
# frozen_string_literal: true

require 'json'
require 'erb'

require File.expand_path(File.join(File.dirname(__FILE__), '..', 'grafana'))

Puppet::Type.type(:grafana_organization).provide(:grafana, parent: Puppet::Provider::Grafana) do
desc 'Support for Grafana organizations'

defaultfor kernel: 'Linux'

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

begin
organizations = JSON.parse(response.body)

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

organization = JSON.parse(response.body)

{
id: organization['id'],
name: organization['name'],
address: organization['address']
}
end
rescue JSON::ParserError
raise format('Failed to parse response: %s', response.body)
# https://grafana.com/docs/grafana/latest/http_api/org/#get-organization-by-name
def get_org_by_name(org_name)
response = send_request('GET', format('%s/orgs/name/%s', resource[:grafana_api_path], ERB::Util.url_encode(org_name)))

case response.code
when '404'
org = nil
when '200'
org = JSON.parse(response.body)
else
raise format('Failed to retrieve organization %s (HTTP response: %s/%s)', org_name, response.code, response.body)
end

org
end

def organization
@organization ||= organizations.find { |x| x[:name] == resource[:name] }
@organization ||= get_org_by_name(resource[:name])
@organization
end

attr_writer :organization

def id
organization[:id]
end

def id=(value)
resource[:id] = value
save_organization
end

def address
organization[:json_data]
end

def address=(value)
resource[:address] = value
save_organization
end

def save_organization
data = {
id: resource[:id],
name: resource[:name],
address: resource[:address]
}

response = send_request('POST', format('%s/orgs', resource[:grafana_api_path]), data) if organization.nil?

raise format('Failed to create save %s (HTTP response: %s/%s)', resource[:name], response.code, response.body) if response.code != '200'
def create
response = send_request('POST', format('%s/orgs', resource[:grafana_api_path]), { name: resource[:name] })

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

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

raise format('Failed to delete organization %s (HTTP response: %s/%s)', resource[:name], response.code, response.body) if response.code != '200'

# change back to default organization
response = send_request 'POST', format('%s/user/using/1', resource[:grafana_api_path])
raise format('Failed to switch to org %s (HTTP response: %s/%s)', fetch_organization[:id], response.code, response.body) unless response.code == '200'

self.organization = nil
end

def create
save_organization
end

def destroy
delete_organization
end

def exists?
organization
end
Expand Down
18 changes: 6 additions & 12 deletions lib/puppet/type/grafana_organization.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@
Puppet::Type.newtype(:grafana_organization) do
@doc = 'Manage organizations in Grafana'

ensurable
ensurable do
defaultvalues
defaultto :present
end

newparam(:name, namevar: true) do
desc 'The name of the organization.'

# You can't delete the default organization without first switching the API user (eg. 'admin')
# to another org first, so implementing this is non trivial.
validate do |value|
raise ArgumentError, format('Unable to modify default organization') if value == 'Main Org.'
end
Expand Down Expand Up @@ -39,17 +44,6 @@
desc 'The password for the Grafana server'
end

newproperty(:id) do
desc 'The ID of the organization'
end

newproperty(:address) do
desc 'Additional JSON data to configure the organization address (optional)'

validate do |value|
raise ArgumentError, 'address should be a Hash!' unless value.nil? || value.is_a?(Hash)
end
end
autorequire(:service) do
'grafana-server'
end
Expand Down
69 changes: 69 additions & 0 deletions spec/acceptance/grafana_organization_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# frozen_string_literal: true

require 'spec_helper_acceptance'

supported_versions.each do |grafana_version|
describe "grafana_organization with Grafana version #{grafana_version}" do
prepare_host
context 'setup grafana server' do
it 'runs successfully' do
pp = <<-EOS
class { 'grafana':
version => "#{grafana_version}",
cfg => {
security => {
admin_user => 'admin',
admin_password => 'admin'
}
}
}
EOS
prepare_host

apply_manifest(pp, catch_failures: true)
apply_manifest(pp, catch_changes: true)
end
end

it_behaves_like 'an idempotent resource' do
let(:manifest) do
<<-PUPPET
grafana_organization { 'org1':
grafana_url => 'http://localhost:3000',
grafana_user => 'admin',
grafana_password => 'admin',
}
PUPPET
end
end

describe 'Organizations with specials characters in name' do
it_behaves_like 'an idempotent resource' do
let(:manifest) do
<<-PUPPET
grafana_organization { 'Example Org!':
grafana_url => 'http://localhost:3000',
grafana_user => 'admin',
grafana_password => 'admin',
}
PUPPET
end
end
end

describe 'Deleting organizations' do
it_behaves_like 'an idempotent resource' do
let(:manifest) do
<<-PUPPET
grafana_organization { ['org1','Example Org!']:
ensure => absent,
grafana_url => 'http://localhost:3000',
grafana_user => 'admin',
grafana_password => 'admin',
}
PUPPET
end
end
end
end
end
10 changes: 1 addition & 9 deletions spec/unit/puppet/type/grafana_organization_type_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,11 @@
name: 'foo',
grafana_url: 'http://example.com',
grafana_user: 'admin',
grafana_password: 'admin',
address: { address1: 'test address1', address2: 'test address2', city: 'CityName', state: 'NewState', zipcode: '12345', country: 'USA' }
grafana_password: 'admin'
)
end

context 'when setting parameters' do
it "fails if json_data isn't valid" do
expect do
described_class.new name: 'foo', address: 'invalid address'
end.to raise_error(Puppet::Error, %r{address should be a Hash!})
end

it "fails if grafana_url isn't HTTP-based" do
expect do
described_class.new name: 'foo', grafana_url: 'example.com', content: '{}', ensure: :present
Expand All @@ -31,7 +24,6 @@
expect(gorganization[:grafana_user]).to eq('admin')
expect(gorganization[:grafana_password]).to eq('admin')
expect(gorganization[:grafana_url]).to eq('http://example.com')
expect(gorganization[:address]).to eq(address1: 'test address1', address2: 'test address2', city: 'CityName', state: 'NewState', zipcode: '12345', country: 'USA')
end

it 'autorequires the grafana-server for proper ordering' do
Expand Down

0 comments on commit de38763

Please sign in to comment.