diff --git a/manifests/config.pp b/manifests/config.pp index 3aca983..c146000 100644 --- a/manifests/config.pp +++ b/manifests/config.pp @@ -1,164 +1,164 @@ # == Class grafana::config # # This class is called from grafana # class grafana::config { case $grafana::install_method { 'docker': { if $grafana::container_cfg { $cfg = $grafana::cfg $myprovision = false file { 'grafana.ini': ensure => file, path => $grafana::cfg_location, content => template('grafana/config.ini.erb'), owner => 'grafana', group => 'grafana', notify => Class['grafana::service'], } } } 'package','repo': { $cfg = $grafana::cfg $myprovision = true file { 'grafana.ini': ensure => file, path => $grafana::cfg_location, content => template('grafana/config.ini.erb'), owner => 'grafana', group => 'grafana', notify => Class['grafana::service'], } $sysconfig = $grafana::sysconfig $sysconfig_location = $grafana::sysconfig_location if $sysconfig_location and $sysconfig { $changes = $sysconfig.map |$key, $value| { "set ${key} ${value}" } augeas{'sysconfig/grafana-server': context => "/files${$sysconfig_location}", changes => $changes, notify => Class['grafana::service'], } } file { "${grafana::data_dir}/plugins": ensure => directory, owner => 'grafana', group => 'grafana', mode => '0750', } } 'archive': { $cfg = $grafana::cfg $myprovision = true file { "${grafana::install_dir}/conf/custom.ini": ensure => file, content => template('grafana/config.ini.erb'), owner => 'grafana', group => 'grafana', notify => Class['grafana::service'], } file { [$grafana::data_dir, "${grafana::data_dir}/plugins"]: ensure => directory, owner => 'grafana', group => 'grafana', mode => '0750', } } default: { fail("Installation method ${grafana::install_method} not supported") } } if $grafana::ldap_cfg { if $grafana::ldap_cfg =~ Array { $ldap_cfg_ary = $grafana::ldap_cfg } else { $ldap_cfg_ary = [$grafana::ldap_cfg] } $template_body = [ "<% scope['ldap_cfg_ary'].each do |v| %>", "<%= require 'toml'; TOML::Generator.new(v).body %>\n", - '<% end %>' + '<% end %>', ] $ldap_cfg_toml = inline_template($template_body.join('')) file { '/etc/grafana/ldap.toml': ensure => file, content => $ldap_cfg_toml, owner => 'grafana', group => 'grafana', notify => Class['grafana::service'], } } # If grafana version is > 5.0.0, and the install method is package, # repo, or archive, then use the provisioning feature. Dashboards # and datasources are placed in # /etc/grafana/provisioning/[dashboards|datasources] by default. # --dashboards-- if ((versioncmp($grafana::version, '5.0.0') >= 0) and ($myprovision)) { $pdashboards = $grafana::provisioning_dashboards if (length($pdashboards) >= 1 ) { $dashboardpaths = flatten(grafana::deep_find_and_remove('options', $pdashboards)) # template uses: # - pdashboards file { $grafana::provisioning_dashboards_file: ensure => file, owner => 'grafana', group => 'grafana', mode => '0640', content => epp('grafana/pdashboards.yaml.epp'), notify => Class['grafana::service'], } # Loop over all providers, extract the paths and create # directories for each path of dashboards. $dashboardpaths.each | Integer $index, Hash $options | { if ('path' in $options) { # get sub paths of 'path' and create subdirs if necessary $subpaths = grafana::get_sub_paths($options['path']) if ($grafana::create_subdirs_provisioning and (length($subpaths) >= 1)) { file { $subpaths : ensure => directory, before => File[$options['path']], } } file { $options['path'] : ensure => directory, owner => 'grafana', group => 'grafana', mode => '0750', recurse => true, purge => true, source => $options['puppetsource'], } } } } # --datasources-- $pdatasources = $grafana::provisioning_datasources if (length($pdatasources) >= 1) { # template uses: # - pdatasources file { $grafana::provisioning_datasources_file: ensure => file, owner => 'grafana', group => 'grafana', mode => '0640', content => epp('grafana/pdatasources.yaml.epp'), notify => Class['grafana::service'], } } } } diff --git a/spec/classes/grafana_spec.rb b/spec/classes/grafana_spec.rb index b05e955..2b53905 100644 --- a/spec/classes/grafana_spec.rb +++ b/spec/classes/grafana_spec.rb @@ -1,343 +1,404 @@ require 'spec_helper' describe 'grafana' do on_supported_os.each do |os, facts| context "on #{os}" do let(:facts) do facts end context 'with default values' do it { is_expected.to compile.with_all_deps } it { is_expected.to contain_class('grafana') } it { is_expected.to contain_class('grafana::install').that_comes_before('Class[grafana::config]') } it { is_expected.to contain_class('grafana::config').that_notifies('Class[grafana::service]') } it { is_expected.to contain_class('grafana::service') } end context 'with parameter install_method is set to package' do let(:params) do { install_method: 'package', version: '5.4.2' } end case facts[:osfamily] when 'Debian' download_location = '/tmp/grafana.deb' describe 'use archive to fetch the package to a temporary location' do it do is_expected.to contain_archive('/tmp/grafana.deb').with_source( 'https://dl.grafana.com/oss/release/grafana_5.4.2_amd64.deb' ) end it { is_expected.to contain_archive('/tmp/grafana.deb').that_comes_before('Package[grafana]') } end describe 'install dependencies first' do it { is_expected.to contain_package('libfontconfig1').with_ensure('present').that_comes_before('Package[grafana]') } end describe 'install the package' do it { is_expected.to contain_package('grafana').with_provider('dpkg') } it { is_expected.to contain_package('grafana').with_source(download_location) } end when 'RedHat' describe 'install dependencies first' do it { is_expected.to contain_package('fontconfig').with_ensure('present').that_comes_before('Package[grafana]') } end describe 'install the package' do it { is_expected.to contain_package('grafana').with_provider('rpm') } end end end context 'with some plugins passed in' do let(:params) do { plugins: { 'grafana-wizzle' => { 'ensure' => 'present' }, 'grafana-woozle' => { 'ensure' => 'absent' }, 'grafana-plugin' => { 'ensure' => 'present', 'repo' => 'https://nexus.company.com/grafana/plugins' } } } end it { is_expected.to contain_grafana_plugin('grafana-wizzle').with(ensure: 'present') } it { is_expected.to contain_grafana_plugin('grafana-woozle').with(ensure: 'absent').that_notifies('Class[grafana::service]') } describe 'install plugin with pluginurl' do it { is_expected.to contain_grafana_plugin('grafana-plugin').with(ensure: 'present', repo: 'https://nexus.company.com/grafana/plugins') } end end context 'with parameter install_method is set to repo' do let(:params) do { install_method: 'repo' } end case facts[:osfamily] when 'Debian' describe 'install apt repo dependencies first' do it { is_expected.to contain_class('apt') } it { is_expected.to contain_apt__source('grafana').with(release: 'stable', repos: 'main', location: 'https://packages.grafana.com/oss/deb') } it { is_expected.to contain_apt__source('grafana').that_comes_before('Package[grafana]') } end describe 'install dependencies first' do it { is_expected.to contain_package('libfontconfig1').with_ensure('present').that_comes_before('Package[grafana]') } end describe 'install the package' do it { is_expected.to contain_package('grafana').with_ensure('installed') } end when 'RedHat' describe 'yum repo dependencies first' do it { is_expected.to contain_yumrepo('grafana-stable').with(baseurl: 'https://packages.grafana.com/oss/rpm', gpgkey: 'https://packages.grafana.com/gpg.key', enabled: 1) } it { is_expected.to contain_yumrepo('grafana-stable').that_comes_before('Package[grafana]') } end describe 'install dependencies first' do it { is_expected.to contain_package('fontconfig').with_ensure('present').that_comes_before('Package[grafana]') } end describe 'install the package' do it { is_expected.to contain_package('grafana').with_ensure('installed') } end end end context 'with parameter install_method is set to repo and manage_package_repo is set to false' do let(:params) do { install_method: 'repo', manage_package_repo: false, version: 'present' } end case facts[:osfamily] when 'Debian' describe 'install dependencies first' do it { is_expected.to contain_package('libfontconfig1').with_ensure('present').that_comes_before('Package[grafana]') } end describe 'install the package' do it { is_expected.to contain_package('grafana').with_ensure('present') } end when 'RedHat' describe 'install dependencies first' do it { is_expected.to contain_package('fontconfig').with_ensure('present').that_comes_before('Package[grafana]') } end describe 'install the package' do it { is_expected.to contain_package('grafana').with_ensure('present') } end when 'Archlinux' describe 'install the package' do it { is_expected.to contain_package('grafana').with_ensure('present') } end end end context 'with parameter install_method is set to archive' do let(:params) do { install_method: 'archive', version: '5.4.2' } end install_dir = '/usr/share/grafana' service_config = '/usr/share/grafana/conf/custom.ini' archive_source = 'https://dl.grafana.com/oss/release/grafana-5.4.2.linux-amd64.tar.gz' describe 'extract archive to install_dir' do it { is_expected.to contain_archive('/tmp/grafana.tar.gz').with_ensure('present') } it { is_expected.to contain_archive('/tmp/grafana.tar.gz').with_source(archive_source) } it { is_expected.to contain_archive('/tmp/grafana.tar.gz').with_extract_path(install_dir) } end describe 'create grafana user' do it { is_expected.to contain_user('grafana').with_ensure('present').with_home(install_dir) } it { is_expected.to contain_user('grafana').that_comes_before('File[/usr/share/grafana]') } end case facts[:osfamily] when 'Archlinux' describe 'create data_dir' do it { is_expected.to contain_file('/var/lib/grafana').with_ensure('directory') } end when 'Debian' describe 'create data_dir' do it { is_expected.to contain_file('/var/lib/grafana').with_ensure('directory') } end when 'FreBSD' describe 'create data_dir' do it { is_expected.to contain_file('/var/db/grafana').with_ensure('directory') } end when 'RedHat' describe 'create data_dir' do it { is_expected.to contain_file('/var/lib/grafana').with_ensure('directory') } end end describe 'manage install_dir' do it { is_expected.to contain_file(install_dir).with_ensure('directory') } it { is_expected.to contain_file(install_dir).with_group('grafana').with_owner('grafana') } end describe 'configure grafana' do it { is_expected.to contain_file(service_config).with_ensure('file') } end describe 'run grafana as service' do it { is_expected.to contain_service('grafana').with_ensure('running').with_provider('base') } it { is_expected.to contain_service('grafana').with_hasrestart(false).with_hasstatus(false) } end context 'when user already defined' do let(:pre_condition) do 'user{"grafana": ensure => present, }' end describe 'do NOT create grafana user' do it { is_expected.not_to contain_user('grafana').with_ensure('present').with_home(install_dir) } end end context 'when service already defined' do let(:pre_condition) do 'service{"grafana": ensure => running, name => "grafana-server", hasrestart => true, hasstatus => true, }' end describe 'do NOT run service' do it { is_expected.not_to contain_service('grafana').with_hasrestart(false).with_hasstatus(false) } end end end context 'invalid parameters' do context 'cfg' do describe 'should not raise an error when cfg parameter is a hash' do let(:params) do { cfg: {} } end it { is_expected.to contain_package('grafana') } end end end context 'configuration file' do describe 'should not contain any configuration when cfg param is empty' do it { is_expected.to contain_file('grafana.ini').with_content("# This file is managed by Puppet, any changes will be overwritten\n\n") } end describe 'should correctly transform cfg param entries to Grafana configuration' do let(:params) do { cfg: { 'app_mode' => 'production', 'section' => { 'string' => 'production', 'number' => 8080, 'boolean' => false, 'empty' => '' } }, ldap_cfg: { 'servers' => [ { 'host' => 'server1', 'use_ssl' => true, 'search_filter' => '(sAMAccountName=%s)', - 'search_base_dns' => ['dc=domain1,dc=com'] }, - { 'host' => 'server2', - 'use_ssl' => true, - 'search_filter' => '(sAMAccountName=%s)', - 'search_base_dns' => ['dc=domain2,dc=com'] } + 'search_base_dns' => ['dc=domain1,dc=com'] } ], 'servers.attributes' => { 'name' => 'givenName', 'surname' => 'sn', 'username' => 'sAMAccountName', 'member_of' => 'memberOf', 'email' => 'email' } } } end expected = "# This file is managed by Puppet, any changes will be overwritten\n\n"\ "app_mode = production\n\n"\ "[section]\n"\ "boolean = false\n"\ "empty = \n"\ "number = 8080\n"\ "string = production\n" it { is_expected.to contain_file('grafana.ini').with_content(expected) } ldap_expected = "\n[[servers]]\n"\ "host = \"server1\"\n"\ "search_base_dns = [\"dc=domain1,dc=com\"]\n"\ "search_filter = \"(sAMAccountName=%s)\"\n"\ "use_ssl = true\n"\ "\n"\ - "[[servers]]\n"\ - "host = \"server2\"\n"\ + "[servers.attributes]\n"\ + "email = \"email\"\n"\ + "member_of = \"memberOf\"\n"\ + "name = \"givenName\"\n"\ + "surname = \"sn\"\n"\ + "username = \"sAMAccountName\"\n"\ + "\n" + + it { is_expected.to contain_file('/etc/grafana/ldap.toml').with_content(ldap_expected) } + end + end + + context 'multiple ldap configuration' do + describe 'should correctly transform ldap config param into Grafana ldap.toml' do + let(:params) do + { + cfg: {}, + ldap_cfg: [ + { + 'servers' => [ + { 'host' => 'server1a server1b', + 'use_ssl' => true, + 'search_filter' => '(sAMAccountName=%s)', + 'search_base_dns' => ['dc=domain1,dc=com'] } + ], + 'servers.attributes' => { + 'name' => 'givenName', + 'surname' => 'sn', + 'username' => 'sAMAccountName', + 'member_of' => 'memberOf', + 'email' => 'email' + } + }, + { + 'servers' => [ + { 'host' => 'server2a server2b', + 'use_ssl' => true, + 'search_filter' => '(sAMAccountName=%s)', + 'search_base_dns' => ['dc=domain2,dc=com'] } + ], + 'servers.attributes' => { + 'name' => 'givenName', + 'surname' => 'sn', + 'username' => 'sAMAccountName', + 'member_of' => 'memberOf', + 'email' => 'email' + } + } + ] + } + end + + ldap_expected = "\n[[servers]]\n"\ + "host = \"server1a server1b\"\n"\ + "search_base_dns = [\"dc=domain1,dc=com\"]\n"\ + "search_filter = \"(sAMAccountName=%s)\"\n"\ + "use_ssl = true\n"\ + "\n"\ + "[servers.attributes]\n"\ + "email = \"email\"\n"\ + "member_of = \"memberOf\"\n"\ + "name = \"givenName\"\n"\ + "surname = \"sn\"\n"\ + "username = \"sAMAccountName\"\n"\ + "\n"\ + "\n[[servers]]\n"\ + "host = \"server2a server2b\"\n"\ "search_base_dns = [\"dc=domain2,dc=com\"]\n"\ "search_filter = \"(sAMAccountName=%s)\"\n"\ "use_ssl = true\n"\ "\n"\ "[servers.attributes]\n"\ "email = \"email\"\n"\ "member_of = \"memberOf\"\n"\ "name = \"givenName\"\n"\ "surname = \"sn\"\n"\ "username = \"sAMAccountName\"\n"\ "\n" it { is_expected.to contain_file('/etc/grafana/ldap.toml').with_content(ldap_expected) } end end context 'sysconfig environment variables' do let(:params) do { install_method: 'repo', sysconfig: { http_proxy: 'http://proxy.example.com/' } } end case facts[:osfamily] when 'Debian' describe 'Add the environment variable to the config file' do it { is_expected.to contain_augeas('sysconfig/grafana-server').with_context('/files/etc/default/grafana-server') } it { is_expected.to contain_augeas('sysconfig/grafana-server').with_changes(['set http_proxy http://proxy.example.com/']) } end when 'RedHat' describe 'Add the environment variable to the config file' do it { is_expected.to contain_augeas('sysconfig/grafana-server').with_context('/files/etc/sysconfig/grafana-server') } it { is_expected.to contain_augeas('sysconfig/grafana-server').with_changes(['set http_proxy http://proxy.example.com/']) } end end end end end end