diff --git a/lib/puppet/provider/grafana_dashboard/grafana.rb b/lib/puppet/provider/grafana_dashboard/grafana.rb index bdfd77e..5b5770b 100644 --- a/lib/puppet/provider/grafana_dashboard/grafana.rb +++ b/lib/puppet/provider/grafana_dashboard/grafana.rb @@ -1,172 +1,174 @@ # Copyright 2015 Mirantis, Inc. # require 'json' require File.expand_path(File.join(File.dirname(__FILE__), '..', 'grafana')) # Note: this class doesn't implement the self.instances and self.prefetch # methods because the Grafana API doesn't allow to retrieve the dashboards and # all their properties in a single call. Puppet::Type.type(:grafana_dashboard).provide(:grafana, parent: Puppet::Provider::Grafana) do desc 'Support for Grafana dashboards stored into Grafana' 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 def folders response = send_request('GET', format('%s/folders', resource[:grafana_api_path])) if response.code != '200' raise format('Fail to retrieve the folders (HTTP response: %s/%s)', response.code, response.body) end begin @folders = JSON.parse(response.body) rescue JSON::ParserError raise format('Fail to parse folders (HTTP response: %s/%s)', response.code, response.body) end end def find_folder folders unless @folders begin @folders.each do |folder| @folder = folder if folder['title'] == resource[:folder] end raise format('Folder not found: %s', resource[:folder]) unless @folder['title'] == resource[:folder] rescue JSON::ParserError raise format('Fail to parse folder %s: %s', resource[:folder], response.body) end end # Return the list of dashboards def dashboards # 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 response = send_request('GET', format('%s/search', resource[:grafana_api_path]), nil, q: '', starred: false) if response.code != '200' raise format('Fail to retrieve the dashboards (HTTP response: %s/%s)', response.code, response.body) end begin JSON.parse(response.body) rescue JSON::ParserError raise format('Fail to parse dashboards (HTTP response: %s/%s)', response.code, response.body) end end # Return the dashboard matching with the resource's title def find_dashboard return unless dashboards.find { |x| x['title'] == resource[:title] } - response = send_request('GET', format('%s/dashboards/db/%s', resource[:grafana_api_path], slug)) + response = send_request('GET', format('%s/dashboards/uid/%s', resource[:grafana_api_path], slug)) + if response.code != '200' raise format('Fail to retrieve dashboard %s (HTTP response: %s/%s)', resource[:title], response.code, response.body) end begin # Cache the dashboard's content @dashboard = JSON.parse(response.body)['dashboard'] rescue JSON::ParserError raise format('Fail to parse dashboard %s: %s', resource[:title], response.body) end end def save_dashboard(dashboard) find_folder if resource[:folder] # 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, + 'uid' => slug, 'version' => @dashboard ? @dashboard['version'] + 1 : 0), folderId: @folder ? @folder['id'] : nil, overwrite: !@dashboard.nil? } response = send_request('POST', format('%s/dashboards/db', resource[:grafana_api_path]), data) 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 def slug resource[:title].downcase.gsub(%r{[ \+]+}, '-').gsub(%r{[^\w\- ]}, '') end def content - @dashboard.reject { |k, _| k =~ %r{^id|version|title$} } + @dashboard.reject { |k, _| k =~ %r{^id|uid|version|title$} } end def content=(value) save_dashboard(value) end def create save_dashboard(resource[:content]) end def destroy - response = send_request('DELETE', format('%s/dashboards/db/%s', resource[:grafana_api_path], slug)) + response = send_request('DELETE', format('%s/dashboards/uid/%s', resource[:grafana_api_path], slug)) return unless response.code != '200' raise Puppet::Error, format('Failed to delete dashboard %s (HTTP response: %s/%s', resource[:title], response.code, response.body) end def exists? find_dashboard end end diff --git a/spec/acceptance/class_spec.rb b/spec/acceptance/class_spec.rb index 0b42ddd..f9cbfcb 100644 --- a/spec/acceptance/class_spec.rb +++ b/spec/acceptance/class_spec.rb @@ -1,168 +1,177 @@ require 'spec_helper_acceptance' -describe 'grafana class' do - # Create dummy module directorty - shell('mkdir -p /etc/puppetlabs/code/environments/production/modules/my_custom_module/files/dashboards') +supported_versions.each do |grafana_version| + describe "grafana class with Grafana version #{grafana_version}" do + # Create dummy module directorty + shell('mkdir -p /etc/puppetlabs/code/environments/production/modules/my_custom_module/files/dashboards') + context 'default parameters' do + before do + install_module_from_forge('puppetlabs/apt', '>= 7.5.0 < 8.0.0') + end + # Using puppet_apply as a helper + it 'works idempotently with no errors' do + pp = <<-EOS + class { 'grafana': + version => "#{grafana_version}" + } + EOS - context 'default parameters' do - before do - install_module_from_forge('puppetlabs/apt', '>= 7.5.0 < 8.0.0') - end - # Using puppet_apply as a helper - it 'works idempotently with no errors' do - pp = <<-EOS - class { 'grafana': } - EOS + prepare_host - # Run it twice and test for idempotency - apply_manifest(pp, catch_failures: true) - apply_manifest(pp, catch_changes: true) - end + # Run it twice and test for idempotency + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) + end - describe package('grafana') do - it { is_expected.to be_installed } - end + describe package('grafana') do + it { is_expected.to be_installed } + end - describe service('grafana-server') do - it { is_expected.to be_enabled } - it { is_expected.to be_running } + describe service('grafana-server') do + it { is_expected.to be_enabled } + it { is_expected.to be_running } + end end - end - context 'with fancy dashboard config' do - it 'works idempotently with no errors' do - pp = <<-EOS - class { 'grafana': - provisioning_datasources => { - apiVersion => 1, - datasources => [ - { - name => 'Prometheus', - type => 'prometheus', - access => 'proxy', - url => 'http://localhost:9090/prometheus', - isDefault => false, - }, - ], - }, - provisioning_dashboards => { - apiVersion => 1, - providers => [ - { - name => 'default', - orgId => 1, - folder => '', - type => 'file', - disableDeletion => true, - options => { - path => '/var/lib/grafana/dashboards', - puppetsource => 'puppet:///modules/my_custom_module/dashboards', + context 'with fancy dashboard config' do + it 'works idempotently with no errors' do + pp = <<-EOS + class { 'grafana': + version => "#{grafana_version}", + provisioning_datasources => { + apiVersion => 1, + datasources => [ + { + name => 'Prometheus', + type => 'prometheus', + access => 'proxy', + url => 'http://localhost:9090/prometheus', + isDefault => false, }, - }, - ], + ], + }, + provisioning_dashboards => { + apiVersion => 1, + providers => [ + { + name => 'default', + orgId => 1, + folder => '', + type => 'file', + disableDeletion => true, + options => { + path => '/var/lib/grafana/dashboards', + puppetsource => 'puppet:///modules/my_custom_module/dashboards', + }, + }, + ], + } } - } - EOS + EOS - # Run it twice and test for idempotency - apply_manifest(pp, catch_failures: true) - apply_manifest(pp, catch_changes: true) + # Run it twice and test for idempotency + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) + end end - end - context 'with fancy dashboard config and custom target file' do - it 'works idempotently with no errors' do - pp = <<-EOS - class { 'grafana': - provisioning_datasources => { - apiVersion => 1, - datasources => [ - { - name => 'Prometheus', - type => 'prometheus', - access => 'proxy', - url => 'http://localhost:9090/prometheus', - isDefault => false, - }, - ], - }, - provisioning_dashboards => { - apiVersion => 1, - providers => [ - { - name => 'default', - orgId => 1, - folder => '', - type => 'file', - disableDeletion => true, - options => { - path => '/var/lib/grafana/dashboards', - puppetsource => 'puppet:///modules/my_custom_module/dashboards', + context 'with fancy dashboard config and custom target file' do + it 'works idempotently with no errors' do + pp = <<-EOS + class { 'grafana': + version => "#{grafana_version}", + provisioning_datasources => { + apiVersion => 1, + datasources => [ + { + name => 'Prometheus', + type => 'prometheus', + access => 'proxy', + url => 'http://localhost:9090/prometheus', + isDefault => false, + }, + ], + }, + provisioning_dashboards => { + apiVersion => 1, + providers => [ + { + name => 'default', + orgId => 1, + folder => '', + type => 'file', + disableDeletion => true, + options => { + path => '/var/lib/grafana/dashboards', + puppetsource => 'puppet:///modules/my_custom_module/dashboards', + }, }, - }, - ], - }, - provisioning_dashboards_file => '/etc/grafana/provisioning/dashboards/dashboard.yaml', - provisioning_datasources_file => '/etc/grafana/provisioning/datasources/datasources.yaml' - } - EOS + ], + }, + provisioning_dashboards_file => '/etc/grafana/provisioning/dashboards/dashboard.yaml', + provisioning_datasources_file => '/etc/grafana/provisioning/datasources/datasources.yaml' + } + EOS - # Run it twice and test for idempotency - apply_manifest(pp, catch_failures: true) - apply_manifest(pp, catch_changes: true) + # Run it twice and test for idempotency + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) + end end end +end +describe 'grafana class with latest grafana version' do context 'update to beta release' do it 'works idempotently with no errors' do case fact('os.family') when 'Debian' pp = <<-EOS class { 'grafana': version => 'latest', repo_name => 'beta', } EOS when 'RedHat' pp = <<-EOS class { 'grafana': version => 'latest', repo_name => 'beta', } EOS end # Run it twice and test for idempotency apply_manifest(pp, catch_failures: true) apply_manifest(pp, catch_changes: true) end describe package('grafana') do it { is_expected.to be_installed } end end context 'revert back to stable' do it 'works idempotently with no errors' do case fact('os.family') when 'Debian' pp = <<-EOS class { 'grafana': version => 'latest', } EOS # Run it twice and test for idempotency apply_manifest(pp, catch_failures: true) apply_manifest(pp, catch_changes: true) when 'RedHat' shell('/bin/rm /etc/yum.repos.d/grafana-beta.repo') shell('yum -y downgrade grafana') # No manifest to apply here end end describe package('grafana') do it { is_expected.to be_installed } end end end diff --git a/spec/acceptance/grafana_folder_spec.rb b/spec/acceptance/grafana_folder_spec.rb index 250c2b1..3cc532d 100644 --- a/spec/acceptance/grafana_folder_spec.rb +++ b/spec/acceptance/grafana_folder_spec.rb @@ -1,196 +1,201 @@ require 'spec_helper_acceptance' -describe 'grafana_folder' do - context 'setup grafana server' do - it 'runs successfully' do - pp = <<-EOS - class { 'grafana': - cfg => { - security => { - admin_user => 'admin', - admin_password => 'admin' +supported_versions.each do |grafana_version| + describe "grafana_folder with Grafana version #{grafana_version}" do + 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 - apply_manifest(pp, catch_failures: true) - apply_manifest(pp, catch_changes: true) - end - end + EOS + prepare_host - context 'create folder resource' do - it 'creates the folders' do - pp = <<-EOS - include grafana::validator - grafana_folder { 'example-folder': - ensure => present, - uid => 'example-folder', - grafana_url => 'http://localhost:3000', - grafana_user => 'admin', - grafana_password => 'admin', - permissions => [ - {'permission' => 2, 'role' => 'Editor'}, - {'permission' => 1, 'role' => 'Viewer'}, - ], - } - grafana_folder { 'editor-folder': - ensure => present, - uid => 'editor-folder', - grafana_url => 'http://localhost:3000', - grafana_user => 'admin', - grafana_password => 'admin', - permissions => [ - {'permission' => 1, 'role' => 'Editor'}, - ], - } - EOS - apply_manifest(pp, catch_failures: true) - apply_manifest(pp, catch_changes: true) + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) + end end - it 'has created the example folder' do - shell('curl --user admin:admin http://localhost:3000/api/folders') do |f| - expect(f.stdout).to match(%r{example-folder}) + context 'create folder resource' do + it 'creates the folders' do + pp = <<-EOS + include grafana::validator + grafana_folder { 'example-folder': + ensure => present, + uid => 'example-folder', + grafana_url => 'http://localhost:3000', + grafana_user => 'admin', + grafana_password => 'admin', + permissions => [ + {'permission' => 2, 'role' => 'Editor'}, + {'permission' => 1, 'role' => 'Viewer'}, + ], + } + grafana_folder { 'editor-folder': + ensure => present, + uid => 'editor-folder', + grafana_url => 'http://localhost:3000', + grafana_user => 'admin', + grafana_password => 'admin', + permissions => [ + {'permission' => 1, 'role' => 'Editor'}, + ], + } + EOS + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) end - end - it 'has created the editor folder' do - shell('curl --user admin:admin http://localhost:3000/api/folders') do |f| - expect(f.stdout).to match(%r{editor-folder}) + + it 'has created the example folder' do + shell('curl --user admin:admin http://localhost:3000/api/folders') do |f| + expect(f.stdout).to match(%r{example-folder}) + end end - end - it 'has created the example folder permissions' do - shell('curl --user admin:admin http://localhost:3000/api/folders/example-folder/permissions') do |f| - data = JSON.parse(f.stdout) - expect(data).to include(hash_including('permission' => 2, 'role' => 'Editor'), hash_including('permission' => 1, 'role' => 'Viewer')) + it 'has created the editor folder' do + shell('curl --user admin:admin http://localhost:3000/api/folders') do |f| + expect(f.stdout).to match(%r{editor-folder}) + end end - end - it 'has created the editor folder permissions' do - shell('curl --user admin:admin http://localhost:3000/api/folders/editor-folder/permissions') do |f| - data = JSON.parse(f.stdout) - expect(data).to include(hash_including('permission' => 1, 'role' => 'Editor')) + it 'has created the example folder permissions' do + shell('curl --user admin:admin http://localhost:3000/api/folders/example-folder/permissions') do |f| + data = JSON.parse(f.stdout) + expect(data).to include(hash_including('permission' => 2, 'role' => 'Editor'), hash_including('permission' => 1, 'role' => 'Viewer')) + end + end + it 'has created the editor folder permissions' do + shell('curl --user admin:admin http://localhost:3000/api/folders/editor-folder/permissions') do |f| + data = JSON.parse(f.stdout) + expect(data).to include(hash_including('permission' => 1, 'role' => 'Editor')) + end end end - end - context 'updates folder resource' do - it 'updates the folders' do - pp = <<-EOS + context 'updates folder resource' do + it 'updates the folders' do + pp = <<-EOS grafana_folder { 'example-folder': ensure => present, uid => 'example-folder', grafana_url => 'http://localhost:3000', grafana_user => 'admin', grafana_password => 'admin', permissions => [ {'permission' => 2, 'role' => 'Editor'}, ], } grafana_folder { 'editor-folder': ensure => present, uid => 'editor-folder', grafana_url => 'http://localhost:3000', grafana_user => 'admin', grafana_password => 'admin', permissions => [ {'permission' => 1, 'role' => 'Viewer'}, ], } - EOS - apply_manifest(pp, catch_failures: true) - apply_manifest(pp, catch_changes: true) - end + EOS + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) + end - it 'has updated the example folder permissions' do - shell('curl --user admin:admin http://localhost:3000/api/folders/example-folder/permissions') do |f| - data = JSON.parse(f.stdout) - expect(data).to include(hash_including('permission' => 2, 'role' => 'Editor')) - # expect(data.size).to eq(1) - # expect(data[0]['permission']).to eq(2) - # expect(data[0]['role']).to eq('Editor') + it 'has updated the example folder permissions' do + shell('curl --user admin:admin http://localhost:3000/api/folders/example-folder/permissions') do |f| + data = JSON.parse(f.stdout) + expect(data).to include(hash_including('permission' => 2, 'role' => 'Editor')) + # expect(data.size).to eq(1) + # expect(data[0]['permission']).to eq(2) + # expect(data[0]['role']).to eq('Editor') + end end - end - it 'has updated the editor folder permissions' do - shell('curl --user admin:admin http://localhost:3000/api/folders/editor-folder/permissions') do |f| - data = JSON.parse(f.stdout) - expect(data).to include(hash_including('permission' => 1, 'role' => 'Viewer')) + it 'has updated the editor folder permissions' do + shell('curl --user admin:admin http://localhost:3000/api/folders/editor-folder/permissions') do |f| + data = JSON.parse(f.stdout) + expect(data).to include(hash_including('permission' => 1, 'role' => 'Viewer')) + end end end - end - context 'create folder containing dashboard' do - it 'creates an example dashboard in the example folder' do - pp = <<-EOS - include grafana::validator - grafana_dashboard { 'example-dashboard': - ensure => present, - grafana_url => 'http://localhost:3000', - grafana_user => 'admin', - grafana_password => 'admin', - content => '{"uid": "abc123xy"}', - folder => 'example-folder' - } - EOS - apply_manifest(pp, catch_failures: true) - apply_manifest(pp, catch_changes: true) - end + context 'create folder containing dashboard' do + it 'creates an example dashboard in the example folder' do + pp = <<-EOS + include grafana::validator + grafana_dashboard { 'example-dashboard': + ensure => present, + grafana_url => 'http://localhost:3000', + grafana_user => 'admin', + grafana_password => 'admin', + content => '{"description": "example dashboard"}', + folder => 'example-folder' + } + EOS + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) + end - it 'folder contains dashboard' do - shell('curl --user admin:admin http://localhost:3000/api/dashboards/db/example-dashboard') do |f| - expect(f.stdout).to match(%r{"folderId":1}) + it 'folder contains dashboard' do + shell('curl --user admin:admin http://localhost:3000/api/dashboards/uid/example-dashboard') do |f| + expect(f.stdout).to match(%r{"folderId":1}) + end end end - end - context 'destroy resources' do - it 'destroys the folders and dashboard' do - pp = <<-EOS - include grafana::validator - grafana_folder { 'example-folder': - ensure => absent, - grafana_url => 'http://localhost:3000', - grafana_user => 'admin', - grafana_password => 'admin', - } - grafana_folder { 'editor-folder': - ensure => absent, - grafana_url => 'http://localhost:3000', - grafana_user => 'admin', - grafana_password => 'admin', - } - grafana_folder { 'nomatch-folder': - ensure => absent, - grafana_url => 'http://localhost:3000', - grafana_user => 'admin', - grafana_password => 'admin', - } - grafana_dashboard { 'example-dashboard': - ensure => absent, - grafana_url => 'http://localhost:3000', - grafana_user => 'admin', - grafana_password => 'admin', - } - EOS + context 'destroy resources' do + it 'destroys the folders and dashboard' do + pp = <<-EOS + include grafana::validator + grafana_folder { 'example-folder': + ensure => absent, + grafana_url => 'http://localhost:3000', + grafana_user => 'admin', + grafana_password => 'admin', + } + grafana_folder { 'editor-folder': + ensure => absent, + grafana_url => 'http://localhost:3000', + grafana_user => 'admin', + grafana_password => 'admin', + } + grafana_folder { 'nomatch-folder': + ensure => absent, + grafana_url => 'http://localhost:3000', + grafana_user => 'admin', + grafana_password => 'admin', + } + grafana_dashboard { 'example-dashboard': + ensure => absent, + grafana_url => 'http://localhost:3000', + grafana_user => 'admin', + grafana_password => 'admin', + } + EOS - apply_manifest(pp, catch_failures: true) - apply_manifest(pp, catch_changes: true) - end + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) + end - it 'has no example-folder' do - shell('curl --user admin:admin http://localhost:3000/api/folders') do |f| - expect(f.stdout).not_to match(%r{example-folder}) + it 'has no example-folder' do + shell('curl --user admin:admin http://localhost:3000/api/folders') do |f| + expect(f.stdout).not_to match(%r{example-folder}) + end end - end - it 'has no editor-folder' do - shell('curl --user admin:admin http://localhost:3000/api/folders') do |f| - expect(f.stdout).not_to match(%r{editor-folder}) + it 'has no editor-folder' do + shell('curl --user admin:admin http://localhost:3000/api/folders') do |f| + expect(f.stdout).not_to match(%r{editor-folder}) + end end - end - it 'has no nomatch-folder' do - shell('curl --user admin:admin http://localhost:3000/api/folders') do |f| - expect(f.stdout).not_to match(%r{nomatch-folder}) + it 'has no nomatch-folder' do + shell('curl --user admin:admin http://localhost:3000/api/folders') do |f| + expect(f.stdout).not_to match(%r{nomatch-folder}) + end end end end end diff --git a/spec/acceptance/grafana_plugin_spec.rb b/spec/acceptance/grafana_plugin_spec.rb index 8369974..38c081e 100644 --- a/spec/acceptance/grafana_plugin_spec.rb +++ b/spec/acceptance/grafana_plugin_spec.rb @@ -1,85 +1,97 @@ require 'spec_helper_acceptance' -describe 'grafana_plugin' do - context 'create plugin resource' do - it 'runs successfully' do - pp = <<-EOS - class { 'grafana':} - include grafana::validator - grafana_plugin { 'grafana-simple-json-datasource': } - EOS - apply_manifest(pp, catch_failures: true) - apply_manifest(pp, catch_changes: true) - end +supported_versions.each do |grafana_version| + describe "grafana_plugin with Grafana version #{grafana_version}" do + context 'create plugin resource' do + it 'runs successfully' do + pp = <<-EOS + class { 'grafana': + version => "#{grafana_version}" + } + include grafana::validator + grafana_plugin { 'grafana-simple-json-datasource': } + EOS + prepare_host - it 'has the plugin' do - shell('grafana-cli plugins ls') do |r| - expect(r.stdout).to match(%r{grafana-simple-json-datasource}) + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) end - end - end - context 'create plugin resource with repo' do - it 'runs successfully' do - pp = <<-EOS - class { 'grafana':} - include grafana::validator - grafana_plugin { 'grafana-simple-json-datasource': - ensure => present, - repo => 'https://nexus.company.com/grafana/plugins', - } - EOS - apply_manifest(pp, catch_failures: true) - apply_manifest(pp, catch_changes: true) + it 'has the plugin' do + shell('grafana-cli plugins ls') do |r| + expect(r.stdout).to match(%r{grafana-simple-json-datasource}) + end + end end - it 'has the plugin' do - shell('grafana-cli plugins ls') do |r| - expect(r.stdout).to match(%r{grafana-simple-json-datasource}) + context 'create plugin resource with repo' do + it 'runs successfully' do + pp = <<-EOS + class { 'grafana': + version => "#{grafana_version}" + } + include grafana::validator + grafana_plugin { 'grafana-simple-json-datasource': + ensure => present, + repo => 'https://nexus.company.com/grafana/plugins', + } + EOS + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) end - end - end - context 'create plugin resource with url' do - it 'runs successfully' do - # Reset and reinstall the same plugin by URL - shell('grafana-cli plugins uninstall grafana-simple-json-datasource') - pp = <<-EOS - class { 'grafana':} - include grafana::validator - grafana_plugin { 'grafana-simple-json-datasource': - ensure => 'present', - plugin_url => 'https://grafana.com/api/plugins/grafana-simple-json-datasource/versions/latest/download', - } - EOS - apply_manifest(pp, catch_failures: true) - apply_manifest(pp, catch_changes: true) + it 'has the plugin' do + shell('grafana-cli plugins ls') do |r| + expect(r.stdout).to match(%r{grafana-simple-json-datasource}) + end + end end - it 'has the plugin' do - shell('grafana-cli plugins ls') do |r| - expect(r.stdout).to match(%r{grafana-simple-json-datasource}) + context 'create plugin resource with url' do + it 'runs successfully' do + # Reset and reinstall the same plugin by URL + shell('grafana-cli plugins uninstall grafana-simple-json-datasource') + pp = <<-EOS + class { 'grafana': + version => "#{grafana_version}" + } + include grafana::validator + grafana_plugin { 'grafana-simple-json-datasource': + ensure => 'present', + plugin_url => 'https://grafana.com/api/plugins/grafana-simple-json-datasource/versions/latest/download', + } + EOS + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) end - end - end - context 'destroy plugin resource' do - it 'runs successfully' do - pp = <<-EOS - class { 'grafana':} - include grafana::validator - grafana_plugin { 'grafana-simple-json-datasource': - ensure => absent, - } - EOS - apply_manifest(pp, catch_failures: true) - apply_manifest(pp, catch_changes: true) + it 'has the plugin' do + shell('grafana-cli plugins ls') do |r| + expect(r.stdout).to match(%r{grafana-simple-json-datasource}) + end + end end - it 'does not have the plugin' do - shell('grafana-cli plugins ls') do |r| - expect(r.stdout).not_to match(%r{grafana-simple-json-datasource}) + context 'destroy plugin resource' do + it 'runs successfully' do + pp = <<-EOS + class { 'grafana': + version => "#{grafana_version}" + } + include grafana::validator + grafana_plugin { 'grafana-simple-json-datasource': + ensure => absent, + } + EOS + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) + end + + it 'does not have the plugin' do + shell('grafana-cli plugins ls') do |r| + expect(r.stdout).not_to match(%r{grafana-simple-json-datasource}) + end end end end end diff --git a/spec/acceptance/grafana_team_spec.rb b/spec/acceptance/grafana_team_spec.rb index 9381ae6..e066323 100644 --- a/spec/acceptance/grafana_team_spec.rb +++ b/spec/acceptance/grafana_team_spec.rb @@ -1,208 +1,213 @@ require 'spec_helper_acceptance' -describe 'grafana_team' do - context 'setup grafana server' do - it 'runs successfully' do - pp = <<-EOS - class { 'grafana': - cfg => { - security => { - admin_user => 'admin', - admin_password => 'admin' +supported_versions.each do |grafana_version| + describe "grafana_team wth Grafana version #{grafana_version}" do + 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 - apply_manifest(pp, catch_failures: true) - apply_manifest(pp, catch_changes: true) - end - end + EOS + prepare_host - context 'create team resource on `Main Org.`' do - it 'creates the team' do - pp = <<-EOS - include grafana::validator - grafana_team { 'example-team': - ensure => present, - grafana_url => 'http://localhost:3000', - grafana_user => 'admin', - grafana_password => 'admin', - } - EOS - apply_manifest(pp, catch_failures: true) - apply_manifest(pp, catch_changes: true) + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) + end end - it 'has created the example team' do - shell('curl --user admin:admin http://localhost:3000/api/teams/search?name=example-team') do |f| - expect(f.stdout).to match(%r{example-team}) + context 'create team resource on `Main Org.`' do + it 'creates the team' do + pp = <<-EOS + include grafana::validator + grafana_team { 'example-team': + ensure => present, + grafana_url => 'http://localhost:3000', + grafana_user => 'admin', + grafana_password => 'admin', + } + EOS + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) end - end - it 'has set default home dashboard' do - shell('curl --user admin:admin http://localhost:3000/api/teams/1/preferences') do |f| - data = JSON.parse(f.stdout) - expect(data).to include('homeDashboardId' => 0) + it 'has created the example team' do + shell('curl --user admin:admin http://localhost:3000/api/teams/search?name=example-team') do |f| + expect(f.stdout).to match(%r{example-team}) + end end - end - end - context 'updates team resource' do - it 'creates dashboard and sets team home dashboard' do - pp = <<-EOS - include grafana::validator - grafana_dashboard { 'example-dashboard': - ensure => present, - grafana_url => 'http://localhost:3000', - grafana_user => 'admin', - grafana_password => 'admin', - content => '{"uid": "zyx986bc"}', - } - grafana_folder { 'example-folder': - ensure => present, - uid => 'example-folder', - grafana_url => 'http://localhost:3000', - grafana_user => 'admin', - grafana_password => 'admin', - } - -> grafana_dashboard { 'example-dashboard2': - ensure => present, - grafana_url => 'http://localhost:3000', - grafana_user => 'admin', - grafana_password => 'admin', - content => '{"uid": "niew0ahN"}', - folder => 'example-folder', - } - grafana_team { 'example-team': - ensure => present, - grafana_url => 'http://localhost:3000', - grafana_user => 'admin', - grafana_password => 'admin', - home_dashboard => 'example-dashboard', - } - grafana_team { 'example-team2': - ensure => present, - grafana_url => 'http://localhost:3000', - grafana_user => 'admin', - grafana_password => 'admin', - home_dashboard_folder => 'example-folder', - home_dashboard => 'example-dashboard2', - } - EOS - apply_manifest(pp, catch_failures: true) - apply_manifest(pp, catch_changes: true) + it 'has set default home dashboard' do + shell('curl --user admin:admin http://localhost:3000/api/teams/1/preferences') do |f| + data = JSON.parse(f.stdout) + expect(data).to include('homeDashboardId' => 0) + end + end end - it 'has updated the example team home dashboard' do - shell('curl --user admin:admin http://localhost:3000/api/teams/1/preferences') do |f| - data = JSON.parse(f.stdout) - expect(data['homeDashboardId']).not_to eq(0) + context 'updates team resource' do + it 'creates dashboard and sets team home dashboard' do + pp = <<-EOS + include grafana::validator + grafana_dashboard { 'example-dashboard': + ensure => present, + grafana_url => 'http://localhost:3000', + grafana_user => 'admin', + grafana_password => 'admin', + content => '{"description": "example dashboard"}', + } + grafana_folder { 'example-folder': + ensure => present, + uid => 'example-folder', + grafana_url => 'http://localhost:3000', + grafana_user => 'admin', + grafana_password => 'admin', + } + -> grafana_dashboard { 'example-dashboard2': + ensure => present, + grafana_url => 'http://localhost:3000', + grafana_user => 'admin', + grafana_password => 'admin', + content => '{"description": "example dashboard2"}', + folder => 'example-folder', + } + grafana_team { 'example-team': + ensure => present, + grafana_url => 'http://localhost:3000', + grafana_user => 'admin', + grafana_password => 'admin', + home_dashboard => 'example-dashboard', + } + grafana_team { 'example-team2': + ensure => present, + grafana_url => 'http://localhost:3000', + grafana_user => 'admin', + grafana_password => 'admin', + home_dashboard_folder => 'example-folder', + home_dashboard => 'example-dashboard2', + } + EOS + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) end - end - it 'has updated the example team home dashboard with folder' do - shell('curl --user admin:admin http://localhost:3000/api/teams/2/preferences') do |f| - data = JSON.parse(f.stdout) - expect(data['homeDashboardId']).not_to eq(0) + it 'has updated the example team home dashboard' do + shell('curl --user admin:admin http://localhost:3000/api/teams/1/preferences') do |f| + data = JSON.parse(f.stdout) + expect(data['homeDashboardId']).not_to eq(0) + end end - end - end - context 'create team resource on seperate organization' do - it 'creates organization and team' do - pp = <<-EOS - include grafana::validator - grafana_organization { 'example-organization': - ensure => present, - grafana_url => 'http://localhost:3000', - grafana_user => 'admin', - grafana_password => 'admin', - } - grafana_team { 'example-team-on-org': - ensure => present, - grafana_url => 'http://localhost:3000', - grafana_user => 'admin', - grafana_password => 'admin', - organization => 'example-organization', - } - EOS - apply_manifest(pp, catch_failures: true) - apply_manifest(pp, catch_changes: true) + it 'has updated the example team home dashboard with folder' do + shell('curl --user admin:admin http://localhost:3000/api/teams/2/preferences') do |f| + data = JSON.parse(f.stdout) + expect(data['homeDashboardId']).not_to eq(0) + end + end end - it 'creates team on organization' do - shell('curl --user admin:admin -X POST http://localhost:3000/api/user/using/2 && '\ + context 'create team resource on seperate organization' do + it 'creates organization and team' do + pp = <<-EOS + include grafana::validator + grafana_organization { 'example-organization': + ensure => present, + grafana_url => 'http://localhost:3000', + grafana_user => 'admin', + grafana_password => 'admin', + } + grafana_team { 'example-team-on-org': + ensure => present, + grafana_url => 'http://localhost:3000', + grafana_user => 'admin', + grafana_password => 'admin', + organization => 'example-organization', + } + EOS + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) + end + + it 'creates team on organization' do + shell('curl --user admin:admin -X POST http://localhost:3000/api/user/using/2 && '\ 'curl --user admin:admin http://localhost:3000/api/teams/search?name=example-team-on-org') do |f| - expect(f.stdout).to match(%r{example-team-on-org}) + expect(f.stdout).to match(%r{example-team-on-org}) + end end end - end - context 'destroy resources' do - it 'destroys the teams, dashboard, and organization' do - pp = <<-EOS - include grafana::validator - grafana_team { 'example-team': - ensure => absent, - grafana_url => 'http://localhost:3000', - grafana_user => 'admin', - grafana_password => 'admin', - } - grafana_team { 'example-team2': - ensure => absent, - grafana_url => 'http://localhost:3000', - grafana_user => 'admin', - grafana_password => 'admin', - } - grafana_team { 'example-team-on-org': - ensure => absent, - grafana_url => 'http://localhost:3000', - grafana_user => 'admin', - grafana_password => 'admin', - organization => 'example-organization', - } - grafana_dashboard { 'example-dashboard': - ensure => absent, - grafana_url => 'http://localhost:3000', - grafana_user => 'admin', - grafana_password => 'admin', - } - grafana_dashboard { 'example-dashboard2': - ensure => absent, - grafana_url => 'http://localhost:3000', - grafana_user => 'admin', - grafana_password => 'admin', - } - grafana_folder { 'example-folder': - ensure => absent, - uid => 'example-folder', - grafana_url => 'http://localhost:3000', - grafana_user => 'admin', - grafana_password => 'admin', - } - grafana_organization { 'example-organization': - ensure => absent, - grafana_url => 'http://localhost:3000', - grafana_user => 'admin', - grafana_password => 'admin', - } - EOS - apply_manifest(pp, catch_failures: true) - apply_manifest(pp, catch_changes: true) - end + context 'destroy resources' do + it 'destroys the teams, dashboard, and organization' do + pp = <<-EOS + include grafana::validator + grafana_team { 'example-team': + ensure => absent, + grafana_url => 'http://localhost:3000', + grafana_user => 'admin', + grafana_password => 'admin', + } + grafana_team { 'example-team2': + ensure => absent, + grafana_url => 'http://localhost:3000', + grafana_user => 'admin', + grafana_password => 'admin', + } + grafana_team { 'example-team-on-org': + ensure => absent, + grafana_url => 'http://localhost:3000', + grafana_user => 'admin', + grafana_password => 'admin', + organization => 'example-organization', + } + grafana_dashboard { 'example-dashboard': + ensure => absent, + grafana_url => 'http://localhost:3000', + grafana_user => 'admin', + grafana_password => 'admin', + } + grafana_dashboard { 'example-dashboard2': + ensure => absent, + grafana_url => 'http://localhost:3000', + grafana_user => 'admin', + grafana_password => 'admin', + } + grafana_folder { 'example-folder': + ensure => absent, + uid => 'example-folder', + grafana_url => 'http://localhost:3000', + grafana_user => 'admin', + grafana_password => 'admin', + } + grafana_organization { 'example-organization': + ensure => absent, + grafana_url => 'http://localhost:3000', + grafana_user => 'admin', + grafana_password => 'admin', + } + EOS + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) + end - it 'has no example-team' do - shell('curl --user admin:admin -X POST http://localhost:3000/api/user/using/1 && '\ + it 'has no example-team' do + shell('curl --user admin:admin -X POST http://localhost:3000/api/user/using/1 && '\ 'curl --user admin:admin http://localhost:3000/api/teams/search') do |f| - expect(f.stdout).not_to match(%r{example-team}) + expect(f.stdout).not_to match(%r{example-team}) + end end - end - it 'has no example-team-on-org' do - shell('curl --user admin:admin -X POST http://localhost:3000/api/user/using/2 && '\ + it 'has no example-team-on-org' do + shell('curl --user admin:admin -X POST http://localhost:3000/api/user/using/2 && '\ 'curl --user admin:admin http://localhost:3000/api/teams') do |f| - expect(f.stdout).not_to match(%r{example-team-on-org}) + expect(f.stdout).not_to match(%r{example-team-on-org}) + end end end end end diff --git a/spec/acceptance/grafana_user_spec.rb b/spec/acceptance/grafana_user_spec.rb index 73a142a..a094e34 100644 --- a/spec/acceptance/grafana_user_spec.rb +++ b/spec/acceptance/grafana_user_spec.rb @@ -1,35 +1,40 @@ require 'spec_helper_acceptance' -describe 'grafana_user' do - context 'setup grafana server' do - it 'runs successfully' do - pp = <<-EOS - class { 'grafana': - cfg => { - security => { - admin_user => 'admin', - admin_password => 'admin' +supported_versions.each do |grafana_version| + describe "grafana_user 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 'runs successfully' do + pp = <<-EOS + grafana_user { 'user1': + grafana_url => 'http://localhost:3000', + grafana_user => 'admin', + grafana_password => 'admin', + full_name => 'John Doe', + password => 'Us3r5ecret', + email => 'john@example.com', } EOS apply_manifest(pp, catch_failures: true) apply_manifest(pp, catch_changes: true) end end - it 'runs successfully' do - pp = <<-EOS - - grafana_user { 'user1': - grafana_url => 'http://localhost:3000', - grafana_user => 'admin', - grafana_password => 'admin', - full_name => 'John Doe', - password => 'Us3r5ecret', - email => 'john@example.com', - } - EOS - apply_manifest(pp, catch_failures: true) - apply_manifest(pp, catch_changes: true) - end end diff --git a/spec/support/acceptance/prepare_host.rb b/spec/support/acceptance/prepare_host.rb new file mode 100644 index 0000000..996f5ae --- /dev/null +++ b/spec/support/acceptance/prepare_host.rb @@ -0,0 +1,8 @@ +def prepare_host + cleanup_script = <<-SHELL + /opt/puppetlabs/bin/puppet resource package grafana ensure=purged + rm -rf /var/lib/grafana/ + SHELL + + shell(cleanup_script) +end diff --git a/spec/support/acceptance/supported_versions.rb b/spec/support/acceptance/supported_versions.rb new file mode 100644 index 0000000..71c754d --- /dev/null +++ b/spec/support/acceptance/supported_versions.rb @@ -0,0 +1,3 @@ +def supported_versions + %w[6.0.0 7.0.0 8.0.0] +end