forked from bfraser/puppet-grafana
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request bfraser#60 from atward/provider-user
grafana_user custom resource
- Loading branch information
Showing
4 changed files
with
293 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -389,6 +389,22 @@ completely missing. Example usage: | |
```puppet | ||
grafana::plugin{'grafana-simple-json-datasource':} | ||
``` | ||
|
||
##### `grafana::user` | ||
|
||
Creates and manages a global grafana user via the API. | ||
|
||
```puppet | ||
grafana_user { 'username': | ||
grafana_url => 'http://localhost:3000', | ||
grafana_user => 'admin', | ||
grafana_password => '5ecretPassw0rd', | ||
full_name => 'John Doe', | ||
password => 'Us3r5ecret', | ||
email => '[email protected]', | ||
} | ||
``` | ||
|
||
## Limitations | ||
|
||
This module has been tested on Ubuntu 14.04, using each of the 'archive', 'docker' | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
# 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. | ||
# | ||
require 'json' | ||
|
||
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'grafana')) | ||
|
||
Puppet::Type.type(:grafana_user).provide(:grafana, parent: Puppet::Provider::Grafana) do | ||
desc 'Support for Grafana users' | ||
|
||
defaultfor kernel: 'Linux' | ||
|
||
def users | ||
response = send_request('GET', '/api/users') | ||
if response.code != '200' | ||
raise format('Fail to retrieve users (HTTP response: %s/%s)', response.code, response.body) | ||
end | ||
|
||
begin | ||
users = JSON.parse(response.body) | ||
|
||
users.map { |x| x['id'] }.map do |id| | ||
response = send_request 'GET', format('/api/users/%s', id) | ||
if response.code != '200' | ||
raise format('Fail to retrieve user %d (HTTP response: %s/%s)', id, response.code, response.body) | ||
end | ||
|
||
user = JSON.parse(response.body) | ||
{ | ||
id: id, | ||
name: user['login'], | ||
full_name: user['name'], | ||
email: user['email'], | ||
theme: user['theme'], | ||
password: nil, | ||
is_admin: user['isGrafanaAdmin'] ? :true : :false | ||
} | ||
end | ||
rescue JSON::ParserError | ||
raise format('Fail to parse response: %s', response.body) | ||
end | ||
end | ||
|
||
def user | ||
@user = users.find { |x| x[:name] == resource[:name] } unless @user | ||
@user | ||
end | ||
|
||
attr_writer :user | ||
|
||
def name | ||
user[:name] | ||
end | ||
|
||
def name=(value) | ||
resource[:name] = value | ||
save_user | ||
end | ||
|
||
def full_name | ||
user[:full_name] | ||
end | ||
|
||
def full_name=(value) | ||
resource[:full_name] = value | ||
save_user | ||
end | ||
|
||
def email | ||
user[:email] | ||
end | ||
|
||
def email=(value) | ||
resource[:email] = value | ||
save_user | ||
end | ||
|
||
def theme | ||
user[:theme] | ||
end | ||
|
||
def theme=(value) | ||
resource[:theme] = value | ||
save_user | ||
end | ||
|
||
def password | ||
user[:password] | ||
end | ||
|
||
def password=(value) | ||
resource[:password] = value | ||
save_user | ||
end | ||
|
||
# rubocop:disable Style/PredicateName | ||
def is_admin | ||
user[:is_admin] | ||
end | ||
|
||
def is_admin=(value) | ||
resource[:is_admin] = value | ||
save_user | ||
end | ||
# rubocop:enable Style/PredicateName | ||
|
||
def save_user | ||
data = { | ||
login: resource[:name], | ||
name: resource[:full_name], | ||
email: resource[:email], | ||
password: resource[:password], | ||
theme: resource[:theme], | ||
isGrafanaAdmin: (resource[:is_admin] == :true) | ||
} | ||
|
||
if user.nil? | ||
response = send_request('POST', '/api/admin/users', data) | ||
else | ||
data[:id] = user[:id] | ||
send_request 'PUT', format('/api/admin/users/%s/password', user[:id]), password: data.delete(:password) | ||
send_request 'PUT', format('/api/admin/users/%s/permissions', user[:id]), isGrafanaAdmin: data.delete(:isGrafanaAdmin) | ||
response = send_request 'PUT', format('/api/users/%s', user[:id]), data | ||
end | ||
|
||
if response.code != '200' | ||
raise format('Failed to create user %s (HTTP response: %s/%s)', resource[:name], response.code, response.body) | ||
end | ||
self.user = nil | ||
end | ||
|
||
def delete_user | ||
response = send_request 'DELETE', format('/api/admin/users/%s', user[:id]) | ||
|
||
if response.code != '200' | ||
raise format('Failed to delete user %s (HTTP response: %s/%s', resource[:name], response.code, response.body) | ||
end | ||
self.user = nil | ||
end | ||
|
||
def create | ||
save_user | ||
end | ||
|
||
def destroy | ||
delete_user | ||
end | ||
|
||
def exists? | ||
user | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# 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. | ||
# | ||
Puppet::Type.newtype(:grafana_user) do | ||
@doc = 'Manage users in Grafana' | ||
|
||
ensurable | ||
|
||
newparam(:name, namevar: true) do | ||
desc 'The username of the user.' | ||
end | ||
|
||
newparam(:grafana_url) do | ||
desc 'The URL of the Grafana server' | ||
defaultto '' | ||
|
||
validate do |value| | ||
unless value =~ %r{^https?://} | ||
raise ArgumentError, format('%s is not a valid URL', value) | ||
end | ||
end | ||
end | ||
|
||
newparam(:grafana_user) do | ||
desc 'The username for the Grafana server' | ||
end | ||
|
||
newparam(:grafana_password) do | ||
desc 'The password for the Grafana server' | ||
end | ||
|
||
newparam(:full_name) do | ||
desc 'The full name of the user.' | ||
end | ||
|
||
newproperty(:password) do | ||
desc 'The password for the user' | ||
end | ||
|
||
newproperty(:email) do | ||
desc 'The email for the user' | ||
end | ||
|
||
newproperty(:theme) do | ||
desc 'The theme for the user' | ||
end | ||
|
||
newproperty(:is_admin) do | ||
desc 'Whether the user is a grafana admin' | ||
newvalues(:true, :false) | ||
defaultto :false | ||
end | ||
|
||
autorequire(:service) do | ||
'grafana-server' | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# 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. | ||
require 'spec_helper' | ||
|
||
describe Puppet::Type.type(:grafana_user) do | ||
let(:guser) do | ||
described_class.new name: 'test', full_name: 'Mr tester', password: 't3st', grafana_url: 'http://example.com/' | ||
end | ||
|
||
context 'when setting parameters' do | ||
it "fails if grafana_url isn't HTTP-based" do | ||
expect do | ||
described_class.new name: 'test', grafana_url: 'example.com' | ||
end.to raise_error(Puppet::Error, %r{not a valid URL}) | ||
end | ||
|
||
# rubocop:disable RSpec/MultipleExpectations | ||
it 'accepts valid parameters' do | ||
expect(guser[:name]).to eq('test') | ||
expect(guser[:full_name]).to eq('Mr tester') | ||
expect(guser[:password]).to eq('t3st') | ||
expect(guser[:grafana_url]).to eq('http://example.com/') | ||
end | ||
it 'autorequires the grafana-server for proper ordering' do | ||
catalog = Puppet::Resource::Catalog.new | ||
service = Puppet::Type.type(:service).new(name: 'grafana-server') | ||
catalog.add_resource service | ||
catalog.add_resource guser | ||
|
||
relationship = guser.autorequire.find do |rel| | ||
(rel.source.to_s == 'Service[grafana-server]') && (rel.target.to_s == guser.to_s) | ||
end | ||
expect(relationship).to be_a Puppet::Relationship | ||
end | ||
it 'does not autorequire the service it is not managed' do | ||
catalog = Puppet::Resource::Catalog.new | ||
catalog.add_resource guser | ||
expect(guser.autorequire).to be_empty | ||
end | ||
end | ||
end |