diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index be66bda..55b4ed0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,83 +1,82 @@ This module has grown over time based on a range of contributions from people using it. If you follow these contributing guidelines your patch will likely make it into a release a little quicker. ## Contributing 1. Fork the repo. 2. Run the tests. We only take pull requests with passing tests, and it's great to know that you have a clean slate 3. Add a test for your change. Only refactoring and documentation changes require no new tests. If you are adding functionality or fixing a bug, please add a test. 4. Make the test pass. 5. Push to your fork and submit a pull request. ## Dependencies The testing and development tools have a bunch of dependencies, all managed by [bundler](http://bundler.io/) according to the [Puppet support matrix](http://docs.puppetlabs.com/guides/platforms.html#ruby-versions). By default the tests use a baseline version of Puppet. If you have Ruby 2.x or want a specific version of Puppet, you must set an environment variable such as: export PUPPET_VERSION="~> 3.2.0" Install the dependencies like so... bundle install ## Syntax and style The test suite will run [Puppet Lint](http://puppet-lint.com/) and [Puppet Syntax](https://github.com/gds-operations/puppet-syntax) to check various syntax and style things. You can run these locally with: bundle exec rake lint bundle exec rake syntax ## Running the unit tests The unit test suite covers most of the code, as mentioned above please add tests if you're adding new functionality. If you've not used [rspec-puppet](http://rspec-puppet.com/) before then feel free to ask about how best to test your new feature. Running the test suite is done with: bundle exec rake spec Note also you can run the syntax, style and unit tests in one go with: bundle exec rake test ## Integration tests The unit tests just check the code runs, not that it does exactly what we want on a real machine. For that we're using [beaker](https://github.com/puppetlabs/beaker). This fires up a new virtual machine (using vagrant) and runs a series of simple tests against it after applying the module. You can run this with: bundle exec rake acceptance This will run the tests on an Ubuntu 12.04 virtual machine. You can also run the integration tests against Centos 6.5 with. - RS_SET=centos-64-x64 bundle exec rake acceptances + RS_SET=centos-64-x64 bundle exec rake acceptance If you don't want to have to recreate the virtual machine every time you can use `BEAKER_DESTROY=no` and `BEAKER_PROVISION=no`. On the first run you will at least need `BEAKER_PROVISION` set to yes (the default). The Vagrantfile for the created virtual machines will be in `.vagrant/beaker_vagrant_fies`. - diff --git a/manifests/install.pp b/manifests/install.pp index 3ebbd2d..c92c6d0 100644 --- a/manifests/install.pp +++ b/manifests/install.pp @@ -1,168 +1,168 @@ # == Class grafana::install # class grafana::install { $base_url = 'https://s3-us-west-2.amazonaws.com/grafana-releases/release' if $::grafana::archive_source != undef { $real_archive_source = $::grafana::archive_source } else { $real_archive_source = "${base_url}/grafana-${::grafana::version}.linux-x64.tar.gz" } if $::grafana::package_source != undef { $real_package_source = $::grafana::package_source } else { $real_package_source = $::osfamily ? { /(RedHat|Amazon)/ => "${base_url}/grafana-${::grafana::version}-${::grafana::rpm_iteration}.x86_64.rpm", 'Debian' => "${base_url}/builds/grafana_${::grafana::version}_amd64.deb", default => $real_archive_source, } } case $::grafana::install_method { 'docker': { docker::image { 'grafana/grafana': image_tag => $::grafana::version, require => Class['docker'], } } 'package': { case $facts['os']['family'] { 'Debian': { package { 'libfontconfig1': ensure => present, } archive { '/tmp/grafana.deb': source => $real_package_source, } package { $::grafana::package_name: ensure => present, provider => 'dpkg', source => '/tmp/grafana.deb', require => [Archive['/tmp/grafana.deb'],Package['libfontconfig1']], } } 'RedHat': { package { 'fontconfig': ensure => present, } package { $::grafana::package_name: ensure => present, provider => 'rpm', source => $real_package_source, require => Package['fontconfig'], } } default: { fail("${facts['os']['family']} not supported") } } } 'repo': { case $facts['os']['family'] { 'Debian': { package { 'libfontconfig1': ensure => present, } if ( $::grafana::manage_package_repo ){ if !defined( Class['apt'] ) { class { '::apt': } } apt::source { 'grafana': - location => "https://packagecloud.io/grafana/${::grafana::repo_name}/debian", - release => 'stretch', + location => 'https://packages.grafana.com/oss/deb', + release => $grafana::repo_name, repos => 'main', key => { - 'id' => '418A7F2FB0E1E6E7EABF6FE8C2E73424D59097AB', - 'source' => 'https://packagecloud.io/gpg.key', + 'id' => '4E40DDF6D76E284A4A6780E48C8C34C524098CB6', + 'source' => 'https://packages.grafana.com/gpg.key', }, before => Package[$::grafana::package_name], } Class['apt::update'] -> Package[$::grafana::package_name] } package { $::grafana::package_name: ensure => $::grafana::version, require => Package['libfontconfig1'], } } 'RedHat': { package { 'fontconfig': ensure => present, } if ( $::grafana::manage_package_repo ){ yumrepo { 'grafana': descr => 'grafana repo', - baseurl => "https://packagecloud.io/grafana/${::grafana::repo_name}/el/${::operatingsystemmajrelease}/\$basearch", + baseurl => 'https://packages.grafana.com/oss/rpm', gpgcheck => 1, - gpgkey => 'https://packagecloud.io/gpg.key https://grafanarel.s3.amazonaws.com/RPM-GPG-KEY-grafana', + gpgkey => 'https://packages.grafana.com/gpg.key', enabled => 1, before => Package[$::grafana::package_name], } } if $::grafana::version =~ /(installed|latest|present)/ { $real_version = $::grafana::version } else { $real_version = "${::grafana::version}-${::grafana::rpm_iteration}" } package { $::grafana::package_name: ensure => $real_version, require => Package['fontconfig'], } } 'Archlinux': { if $::grafana::manage_package_repo { fail('manage_package_repo is not supported on Archlinux') } package { $::grafana::package_name: ensure => 'present', # pacman provider doesn't have feature versionable } } default: { fail("${::operatingsystem} not supported") } } } 'archive': { # create log directory /var/log/grafana (or parameterize) if !defined(User['grafana']){ user { 'grafana': ensure => present, home => $::grafana::install_dir, } } file { $::grafana::install_dir: ensure => directory, group => 'grafana', owner => 'grafana', require => User['grafana'], } archive { '/tmp/grafana.tar.gz': ensure => present, extract => true, extract_command => 'tar xfz %s --strip-components=1', extract_path => $::grafana::install_dir, source => $real_archive_source, user => 'grafana', group => 'grafana', cleanup => true, require => File[$::grafana::install_dir], } } default: { fail("Installation method ${::grafana::install_method} not supported") } } } diff --git a/spec/classes/grafana_spec.rb b/spec/classes/grafana_spec.rb index 5fa6040..ae8ad36 100644 --- a/spec/classes/grafana_spec.rb +++ b/spec/classes/grafana_spec.rb @@ -1,347 +1,347 @@ require 'spec_helper' describe 'grafana' do on_supported_os.each do |os, facts| context "on #{os}" do let(:facts) do facts end let :service_name do case facts[:osfamily] when 'Archlinux' 'grafana' else 'grafana-server' end end let :config_path do case facts[:osfamily] when 'Archlinux' '/etc/grafana.ini' else '/etc/grafana/grafana.ini' end 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::params') } 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: '4.5.1' } 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://s3-us-west-2.amazonaws.com/grafana-releases/release/builds/grafana_4.5.1_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: 'stretch', repos: 'main', location: 'https://packagecloud.io/grafana/stable/debian') } + 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').with(baseurl: 'https://packagecloud.io/grafana/stable/el/' + facts[:operatingsystemmajrelease] + '/$basearch', gpgkey: 'https://packagecloud.io/gpg.key https://grafanarel.s3.amazonaws.com/RPM-GPG-KEY-grafana', enabled: 1) } + it { is_expected.to contain_yumrepo('grafana').with(baseurl: 'https://packages.grafana.com/oss/rpm', gpgkey: 'https://packages.grafana.com/gpg.key', enabled: 1) } it { is_expected.to contain_yumrepo('grafana').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: '4.5.1' } end install_dir = '/usr/share/grafana' service_config = '/usr/share/grafana/conf/custom.ini' archive_source = 'https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-4.5.1.linux-x64.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 describe 'create data_dir' do it { is_expected.to contain_file('/var/lib/grafana').with_ensure('directory') } 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(service_name).with_ensure('running').with_provider('base') } it { is_expected.to contain_service(service_name).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-server": ensure => running, hasrestart => true, hasstatus => true, }' end # let(:params) {{ :service_name => 'grafana-server'}} describe 'do NOT run service' do it { is_expected.not_to contain_service('grafana-server').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(config_path).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'] } ], '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(config_path).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"\ "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