diff --git a/manifests/server.pp b/manifests/server.pp index e9d2bf4..2f2fe15 100644 --- a/manifests/server.pp +++ b/manifests/server.pp @@ -1,88 +1,111 @@ # This installs a PostgreSQL server. See README.md for more details. class postgresql::server ( $postgres_password = undef, $package_name = $postgresql::params::server_package_name, $package_ensure = $postgresql::params::package_ensure, $plperl_package_name = $postgresql::params::plperl_package_name, $plpython_package_name = $postgresql::params::plpython_package_name, $service_ensure = $postgresql::params::service_ensure, $service_enable = $postgresql::params::service_enable, $service_manage = $postgresql::params::service_manage, $service_name = $postgresql::params::service_name, $service_restart_on_change = $postgresql::params::service_restart_on_change, $service_provider = $postgresql::params::service_provider, $service_reload = $postgresql::params::service_reload, $service_status = $postgresql::params::service_status, $default_database = $postgresql::params::default_database, $default_connect_settings = $postgresql::globals::default_connect_settings, $listen_addresses = $postgresql::params::listen_addresses, $port = $postgresql::params::port, $ip_mask_deny_postgres_user = $postgresql::params::ip_mask_deny_postgres_user, $ip_mask_allow_all_users = $postgresql::params::ip_mask_allow_all_users, $ipv4acls = $postgresql::params::ipv4acls, $ipv6acls = $postgresql::params::ipv6acls, $initdb_path = $postgresql::params::initdb_path, $createdb_path = $postgresql::params::createdb_path, $psql_path = $postgresql::params::psql_path, $pg_hba_conf_path = $postgresql::params::pg_hba_conf_path, $pg_ident_conf_path = $postgresql::params::pg_ident_conf_path, $postgresql_conf_path = $postgresql::params::postgresql_conf_path, $recovery_conf_path = $postgresql::params::recovery_conf_path, $datadir = $postgresql::params::datadir, $xlogdir = $postgresql::params::xlogdir, $logdir = $postgresql::params::logdir, $log_line_prefix = $postgresql::params::log_line_prefix, $pg_hba_conf_defaults = $postgresql::params::pg_hba_conf_defaults, $user = $postgresql::params::user, $group = $postgresql::params::group, $needs_initdb = $postgresql::params::needs_initdb, $encoding = $postgresql::params::encoding, $locale = $postgresql::params::locale, $data_checksums = $postgresql::params::data_checksums, $timezone = $postgresql::params::timezone, $manage_pg_hba_conf = $postgresql::params::manage_pg_hba_conf, $manage_pg_ident_conf = $postgresql::params::manage_pg_ident_conf, $manage_recovery_conf = $postgresql::params::manage_recovery_conf, $module_workdir = $postgresql::params::module_workdir, + + Hash[String, Hash] $roles = {}, + Hash[String, Any] $config_entries = {}, + Hash[String, Hash] $pg_hba_rules = {}, + #Deprecated $version = undef, ) inherits postgresql::params { $pg = 'postgresql::server' if $version != undef { warning('Passing "version" to postgresql::server is deprecated; please use postgresql::globals instead.') $_version = $version } else { $_version = $postgresql::params::version } if $createdb_path != undef{ warning('Passing "createdb_path" to postgresql::server is deprecated, it can be removed safely for the same behaviour') } # Reload has its own ordering, specified by other defines class { "${pg}::reload": require => Class["${pg}::install"] } contain postgresql::server::install contain postgresql::server::initdb contain postgresql::server::config contain postgresql::server::service contain postgresql::server::passwd Class['postgresql::server::install'] -> Class['postgresql::server::initdb'] -> Class['postgresql::server::config'] -> Class['postgresql::server::service'] -> Class['postgresql::server::passwd'] + + $roles.each |$rolename, $role| { + postgresql::server::role { $rolename: + * => $role, + } + } + + $config_entries.each |$entry, $value| { + postgresql::server::config_entry { $entry: + value => $value, + } + } + + $pg_hba_rules.each |$rule_name, $rule| { + postgresql::server::pg_hba_rule { $rule_name: + * => $rule, + } + } } diff --git a/spec/acceptance/overridden_settings_spec.rb b/spec/acceptance/overridden_settings_spec.rb new file mode 100644 index 0000000..b956bf1 --- /dev/null +++ b/spec/acceptance/overridden_settings_spec.rb @@ -0,0 +1,53 @@ +require 'spec_helper_acceptance' + +# These tests are designed to ensure that the module, when ran overrides, +# sets up everything correctly and allows us to connect to Postgres. +describe 'postgresql::server', unless: UNSUPPORTED_PLATFORMS.include?(fact('osfamily')) do + pp = <<-MANIFEST + class { 'postgresql::server': + roles => { + 'testusername' => { + password_hash => postgresql_password('testusername', 'supersecret'), + createdb => true, + }, + }, + config_entries => { + max_connections => 200, + }, + pg_hba_rules => { + 'from_remote_host' => { + type => 'host', + database => 'mydb', + user => 'myuser', + auth_method => 'md5', + address => '192.0.2.100/32', + }, + }, + } + + postgresql::server::database { 'testusername': + owner => 'testusername', + } + MANIFEST + + it 'with additional hiera entries' do + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) + end + + describe port(5432) do + it { is_expected.to be_listening } + end + + it 'can connect with psql' do + psql('--command="\l" postgres', 'postgres') do |r| + expect(r.stdout).to match(%r{List of databases}) + end + end + + it 'can connect with psql as testusername' do + shell('PGPASSWORD=supersecret psql -U testusername -h localhost --command="\l"') do |r| + expect(r.stdout).to match(%r{List of databases}) + end + end +end diff --git a/spec/unit/classes/server_spec.rb b/spec/unit/classes/server_spec.rb index 02d5a95..0667567 100644 --- a/spec/unit/classes/server_spec.rb +++ b/spec/unit/classes/server_spec.rb @@ -1,166 +1,220 @@ require 'spec_helper' describe 'postgresql::server', type: :class do let :facts do { os: { family: 'Debian', name: 'Debian', release: { full: '6.0', major: '6', }, }, osfamily: 'Debian', operatingsystem: 'Debian', lsbdistid: 'Debian', lsbdistcodename: 'jessie', operatingsystemrelease: '8.0', concat_basedir: tmpfilename('server'), kernel: 'Linux', id: 'root', path: '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', } end describe 'with no parameters' do it { is_expected.to contain_class('postgresql::params') } it { is_expected.to contain_class('postgresql::server') } it { is_expected.to contain_exec('postgresql_reload').with('command' => 'service postgresql reload') } it 'validates connection' do is_expected.to contain_postgresql_conn_validator('validate_service_is_running') end end describe 'service_ensure => running' do let(:params) do { service_ensure: 'running', postgres_password: 'new-p@s$word-to-set', } end it { is_expected.to contain_class('postgresql::params') } it { is_expected.to contain_class('postgresql::server') } it { is_expected.to contain_class('postgresql::server::passwd') } it 'validates connection' do is_expected.to contain_postgresql_conn_validator('validate_service_is_running') end it 'sets postgres password' do is_expected.to contain_exec('set_postgres_postgrespw').with('command' => '/usr/bin/psql -c "ALTER ROLE \"postgres\" PASSWORD ${NEWPASSWD_ESCAPED}"', 'user' => 'postgres', 'environment' => ['PGPASSWORD=new-p@s$word-to-set', 'PGPORT=5432', 'NEWPASSWD_ESCAPED=$$new-p@s$word-to-set$$'], 'unless' => "/usr/bin/psql -h localhost -p 5432 -c 'select 1' > /dev/null") end end describe 'service_ensure => stopped' do let(:params) { { service_ensure: 'stopped' } } it { is_expected.to contain_class('postgresql::params') } it { is_expected.to contain_class('postgresql::server') } it 'shouldnt validate connection' do is_expected.not_to contain_postgresql_conn_validator('validate_service_is_running') end end describe 'service_restart_on_change => false' do let(:params) { { service_restart_on_change: false } } it { is_expected.to contain_class('postgresql::params') } it { is_expected.to contain_class('postgresql::server') } it { is_expected.not_to contain_Postgresql_conf('data_directory').that_notifies('Class[postgresql::server::service]') } it 'validates connection' do is_expected.to contain_postgresql_conn_validator('validate_service_is_running') end end describe 'service_restart_on_change => true' do let(:params) { { service_restart_on_change: true } } it { is_expected.to contain_class('postgresql::params') } it { is_expected.to contain_class('postgresql::server') } it { is_expected.to contain_Postgresql_conf('data_directory').that_notifies('Class[postgresql::server::service]') } it 'validates connection' do is_expected.to contain_postgresql_conn_validator('validate_service_is_running') end end describe 'service_reload => /bin/true' do let(:params) { { service_reload: '/bin/true' } } it { is_expected.to contain_class('postgresql::params') } it { is_expected.to contain_class('postgresql::server') } it { is_expected.to contain_exec('postgresql_reload').with('command' => '/bin/true') } it 'validates connection' do is_expected.to contain_postgresql_conn_validator('validate_service_is_running') end end describe 'service_manage => true' do let(:params) { { service_manage: true } } it { is_expected.to contain_service('postgresqld') } end describe 'service_manage => false' do let(:params) { { service_manage: false } } it { is_expected.not_to contain_service('postgresqld') } it 'shouldnt validate connection' do is_expected.not_to contain_postgresql_conn_validator('validate_service_is_running') end end describe 'package_ensure => absent' do let(:params) do { package_ensure: 'absent', } end it 'removes the package' do is_expected.to contain_package('postgresql-server').with(ensure: 'purged') end it 'stills enable the service' do is_expected.to contain_service('postgresqld').with(ensure: 'running') end end describe 'needs_initdb => true' do let(:params) do { needs_initdb: true, } end it 'contains proper initdb exec' do is_expected.to contain_exec('postgresql_initdb') end end describe 'postgresql_version' do let(:pre_condition) do <<-EOS class { 'postgresql::globals': manage_package_repo => true, version => '99.5', before => Class['postgresql::server'], } EOS end it 'contains the correct package version' do is_expected.to contain_class('postgresql::repo').with_version('99.5') end end + + describe 'additional roles' do + let(:params) do + { + roles: { + username: { createdb: true }, + }, + } + end + + it { is_expected.to compile.with_all_deps } + it { is_expected.to contain_postgresql__server__role('username').with_createdb(true) } + end + + describe 'additional config_entries' do + let(:params) do + { + config_entries: { + fsync: 'off', + checkpoint_segments: '20', + }, + } + end + + it { is_expected.to compile.with_all_deps } + it { is_expected.to contain_postgresql__server__config_entry('fsync').with_value('off') } + it { is_expected.to contain_postgresql__server__config_entry('checkpoint_segments').with_value('20') } + end + + describe 'additional pg_hba_rules' do + let(:params) do + { + pg_hba_rules: { + from_remote_host: { + type: 'host', + database: 'mydb', + user: 'myuser', + auth_method: 'md5', + address: '192.0.2.100', + }, + }, + } + end + + it { is_expected.to compile.with_all_deps } + it do + is_expected.to contain_postgresql__server__pg_hba_rule('from_remote_host') + .with_type('host') + .with_database('mydb') + .with_user('myuser') + .with_auth_method('md5') + .with_address('192.0.2.100') + end + end end