├── cookbooks ├── postgresql │ ├── .envrc │ ├── .gitattributes │ ├── .mdlrc │ ├── .github │ │ ├── CODEOWNERS │ │ ├── lock.yml │ │ └── workflows │ │ │ └── ci.yml │ ├── templates │ │ ├── pgsql.sysconfig.erb │ │ ├── postgresql.service.erb │ │ ├── postgresql.conf.erb │ │ ├── pg_hba.conf.erb │ │ ├── createcluster.conf.erb │ │ └── pg_ident.conf.erb │ ├── test │ │ ├── cookbooks │ │ │ └── test │ │ │ │ ├── recipes │ │ │ │ ├── repository.rb │ │ │ │ ├── initdb_locale.rb │ │ │ │ ├── client_install.rb │ │ │ │ ├── server_install.rb │ │ │ │ ├── extension.rb │ │ │ │ ├── access.rb │ │ │ │ └── ident.rb │ │ │ │ ├── metadata.rb │ │ │ │ └── templates │ │ │ │ └── default │ │ │ │ └── pg_hba.conf.erb │ │ └── integration │ │ │ ├── extension │ │ │ ├── inspec.yml │ │ │ └── controls │ │ │ │ └── extension_spec.rb │ │ │ ├── client_install │ │ │ ├── inspec.yml │ │ │ └── controls │ │ │ │ └── client_spec.rb │ │ │ ├── access │ │ │ ├── inspec.yml │ │ │ └── controls │ │ │ │ └── base_access.rb │ │ │ ├── repo │ │ │ ├── inspec.yml │ │ │ └── controls │ │ │ │ └── repo_spec.rb.rb │ │ │ ├── ident │ │ │ ├── inspec.yml │ │ │ └── controls │ │ │ │ └── ident_map.rb │ │ │ ├── initdb_locale │ │ │ ├── inspec.yml │ │ │ └── controls │ │ │ │ └── default_spec.rb │ │ │ └── server_install │ │ │ ├── inspec.yml │ │ │ └── controls │ │ │ └── server_spec.rb │ ├── .delivery │ │ └── project.toml │ ├── CODE_OF_CONDUCT.md │ ├── TESTING.md │ ├── Berksfile │ ├── .circleci │ │ └── config.yml │ ├── CONTRIBUTING.md │ ├── .editorconfig │ ├── spec │ │ ├── spec_helper.rb │ │ └── libraries │ │ │ └── helpers_spec.rb │ ├── .overcommit.yml │ ├── metadata.rb │ ├── .gitignore │ ├── UPGRADING.md │ ├── kitchen.yml │ ├── kitchen.dokken.yml │ ├── resources │ │ ├── client_install.rb │ │ ├── extension.rb │ │ ├── ident.rb │ │ ├── access.rb │ │ ├── server_conf.rb │ │ ├── database.rb │ │ ├── user.rb │ │ ├── server_install.rb │ │ └── repository.rb │ ├── Dangerfile │ ├── chefignore │ ├── CHANGELOG.md │ ├── libraries │ │ └── helpers.rb │ ├── LICENSE │ └── README.md └── vagrant-postgresql │ ├── metadata.rb │ └── recipes │ └── default.rb ├── .gitignore ├── config.sample.yaml ├── script └── database ├── Vagrantfile └── README.md /cookbooks/postgresql/.envrc: -------------------------------------------------------------------------------- 1 | use chefworkstation 2 | -------------------------------------------------------------------------------- /cookbooks/postgresql/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /cookbooks/postgresql/.mdlrc: -------------------------------------------------------------------------------- 1 | rules "~MD013", "~MD024" 2 | -------------------------------------------------------------------------------- /cookbooks/postgresql/.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @sous-chefs/postgresql 2 | -------------------------------------------------------------------------------- /cookbooks/postgresql/templates/pgsql.sysconfig.erb: -------------------------------------------------------------------------------- 1 | PGDATA=<%= @postgresql_dir %> 2 | PGPORT=<%= @port %> 3 | -------------------------------------------------------------------------------- /cookbooks/postgresql/test/cookbooks/test/recipes/repository.rb: -------------------------------------------------------------------------------- 1 | postgresql_repository 'pg repo' do 2 | version '9.5' 3 | end 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # This directory is workspace specific 2 | .vagrant 3 | 4 | # Shouldn't ever commit your custom config.yaml 5 | config.yaml 6 | -------------------------------------------------------------------------------- /cookbooks/postgresql/.delivery/project.toml: -------------------------------------------------------------------------------- 1 | remote_file = "https://raw.githubusercontent.com/chef-cookbooks/community_cookbook_tools/master/delivery/project.toml" 2 | -------------------------------------------------------------------------------- /cookbooks/postgresql/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Community Guidelines 2 | 3 | This project follows the Chef Community Guidelines 4 | -------------------------------------------------------------------------------- /cookbooks/postgresql/test/cookbooks/test/recipes/initdb_locale.rb: -------------------------------------------------------------------------------- 1 | postgresql_server_install 'Install' do 2 | version '10' 3 | initdb_locale 'en_GB.utf8' 4 | action [:install, :create] 5 | end 6 | -------------------------------------------------------------------------------- /cookbooks/postgresql/test/cookbooks/test/recipes/client_install.rb: -------------------------------------------------------------------------------- 1 | # This resource should install the postgresql client 2 | postgresql_client_install 'postgresql client' do 3 | version '9.5' 4 | end 5 | -------------------------------------------------------------------------------- /cookbooks/postgresql/TESTING.md: -------------------------------------------------------------------------------- 1 | # Testing 2 | 3 | Please refer to [the community cookbook documentation on testing](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/TESTING.MD). 4 | -------------------------------------------------------------------------------- /cookbooks/postgresql/Berksfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | source 'https://supermarket.chef.io' 3 | 4 | metadata 5 | 6 | group :integration do 7 | cookbook 'test', path: './test/cookbooks/test' 8 | end 9 | -------------------------------------------------------------------------------- /cookbooks/postgresql/templates/postgresql.service.erb: -------------------------------------------------------------------------------- 1 | [Service] 2 | .include /usr/lib/systemd/system/<%= @svc_name %>.service 3 | 4 | Environment= 5 | Environment=PGPORT=<%= @port %> 6 | Environment=PGDATA=<%= @data_dir %> 7 | -------------------------------------------------------------------------------- /cookbooks/postgresql/.circleci/config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 2.1 3 | orbs: 4 | kitchen: sous-chefs/kitchen@2 5 | workflows: 6 | danger: 7 | jobs: 8 | - kitchen/danger: 9 | name: danger 10 | context: Danger-Minimal 11 | -------------------------------------------------------------------------------- /cookbooks/postgresql/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Please refer to 4 | [https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) 5 | -------------------------------------------------------------------------------- /cookbooks/postgresql/.editorconfig: -------------------------------------------------------------------------------- 1 | #https://EditorConfig.org 2 | # top-most EditorConfig file 3 | root=true 4 | 5 | [*] 6 | end_of_line = lf 7 | insert_final_newline = true 8 | indent_style = space 9 | indent_size = 2 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | -------------------------------------------------------------------------------- /cookbooks/postgresql/.github/lock.yml: -------------------------------------------------------------------------------- 1 | --- 2 | daysUntilLock: 365 3 | exemptLabels: [] 4 | lockLabel: false 5 | lockComment: > 6 | This thread has been automatically locked since there has not been 7 | any recent activity after it was closed. Please open a new issue for 8 | related bugs. 9 | -------------------------------------------------------------------------------- /cookbooks/postgresql/test/cookbooks/test/metadata.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | name 'test' 3 | maintainer 'Sous Chefs' 4 | maintainer_email 'help@sous-chefs.org' 5 | license 'Apache-2.0' 6 | description 'Installs/Configures test' 7 | version '0.1.0' 8 | 9 | depends 'postgresql' 10 | -------------------------------------------------------------------------------- /cookbooks/vagrant-postgresql/metadata.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | name 'vagrant-postgresql' 3 | maintainer 'Scott Muc' 4 | maintainer_email 'scottmuc@gmail.com' 5 | license 'Apache-2.0' 6 | description 'Calls resources of the postgresql cookbook' 7 | version '0.0.1' 8 | 9 | depends 'postgresql' 10 | -------------------------------------------------------------------------------- /cookbooks/postgresql/test/integration/extension/inspec.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: extension 3 | title: PostgreSQL extension tests 4 | maintainer: Sous Chefs 5 | copyright_email: help@sous-chefs.org 6 | license: Apache 7 | summary: Check that extensions are installed 8 | version: 0.0.1 9 | supports: 10 | - os-family: unix 11 | -------------------------------------------------------------------------------- /cookbooks/postgresql/test/integration/client_install/inspec.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: client 3 | title: PostgreSQL client integration tests 4 | maintainer: Sous Chefs 5 | copyright_email: help@sous-chefs.org 6 | license: Apache 7 | summary: Check that the client is installed and working 8 | version: 0.0.1 9 | supports: 10 | - os-family: unix 11 | -------------------------------------------------------------------------------- /cookbooks/postgresql/test/integration/access/inspec.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: access 3 | title: PostgreSQL HBA Access integration tests 4 | maintainer: Aaron Kalin 5 | copyright_email: aaron.kalin@dnsimple.com 6 | license: Apache 7 | summary: Check that proper access is provided in the pg_hba conf 8 | version: 0.0.1 9 | supports: 10 | - os-family: unix 11 | -------------------------------------------------------------------------------- /cookbooks/postgresql/test/integration/repo/inspec.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: client 3 | title: PostgreSQL repository integration tests 4 | maintainer: Dan Webb 5 | copyright_email: dan.webb@damacus.io 6 | license: Apache 7 | summary: Check that repostories are enabled and we can download a package 8 | version: 0.0.1 9 | supports: 10 | - os-family: unix 11 | -------------------------------------------------------------------------------- /cookbooks/postgresql/test/integration/ident/inspec.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: ident 3 | title: PostgreSQL Ident Map integration tests 4 | maintainer: Aaron Kalin 5 | copyright_email: aaron.kalin@dnsimple.com 6 | license: Apache 7 | summary: Check that proper access maps are provided in the pg_ident conf 8 | version: 0.0.1 9 | supports: 10 | - os-family: unix 11 | -------------------------------------------------------------------------------- /cookbooks/postgresql/test/integration/initdb_locale/inspec.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: initdb_locale 3 | title: PostgreSQL server 4 | maintainer: Sous Chefs 5 | copyright_email: help@sous-chefs.org 6 | license: Apache 7 | summary: Verify the locale is set correctly when we pass in a non-default locale 8 | version: 0.0.1 9 | supports: 10 | - os-family: unix 11 | -------------------------------------------------------------------------------- /cookbooks/postgresql/spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | require 'chefspec' 3 | require 'chefspec/berkshelf' 4 | 5 | RSpec.configure do |config| 6 | config.color = true # Use color in STDOUT 7 | config.formatter = :documentation # Use the specified formatter 8 | config.log_level = :error # Avoid deprecation notice SPAM 9 | end 10 | -------------------------------------------------------------------------------- /cookbooks/postgresql/test/integration/client_install/controls/client_spec.rb: -------------------------------------------------------------------------------- 1 | control 'postgresql-client-install' do 2 | impact 1.0 3 | desc 'These tests ensure a postgresql client installed correctly' 4 | 5 | describe command('/usr/bin/psql -V') do 6 | its('stdout') { should match(/psql \(PostgreSQL\) [0-9.]+/) } 7 | its('exit_status') { should eq 0 } 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /cookbooks/postgresql/test/integration/server_install/inspec.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: server 3 | title: PostgreSQL server 4 | maintainer: Sous Chefs 5 | copyright_email: help@sous-chefs.org 6 | license: Apache 7 | summary: Verify the correct installation of the postgresql server 8 | version: 0.0.1 9 | supports: 10 | - os-family: unix 11 | depends: 12 | - name: client 13 | path: ./test/integration/client_install 14 | -------------------------------------------------------------------------------- /config.sample.yaml: -------------------------------------------------------------------------------- 1 | version: 1 2 | 3 | postgresql: 4 | version: 9.3 5 | password: 6 | postgres: password 7 | config: 8 | listen_addresses: '*' 9 | pg_hba: 10 | - 11 | type: 'host' 12 | db: 'all' 13 | user: 'all' 14 | addr: '0.0.0.0/0' 15 | method: 'md5' 16 | - 17 | type: 'host' 18 | db: 'all' 19 | user: 'all' 20 | addr: '::1/0' 21 | method: 'md5' 22 | 23 | -------------------------------------------------------------------------------- /script/database: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | COMMAND=$1 4 | 5 | function main() { 6 | case "$COMMAND" in 7 | up) up 8 | ;; 9 | down) down 10 | ;; 11 | destroy) destroy 12 | ;; 13 | *) echo "invalid command: script/database up|down|destroy" 14 | ;; 15 | esac 16 | } 17 | 18 | function up() { 19 | vagrant up 20 | } 21 | 22 | function down() { 23 | vagrant suspend 24 | } 25 | 26 | function destroy() { 27 | vagrant destroy -f 28 | } 29 | 30 | main 31 | -------------------------------------------------------------------------------- /cookbooks/postgresql/.overcommit.yml: -------------------------------------------------------------------------------- 1 | --- 2 | PreCommit: 3 | TrailingWhitespace: 4 | enabled: true 5 | YamlLint: 6 | enabled: true 7 | Rspec: 8 | enabled: true 9 | required_executable: 'rspec' 10 | Cookstyle: 11 | enabled: true 12 | required_executable: 'cookstyle' 13 | command: ["cookstyle"] 14 | Delivery: 15 | enabled: true 16 | required_executable: 'delivery' 17 | flags: ['local', 'all'] 18 | CommitMsg: 19 | HardTabs: 20 | enabled: true 21 | -------------------------------------------------------------------------------- /cookbooks/postgresql/test/integration/server_install/controls/server_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | if os[:family] == 'redhat' || os[:family] == 'fedora' 4 | describe service('postgresql-9.6') do 5 | it { should be_installed } 6 | it { should be_enabled } 7 | it { should be_running } 8 | end 9 | else 10 | describe service('postgresql') do 11 | it { should be_installed } 12 | it { should be_enabled } 13 | it { should be_running } 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /cookbooks/postgresql/test/integration/initdb_locale/controls/default_spec.rb: -------------------------------------------------------------------------------- 1 | control 'postgresql-initdb-locale' do 2 | impact 1.0 3 | desc 'This test ensures the locales are correcly set' 4 | 5 | postgres_access = postgres_session('postgres', '12345', '127.0.0.1') 6 | 7 | describe postgres_access.query('SHOW lc_collate;') do 8 | its('output') { should include 'en_GB.utf8' } 9 | end 10 | 11 | describe postgres_access.query('SHOW lc_messages;') do 12 | its('output') { should include 'en_GB.utf8' } 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /cookbooks/postgresql/test/cookbooks/test/recipes/server_install.rb: -------------------------------------------------------------------------------- 1 | postgresql_repository 'install' 2 | 3 | postgresql_server_install 'package' do 4 | action [:install, :create] 5 | end 6 | 7 | # Using this to generate a service resource to control 8 | find_resource(:service, 'postgresql') do 9 | extend PostgresqlCookbook::Helpers 10 | service_name(lazy { platform_service_name }) 11 | supports restart: true, status: true, reload: true 12 | action [:enable, :start] 13 | end 14 | 15 | postgresql_server_conf 'PostgreSQL Config' do 16 | notifies :reload, 'service[postgresql]' 17 | end 18 | -------------------------------------------------------------------------------- /cookbooks/postgresql/metadata.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | name 'postgresql' 3 | maintainer 'Sous Chefs' 4 | maintainer_email 'help@sous-chefs.org' 5 | license 'Apache-2.0' 6 | description 'Installs and configures postgresql for clients or servers' 7 | version '7.1.9' 8 | source_url 'https://github.com/sous-chefs/postgresql' 9 | issues_url 'https://github.com/sous-chefs/postgresql/issues' 10 | chef_version '>= 13.8' 11 | 12 | %w(ubuntu debian fedora amazon redhat centos scientific oracle).each do |os| 13 | supports os 14 | end 15 | -------------------------------------------------------------------------------- /cookbooks/postgresql/test/cookbooks/test/templates/default/pg_hba.conf.erb: -------------------------------------------------------------------------------- 1 | # This file was automatically generated and dropped off by Chef! 2 | 3 | ########### 4 | # From the postgresql_access resources 5 | ########### 6 | <% @pg_hba.each do |k,v| -%> 7 | # <%= k %> 8 | <% if v[:comment] -%> 9 | # <%= v[:comment] %> 10 | <% end -%> 11 | <% if v[:addr] %> 12 | <%= v[:type].ljust(7) %> <%= v[:db].ljust(15) %> <%= v[:user].ljust(15) %> <%= v[:addr].ljust(23) %> <%= v[:method] %> 13 | <% else %> 14 | <%= v[:type].ljust(7) %> <%= v[:db].ljust(15) %> <%= v[:user].ljust(15) %> <%= v[:method] %> 15 | <% end %> 16 | <% end %> 17 | -------------------------------------------------------------------------------- /cookbooks/postgresql/.gitignore: -------------------------------------------------------------------------------- 1 | *.rbc 2 | .config 3 | coverage 4 | InstalledFiles 5 | lib/bundler/man 6 | pkg 7 | rdoc 8 | spec/reports 9 | test/tmp 10 | test/version_tmp 11 | tmp 12 | _Store 13 | *~ 14 | *# 15 | .#* 16 | \#*# 17 | .*.sw[a-z] 18 | *.un~ 19 | *.tmp 20 | *.bk 21 | *.bkup 22 | 23 | # ruby/bundler files 24 | .ruby-version 25 | .ruby-gemset 26 | .rvmrc 27 | Gemfile.lock 28 | .bundle 29 | *.gem 30 | 31 | # YARD artifacts 32 | .yardoc 33 | _yardoc 34 | doc/ 35 | .idea 36 | 37 | # chef stuff 38 | Berksfile.lock 39 | .kitchen 40 | kitchen.local.yml 41 | vendor/ 42 | .coverage/ 43 | .zero-knife.rb 44 | Policyfile.lock.json 45 | 46 | # vagrant stuff 47 | .vagrant/ 48 | .vagrant.d/ 49 | -------------------------------------------------------------------------------- /cookbooks/postgresql/test/integration/extension/controls/extension_spec.rb: -------------------------------------------------------------------------------- 1 | control 'postgresql-extension' do 2 | impact 1.0 3 | desc 'Check if the "plpgsql" extension was installed successfully' 4 | 5 | postgres_access = postgres_session('postgres', '12345', '127.0.0.1') 6 | 7 | describe postgres_access.query('\dx;', ['test_1']) do 8 | its('output') { should include 'plpgsql' } 9 | end 10 | end 11 | 12 | control 'postgresql-extension-hyphenated' do 13 | impact 1.0 14 | desc 'Check if the "uuid-ossp" extension was installed successfully' 15 | 16 | postgres_access = postgres_session('postgres', '12345', '127.0.0.1') 17 | 18 | describe postgres_access.query('\dx;', ['test_1']) do 19 | its('output') { should include 'ossp' } 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /cookbooks/postgresql/test/integration/ident/controls/ident_map.rb: -------------------------------------------------------------------------------- 1 | control 'postgresql-ident-map' do 2 | impact 1.0 3 | desc 'This test ensures postgres configures ident access correctly' 4 | 5 | describe command("sudo -u shef bash -c \"psql -U sous_chef -d postgres -c 'SELECT 1;'\"") do 6 | its('exit_status') { should eq 0 } 7 | end 8 | end 9 | 10 | control 'shef and postgres roles should exist' do 11 | impact 1.0 12 | desc 'The shef & postgres database user role should exist' 13 | 14 | postgres_access = postgres_session('postgres', '12345', '127.0.0.1') 15 | 16 | describe postgres_access.query('SELECT rolname FROM pg_roles;') do 17 | its('output') { should include 'postgres' } 18 | its('output') { should include 'sous_chef' } 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /cookbooks/postgresql/templates/postgresql.conf.erb: -------------------------------------------------------------------------------- 1 | # PostgreSQL configuration file 2 | # This file was automatically generated and dropped off by chef! 3 | # Please refer to the PostgreSQL documentation for details on 4 | # configuration settings. 5 | 6 | data_directory = '<%= @data_dir %>' 7 | hba_file = '<%= @hba_file %>' 8 | ident_file = '<%= @ident_file %>' 9 | external_pid_file = '<%= @external_pid_file %>' 10 | stats_temp_directory = '<%= @stats_temp_directory %>' 11 | port = <%= @port %> 12 | <% @additional_config.sort.each do |key, value| %> 13 | <% next if value.nil? -%> 14 | <%= key %> = <%= 15 | case value 16 | when String 17 | "'#{value}'" 18 | when TrueClass 19 | 'on' 20 | when FalseClass 21 | 'off' 22 | else 23 | value 24 | end 25 | %> 26 | <% end %> 27 | -------------------------------------------------------------------------------- /cookbooks/postgresql/test/integration/repo/controls/repo_spec.rb.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | case os[:family] 4 | 5 | when 'redhat' 6 | 7 | describe yum.repo('pgdg9.5') do 8 | it { should exist } 9 | it { should be_enabled } 10 | end 11 | 12 | describe yum.repo('pgdg9.5-source') do 13 | it { should exist } 14 | it { should_not be_enabled } 15 | end 16 | 17 | describe yum.repo('pgdg9.5-source-updates-testing') do 18 | it { should exist } 19 | it { should_not be_enabled } 20 | end 21 | 22 | describe yum.repo('pgdg9.5-updates-testing') do 23 | it { should exist } 24 | it { should_not be_enabled } 25 | end 26 | 27 | when 'debian' 28 | 29 | describe apt('https://download.postgresql.org/pub/repos/apt/') do 30 | it { should exist } 31 | it { should be_enabled } 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /cookbooks/postgresql/test/cookbooks/test/recipes/extension.rb: -------------------------------------------------------------------------------- 1 | postgresql_repository 'install' 2 | 3 | # Dokken images don't have all locales available so this is a workaround 4 | locale = value_for_platform( 5 | [:debian, :ubuntu, :fedora] => { default: 'C.UTF-8' }, 6 | centos: { default: 'en_GB.utf-8' }, 7 | default: 'en_US' 8 | ) 9 | 10 | postgresql_server_install 'package' do 11 | password '12345' 12 | action [:install, :create] 13 | initdb_locale locale 14 | initdb_encoding 'UTF-8' 15 | version '9.6' 16 | end 17 | 18 | postgresql_database 'test_1' do 19 | locale locale 20 | end 21 | 22 | if platform_family?('rhel') 23 | package 'postgresql96-contrib' 24 | else 25 | package 'postgresql-contrib' 26 | end 27 | 28 | postgresql_extension 'plpgsql' do 29 | database 'test_1' 30 | end 31 | 32 | postgresql_extension '\"uuid-ossp\"' do 33 | database 'test_1' 34 | end 35 | -------------------------------------------------------------------------------- /cookbooks/postgresql/UPGRADING.md: -------------------------------------------------------------------------------- 1 | # Upgrading from v6.0 2 | 3 | From v7.0.0 of the postgresql cookbook we have removed all recipes and attributes from the cookbook. 4 | 5 | ## Deprecations 6 | 7 | ### Gem 8 | 9 | Due to limitations in the gem compile process (libssl related) we have removed the pg_gem. 10 | 11 | We no longer support accessing the database via the gem, and internally use the cli. 12 | 13 | ### PG Tune 14 | 15 | We currently do not implement the PG Tune functionality. 16 | 17 | This may be added in a future release. 18 | 19 | ## Major Changes 20 | 21 | Recipes are no longer supported so you should take a look at the examples in `test/cookbooks/test/recipes` 22 | 23 | An example of how to 24 | 25 | - Install the the server from the postgresql repository 26 | - Install a database 27 | - Install an extension 28 | 29 | install an extension 30 | 31 | ```ruby 32 | postgresql_repository 'install' 33 | 34 | postgresql_server_install 'package' 35 | 36 | postgresql_database 'test_1' 37 | 38 | postgresql_extension 'openfts' do 39 | database 'test_1' 40 | end 41 | ``` 42 | -------------------------------------------------------------------------------- /cookbooks/postgresql/test/cookbooks/test/recipes/access.rb: -------------------------------------------------------------------------------- 1 | postgresql_server_install 'postgresql' do 2 | password '12345' 3 | port 5432 4 | setup_repo true 5 | action [:install, :create] 6 | end 7 | 8 | postgresql_access 'postgresql host superuser' do 9 | access_type 'host' 10 | access_db 'all' 11 | access_user 'postgres' 12 | access_addr '127.0.0.1/32' 13 | access_method 'md5' 14 | notifies :reload, 'service[postgresql]' 15 | end 16 | 17 | postgresql_user 'sous_chef' do 18 | superuser true 19 | password '67890' 20 | sensitive false 21 | end 22 | 23 | postgresql_access 'a sous_chef local superuser' do 24 | access_type 'host' 25 | access_db 'all' 26 | access_user 'sous_chef' 27 | access_method 'md5' 28 | access_addr '127.0.0.1/32' 29 | notifies :reload, 'service[postgresql]' 30 | end 31 | 32 | postgresql_user 'name-with-dash' do 33 | password '1234' 34 | end 35 | 36 | service 'postgresql' do 37 | extend PostgresqlCookbook::Helpers 38 | service_name lazy { platform_service_name } 39 | supports restart: true, status: true, reload: true 40 | action :nothing 41 | end 42 | -------------------------------------------------------------------------------- /cookbooks/postgresql/kitchen.yml: -------------------------------------------------------------------------------- 1 | --- 2 | driver: 3 | name: vagrant 4 | 5 | provisioner: 6 | name: chef_solo 7 | product_name: chef 8 | product_version: 14.2 9 | enforce_idempotency: true 10 | multiple_converge: 2 11 | solo_rb: 12 | treat_deprecation_warnings_as_errors: true 13 | 14 | verifier: 15 | name: inspec 16 | 17 | platforms: 18 | - name: amazonlinux-2 19 | driver_config: 20 | box: ywatase/amzn2 21 | - name: centos-6 22 | - name: centos-7 23 | - name: debian-9 24 | - name: ubuntu-16.04 25 | - name: ubuntu-18.04 26 | 27 | suites: 28 | - name: repo 29 | run_list: 30 | - recipe[test::repository] 31 | - name: server_install 32 | run_list: 33 | - recipe[test::server_install] 34 | - name: client_install 35 | run_list: 36 | - recipe[test::client_install] 37 | - name: access 38 | run_list: 39 | - recipe[test::access] 40 | - name: ident 41 | run_list: 42 | - recipe[test::ident] 43 | - name: extension 44 | run_list: 45 | - recipe[test::extension] 46 | - name: initdb_locale 47 | run_list: 48 | - recipe[test::initdb_locale] 49 | includes: [centos-7] 50 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | require 'yaml' 4 | require 'fileutils' 5 | 6 | # Vagrantfile API/syntax version. Don't touch unless you know what you're doing! 7 | VAGRANTFILE_API_VERSION = "2" 8 | ROOT_DIR = File.expand_path(File.dirname(__FILE__)) 9 | 10 | def read_user_json 11 | config_path = File.join(ROOT_DIR, 'config.yaml') 12 | sample_config_path = File.join(ROOT_DIR, 'config.sample.yaml') 13 | 14 | unless File.exists? config_path 15 | FileUtils.cp sample_config_path, config_path 16 | end 17 | 18 | YAML.load_file config_path 19 | end 20 | 21 | Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| 22 | config.vm.box = "ubuntu/trusty64" 23 | 24 | config.vm.define "database" do |database| 25 | database.vm.network :forwarded_port, guest: 5432, host: 5432 26 | 27 | database.vm.provision :chef_solo do |chef| 28 | chef.arguments = "--chef-license accept" 29 | chef.cookbooks_path = File.join(File.dirname(__FILE__), 'cookbooks') 30 | chef.add_recipe "vagrant-postgresql::default" 31 | chef.json = read_user_json 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /cookbooks/vagrant-postgresql/recipes/default.rb: -------------------------------------------------------------------------------- 1 | postgresql_repository 'install' 2 | 3 | postgresql_server_install 'package' do 4 | version node['postgresql']['version'].to_s 5 | password node['postgresql']['password']['postgres'] 6 | action [:install, :create] 7 | end 8 | 9 | # Using this to generate a service resource to control 10 | find_resource(:service, 'postgresql') do 11 | extend PostgresqlCookbook::Helpers 12 | service_name(lazy { platform_service_name }) 13 | supports restart: true, status: true, reload: true 14 | action [:enable, :start] 15 | end 16 | 17 | counter = 0 18 | node['postgresql'].fetch('pg_hba', []).each do |access| 19 | counter = counter + 1 20 | comment = access.fetch('comment', "custom access #{counter}") 21 | postgresql_access comment do 22 | comment comment 23 | access_type access.fetch('type') 24 | access_db access.fetch('db') 25 | access_user access.fetch('user') 26 | access_addr access.fetch('addr') 27 | access_method access.fetch('method') 28 | end 29 | end 30 | 31 | postgresql_server_conf 'PostgreSQL Config' do 32 | additional_config node['postgresql']['config'] 33 | notifies :restart, 'service[postgresql]' 34 | end 35 | -------------------------------------------------------------------------------- /cookbooks/postgresql/kitchen.dokken.yml: -------------------------------------------------------------------------------- 1 | --- 2 | driver: 3 | name: dokken 4 | privileged: true # because Docker and SystemD/Upstart 5 | env: [CHEF_LICENSE=accept] 6 | 7 | transport: 8 | name: dokken 9 | 10 | provisioner: 11 | name: dokken 12 | product_name: chef 13 | product_version: <%= ENV['CHEF_VERSION'] || 'latest' %> 14 | install_strategy: once 15 | 16 | platforms: 17 | - name: debian-9 18 | driver: 19 | image: dokken/debian-9 20 | pid_one_command: /bin/systemd 21 | intermediate_instructions: 22 | - RUN /usr/bin/apt-get update 23 | 24 | - name: centos-6 25 | driver: 26 | image: dokken/centos-6 27 | pid_one_command: /sbin/init 28 | 29 | - name: centos-7 30 | driver: 31 | image: dokken/centos-7 32 | pid_one_command: /usr/lib/systemd/systemd 33 | 34 | - name: ubuntu-16.04 35 | driver: 36 | image: dokken/ubuntu-16.04 37 | pid_one_command: /bin/systemd 38 | intermediate_instructions: 39 | - RUN /usr/bin/apt-get update 40 | 41 | - name: ubuntu-18.04 42 | driver: 43 | image: dokken/ubuntu-18.04 44 | pid_one_command: /bin/systemd 45 | intermediate_instructions: 46 | - RUN /usr/bin/apt-get update 47 | -------------------------------------------------------------------------------- /cookbooks/postgresql/resources/client_install.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | # 3 | # Cookbook:: postgresql 4 | # Resource:: client_install 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | property :version, String, default: '9.6' 20 | property :setup_repo, [true, false], default: true 21 | 22 | action :install do 23 | postgresql_repository 'Add downloads.postgresql.org repository' do 24 | version new_resource.version 25 | only_if { new_resource.setup_repo } 26 | end 27 | 28 | case node['platform_family'] 29 | when 'debian' 30 | package "postgresql-client-#{new_resource.version}" 31 | when 'rhel', 'fedora', 'amazon' 32 | ver = new_resource.version.delete('.') 33 | package "postgresql#{ver}" 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /cookbooks/postgresql/templates/pg_hba.conf.erb: -------------------------------------------------------------------------------- 1 | # This file was automatically generated and dropped off by Chef! 2 | 3 | # PostgreSQL Client Authentication Configuration File 4 | # =================================================== 5 | # 6 | # Refer to the "Client Authentication" section in the PostgreSQL 7 | # documentation for a complete description of this file. 8 | 9 | local all postgres peer 10 | 11 | # TYPE DATABASE USER ADDRESS METHOD 12 | 13 | # "local" is for Unix domain socket connections only 14 | local all all peer 15 | # IPv4 local connections: 16 | host all all 127.0.0.1/32 md5 17 | # IPv6 local connections: 18 | host all all ::1/128 md5 19 | 20 | ########### 21 | # From the postgresql_access resources 22 | ########### 23 | <% @pg_hba.each do |k,v| -%> 24 | # <%= k %> 25 | <% if v[:comment] -%> 26 | # <%= v[:comment] %> 27 | <% end -%> 28 | <% if v[:addr] %> 29 | <%= v[:type].ljust(7) %> <%= v[:db].ljust(15) %> <%= v[:user].ljust(15) %> <%= v[:addr].ljust(23) %> <%= v[:method] %> 30 | <% else %> 31 | <%= v[:type].ljust(7) %> <%= v[:db].ljust(15) %> <%= v[:user].ljust(15) %> <%= v[:method] %> 32 | <% end %> 33 | <% end %> 34 | -------------------------------------------------------------------------------- /cookbooks/postgresql/test/cookbooks/test/recipes/ident.rb: -------------------------------------------------------------------------------- 1 | postgresql_server_install 'postgresql' do 2 | password '12345' 3 | port 5432 4 | setup_repo true 5 | action [:install, :create] 6 | end 7 | 8 | user 'shef' 9 | 10 | postgresql_ident 'postgresl mapping' do 11 | mapname 'testmap' 12 | system_user 'postgres' 13 | pg_user 'postgres' 14 | notifies :reload, 'service[postgresql]' 15 | end 16 | 17 | postgresql_ident 'shef mapping' do 18 | mapname 'testmap' 19 | system_user 'shef' 20 | pg_user 'sous_chef' 21 | notifies :reload, 'service[postgresql]' 22 | end 23 | 24 | postgresql_access 'postgresql host superuser' do 25 | access_type 'host' 26 | access_db 'all' 27 | access_user 'postgres' 28 | access_addr '127.0.0.1/32' 29 | access_method 'md5' 30 | notifies :reload, 'service[postgresql]' 31 | end 32 | 33 | postgresql_access 'shef mapping' do 34 | access_type 'local' 35 | access_db 'all' 36 | access_user 'all' 37 | access_method 'peer map=testmap' 38 | cookbook 'test' 39 | notifies :reload, 'service[postgresql]' 40 | end 41 | 42 | postgresql_user 'sous_chef' do 43 | superuser true 44 | password '67890' 45 | sensitive false 46 | end 47 | 48 | service 'postgresql' do 49 | extend PostgresqlCookbook::Helpers 50 | service_name lazy { platform_service_name } 51 | supports restart: true, status: true, reload: true 52 | action :nothing 53 | end 54 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Postgresql database server whenever you need one 2 | 3 | ```diff 4 | - this project is no longer mainained. Docker is probably a better option nowadays 5 | ``` 6 | 7 | ## Dependencies 8 | 9 | You'll need to have the following tools installed for this to work 10 | 11 | * [VirtualBox](https://www.virtualbox.org/wiki/Downloads) 12 | * [Vagrant](http://vagrantup.com/) 13 | 14 | ## Instructions 15 | 16 | This repo contains everything necessary to stand up a local instance of an 17 | ubuntu 14.04 server running postgresql. 18 | 19 | To get the server going execute the following in the directory: 20 | 21 | script/database up 22 | 23 | To shutdown the database server do the following: 24 | 25 | script/database down 26 | 27 | To destroy the database server do the following (this will remove all data): 28 | 29 | script/database destroy 30 | 31 | From a terminal you can also start a shell (given that you have the postgresql 32 | client on your host operating system). 33 | 34 | psql -h localhost -U postgres --password 35 | enter password: password 36 | 37 | ## Customisations 38 | 39 | You'll need to know a little bit about chef, but if you're feeling up for it, 40 | you can tweak `config.yaml`. It's essentially the node attributes that will 41 | be loaded by chef when performing the chef execution. 42 | 43 | ## Troubleshooting 44 | 45 | This vagrant box takes port 5432 so if you have processes listening on those 46 | ports then things might not work. 47 | 48 | -------------------------------------------------------------------------------- /cookbooks/postgresql/templates/createcluster.conf.erb: -------------------------------------------------------------------------------- 1 | # Default values for pg_createcluster(8) 2 | # Occurrences of '%v' are replaced by the major version number, 3 | # and '%c' by the cluster name. Use '%%' for a literal '%'. 4 | 5 | # Create a "main" cluster when a new postgresql-x.y server package is installed 6 | #create_main_cluster = true 7 | 8 | # Default start.conf value, must be one of "auto", "manual", and "disabled". 9 | # See pg_createcluster(8) for more documentation. 10 | #start_conf = 'auto' 11 | 12 | # Default data directory. 13 | #data_directory = '/var/lib/postgresql/%v/%c' 14 | 15 | # Default directory for transaction logs 16 | # Unset by default, i.e. transaction logs remain in the data directory. 17 | #waldir = '/var/lib/postgresql/wal/%v/%c/pg_wal' 18 | 19 | # Options to pass to initdb. 20 | initdb_options = '<%= @initdb_options %>' 21 | 22 | # The following options are copied into the new cluster's postgresql.conf: 23 | 24 | # Enable SSL by default (using the "snakeoil" certificates installed by the 25 | # ssl-cert package, unless configured otherwise here) 26 | ssl = on 27 | 28 | # Show cluster name in process title 29 | cluster_name = '%v/%c' 30 | 31 | # Put stats_temp_directory on tmpfs 32 | stats_temp_directory = '/var/run/postgresql/%v-%c.pg_stat_tmp' 33 | 34 | # Add prefix to log lines 35 | log_line_prefix = '%%m [%%p] %%q%%u@%%d ' 36 | 37 | # Add "include_dir" in postgresql.conf 38 | add_include_dir = 'conf.d' 39 | 40 | # Directory for additional createcluster config 41 | include_dir '/etc/postgresql-common/createcluster.d' 42 | -------------------------------------------------------------------------------- /cookbooks/postgresql/Dangerfile: -------------------------------------------------------------------------------- 1 | # Reference: http://danger.systems/reference.html 2 | 3 | # A pull request summary is required. Add a description of the pull request purpose. 4 | # Changelog must be updated for each pull request that changes code. 5 | # Warnings will be issued for: 6 | # Pull request with more than 400 lines of code changed 7 | # Pull reqest that change more than 5 lines without test changes 8 | # Failures will be issued for: 9 | # Pull request without summary 10 | # Pull requests with code changes without changelog entry 11 | 12 | def code_changes? 13 | code = %w(libraries attributes recipes resources files templates) 14 | code.each do |location| 15 | return true unless git.modified_files.grep(/#{location}/).empty? 16 | end 17 | false 18 | end 19 | 20 | def test_changes? 21 | tests = %w(spec test .kitchen.yml .kitchen.dokken.yml) 22 | tests.each do |location| 23 | return true unless git.modified_files.grep(/#{location}/).empty? 24 | end 25 | false 26 | end 27 | 28 | failure 'Please provide a summary of your Pull Request.' if github.pr_body.length < 10 29 | 30 | warn 'This is a big Pull Request.' if git.lines_of_code > 400 31 | 32 | warn 'This is a Table Flip.' if git.lines_of_code > 2000 33 | 34 | # Require a CHANGELOG entry for non-test changes. 35 | if !git.modified_files.include?('CHANGELOG.md') && code_changes? 36 | failure 'Please include a CHANGELOG entry.' 37 | end 38 | 39 | # A sanity check for tests. 40 | if git.lines_of_code > 5 && code_changes? && !test_changes? 41 | warn 'This Pull Request is probably missing tests.' 42 | end 43 | -------------------------------------------------------------------------------- /cookbooks/postgresql/chefignore: -------------------------------------------------------------------------------- 1 | # Put files/directories that should be ignored in this file when uploading 2 | # to a Chef Infra Server or Supermarket. 3 | # Lines that start with '# ' are comments. 4 | 5 | # OS generated files # 6 | ###################### 7 | .DS_Store 8 | ehthumbs.db 9 | Icon? 10 | nohup.out 11 | Thumbs.db 12 | 13 | # SASS # 14 | ######## 15 | .sass-cache 16 | 17 | # EDITORS # 18 | ########### 19 | .#* 20 | .project 21 | .settings 22 | *_flymake 23 | *_flymake.* 24 | *.bak 25 | *.sw[a-z] 26 | *.tmproj 27 | *~ 28 | \#* 29 | mkmf.log 30 | REVISION 31 | TAGS* 32 | tmtags 33 | 34 | ## COMPILED ## 35 | ############## 36 | *.class 37 | *.com 38 | *.dll 39 | *.exe 40 | *.o 41 | *.pyc 42 | *.so 43 | */rdoc/ 44 | a.out 45 | 46 | # Testing # 47 | ########### 48 | .circleci/* 49 | .codeclimate.yml 50 | .foodcritic 51 | .kitchen* 52 | .rspec 53 | .rubocop.yml 54 | .travis.yml 55 | .watchr 56 | azure-pipelines.yml 57 | examples/* 58 | features/* 59 | Guardfile 60 | kitchen.yml* 61 | Procfile 62 | Rakefile 63 | spec/* 64 | test/* 65 | 66 | # SCM # 67 | ####### 68 | .git 69 | .gitattributes 70 | .gitconfig 71 | .github/* 72 | .gitignore 73 | .gitmodules 74 | .svn 75 | */.bzr/* 76 | */.git 77 | */.hg/* 78 | */.svn/* 79 | 80 | # Berkshelf # 81 | ############# 82 | Berksfile 83 | Berksfile.lock 84 | cookbooks/* 85 | tmp 86 | 87 | # Bundler # 88 | ########### 89 | vendor/* 90 | Gemfile 91 | Gemfile.lock 92 | 93 | # Policyfile # 94 | ############## 95 | Policyfile.rb 96 | Policyfile.lock.json 97 | 98 | # Cookbooks # 99 | ############# 100 | CHANGELOG* 101 | CONTRIBUTING* 102 | TESTING* 103 | CODE_OF_CONDUCT* 104 | 105 | # Vagrant # 106 | ########### 107 | .vagrant 108 | Vagrantfile 109 | -------------------------------------------------------------------------------- /cookbooks/postgresql/resources/extension.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: postgresql 3 | # Resource:: extension 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | property :extension, String, name_property: true 19 | property :old_version, String 20 | property :version, String 21 | 22 | # Connection prefernces 23 | property :user, String, default: 'postgres' 24 | property :database, String, required: true 25 | property :host, [String, nil] 26 | property :port, Integer, default: 5432 27 | 28 | action :create do 29 | bash "CREATE EXTENSION #{new_resource.name}" do 30 | code create_extension_sql(new_resource) 31 | user 'postgres' 32 | action :run 33 | environment(psql_environment) 34 | not_if { follower? || extension_installed?(new_resource) } 35 | end 36 | end 37 | 38 | action :drop do 39 | bash "DROP EXTENSION #{new_resource.name}" do 40 | code psql_command_string(new_resource, "DROP EXTENSION IF EXISTS \"#{new_resource.extension}\"") 41 | user 'postgres' 42 | action :run 43 | environment(psql_environment) 44 | not_if { follower? } 45 | only_if { extension_installed?(new_resource) } 46 | end 47 | end 48 | 49 | action_class do 50 | include PostgresqlCookbook::Helpers 51 | end 52 | -------------------------------------------------------------------------------- /cookbooks/postgresql/resources/ident.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | # 3 | # Cookbook:: postgresql 4 | # Resource:: access 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | property :mapname, String, required: true 20 | property :source, String, default: 'pg_ident.conf.erb' 21 | property :cookbook, String, default: 'postgresql' 22 | property :system_user, String, required: true 23 | property :pg_user, String, required: true 24 | property :comment, String 25 | 26 | action :create do 27 | ident_resource = new_resource 28 | with_run_context :root do 29 | edit_resource(:template, "#{conf_dir}/pg_ident.conf") do |new_resource| 30 | source new_resource.source 31 | cookbook new_resource.cookbook 32 | owner 'postgres' 33 | group 'postgres' 34 | mode '0640' 35 | variables[:pg_ident] ||= {} 36 | variables[:pg_ident][new_resource.name] = { 37 | comment: new_resource.comment, 38 | mapname: new_resource.mapname, 39 | system_user: new_resource.system_user, 40 | pg_user: new_resource.pg_user, 41 | } 42 | action :nothing 43 | delayed_action :create 44 | notifies :trigger, ident_resource, :immediately 45 | end 46 | end 47 | end 48 | 49 | action :trigger do 50 | new_resource.updated_by_last_action(true) 51 | end 52 | 53 | action_class do 54 | include PostgresqlCookbook::Helpers 55 | end 56 | -------------------------------------------------------------------------------- /cookbooks/postgresql/test/integration/access/controls/base_access.rb: -------------------------------------------------------------------------------- 1 | control 'postgresql-local-access' do 2 | impact 1.0 3 | desc 'This test ensures postgres has localhost access to the database' 4 | 5 | describe postgres_hba_conf.where { type == 'host' && user == 'postgres' } do 6 | its('database') { should cmp 'all' } 7 | its('user') { should cmp 'postgres' } 8 | its('auth_method') { should cmp 'md5' } 9 | its('address') { should cmp '127.0.0.1/32' } 10 | end 11 | 12 | postgres_access = postgres_session('postgres', '12345', '127.0.0.1') 13 | 14 | describe postgres_access.query('SELECT 1;') do 15 | its('output') { should eq '1' } 16 | end 17 | end 18 | 19 | control 'postgresql-sous-chef-access' do 20 | impact 1.0 21 | desc 'This test ensures sous_chefs have local trust access to the database' 22 | 23 | describe postgres_hba_conf.where { user == 'sous_chef' } do 24 | its('database') { should cmp 'all' } 25 | its('type') { should cmp 'host' } 26 | its('auth_method') { should cmp 'md5' } 27 | its('address') { should cmp '127.0.0.1/32' } 28 | end 29 | 30 | postgres_access = postgres_session('sous_chef', '67890') 31 | 32 | describe postgres_access.query('SELECT 1;', ['postgres']) do 33 | its('output') { should eq '1' } 34 | end 35 | end 36 | 37 | control 'sous_chef role should exist' do 38 | impact 1.0 39 | desc 'The sous_chef database user role should exist' 40 | 41 | postgres_access = postgres_session('postgres', '12345', '127.0.0.1') 42 | 43 | describe postgres_access.query('SELECT rolname FROM pg_roles;') do 44 | its('output') { should cmp /sous_chef/ } 45 | end 46 | end 47 | 48 | control 'name-with-dash role should exist' do 49 | impact 1.0 50 | desc 'The name-with-dash database user role should exist' 51 | 52 | postgres_access = postgres_session('postgres', '12345', '127.0.0.1') 53 | 54 | describe postgres_access.query('SELECT rolname FROM pg_roles;') do 55 | its('output') { should cmp /name-with-dash/ } 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /cookbooks/postgresql/.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: ci 3 | 4 | on: 5 | pull_request: 6 | push: 7 | branches: 8 | - master 9 | 10 | jobs: 11 | delivery: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Check out code 15 | uses: actions/checkout@master 16 | - name: Run Chef Delivery 17 | uses: actionshub/chef-delivery@master 18 | env: 19 | CHEF_LICENSE: accept-no-persist 20 | 21 | yamllint: 22 | runs-on: ubuntu-latest 23 | steps: 24 | - name: Check out code 25 | uses: actions/checkout@master 26 | - name: Run yaml Lint 27 | uses: actionshub/yamllint@master 28 | 29 | mdl: 30 | runs-on: ubuntu-latest 31 | steps: 32 | - name: Check out code 33 | uses: actions/checkout@master 34 | - name: Run Markdown Lint 35 | uses: actionshub/markdownlint@master 36 | 37 | dokken: 38 | needs: [mdl, yamllint, delivery] 39 | runs-on: ubuntu-latest 40 | strategy: 41 | matrix: 42 | os: 43 | - 'debian-9' 44 | - 'centos-6' 45 | - 'centos-7' 46 | - 'ubuntu-1604' 47 | - 'ubuntu-1804' 48 | suite: 49 | - 'extension' 50 | - 'ident' 51 | - 'access' 52 | - 'client-install' 53 | - 'server-install' 54 | - 'repo' 55 | fail-fast: false 56 | 57 | steps: 58 | - name: Check out code 59 | uses: actions/checkout@master 60 | - name: Install Chef 61 | uses: actionshub/chef-install@master 62 | - name: Dokken 63 | uses: actionshub/kitchen-dokken@master 64 | env: 65 | CHEF_LICENSE: accept-no-persist 66 | KITCHEN_LOCAL_YAML: kitchen.dokken.yml 67 | with: 68 | suite: ${{ matrix.suite }} 69 | os: ${{ matrix.os }} 70 | 71 | final: 72 | needs: [dokken] 73 | runs-on: ubuntu-latest 74 | steps: 75 | - name: Check out code 76 | uses: actions/checkout@master 77 | -------------------------------------------------------------------------------- /cookbooks/postgresql/templates/pg_ident.conf.erb: -------------------------------------------------------------------------------- 1 | # PostgreSQL User Name Maps 2 | # ========================= 3 | # 4 | # Refer to the PostgreSQL documentation, chapter "Client 5 | # Authentication" for a complete description. A short synopsis 6 | # follows. 7 | # 8 | # This file controls PostgreSQL user name mapping. It maps external 9 | # user names to their corresponding PostgreSQL user names. Records 10 | # are of the form: 11 | # 12 | # MAPNAME SYSTEM-USERNAME PG-USERNAME 13 | # 14 | # (The uppercase quantities must be replaced by actual values.) 15 | # 16 | # MAPNAME is the (otherwise freely chosen) map name that was used in 17 | # pg_hba.conf. SYSTEM-USERNAME is the detected user name of the 18 | # client. PG-USERNAME is the requested PostgreSQL user name. The 19 | # existence of a record specifies that SYSTEM-USERNAME may connect as 20 | # PG-USERNAME. 21 | # 22 | # If SYSTEM-USERNAME starts with a slash (/), it will be treated as a 23 | # regular expression. Optionally this can contain a capture (a 24 | # parenthesized subexpression). The substring matching the capture 25 | # will be substituted for \1 (backslash-one) if present in 26 | # PG-USERNAME. 27 | # 28 | # Multiple maps may be specified in this file and used by pg_hba.conf. 29 | # 30 | # No map names are defined in the default configuration. If all 31 | # system user names and PostgreSQL user names are the same, you don't 32 | # need anything in this file. 33 | # 34 | # This file is read on server startup and when the postmaster receives 35 | # a SIGHUP signal. If you edit the file on a running system, you have 36 | # to SIGHUP the postmaster for the changes to take effect. You can 37 | # use "pg_ctl reload" to do that. 38 | 39 | # Put your actual configuration here 40 | # ---------------------------------- 41 | 42 | # MAPNAME SYSTEM-USERNAME PG-USERNAME 43 | <% @pg_ident.each do |k,v| -%> 44 | <% if v[:comment] -%> 45 | 46 | # <%= v[:comment] %> 47 | <% end -%> 48 | <%= v[:mapname].ljust(15) %> <%= v[:system_user].ljust(23) %> <%= v[:pg_user].ljust(15) %> 49 | <% end %> 50 | -------------------------------------------------------------------------------- /cookbooks/postgresql/resources/access.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | # 3 | # Cookbook:: postgresql 4 | # Resource:: access 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | property :access_type, String, default: 'local' 20 | property :access_db, String, default: 'all' 21 | property :access_user, String, default: 'postgres' 22 | property :access_method, String, default: 'ident' 23 | property :cookbook, String, default: 'postgresql' 24 | property :source, String, default: 'pg_hba.conf.erb' 25 | property :access_addr, String 26 | property :comment, String 27 | 28 | action :grant do 29 | config_resource = new_resource 30 | with_run_context :root do 31 | edit_resource(:template, "#{conf_dir}/pg_hba.conf") do |new_resource| 32 | source new_resource.source 33 | cookbook new_resource.cookbook 34 | owner 'postgres' 35 | group 'postgres' 36 | mode '0600' 37 | variables[:pg_hba] ||= {} 38 | variables[:pg_hba][new_resource.name] = { 39 | comment: new_resource.comment, 40 | type: new_resource.access_type, 41 | db: new_resource.access_db, 42 | user: new_resource.access_user, 43 | addr: new_resource.access_addr, 44 | method: new_resource.access_method, 45 | } 46 | action :nothing 47 | delayed_action :create 48 | notifies :trigger, config_resource, :immediately 49 | end 50 | end 51 | end 52 | 53 | action :trigger do 54 | new_resource.updated_by_last_action(true) 55 | end 56 | 57 | action_class do 58 | include PostgresqlCookbook::Helpers 59 | end 60 | -------------------------------------------------------------------------------- /cookbooks/postgresql/resources/server_conf.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | # 3 | # Cookbook:: postgresql 4 | # Resource:: server_conf 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | include PostgresqlCookbook::Helpers 20 | 21 | property :version, String, default: '9.6' 22 | property :data_directory, String, default: lazy { data_dir } 23 | property :hba_file, String, default: lazy { "#{conf_dir}/pg_hba.conf" } 24 | property :ident_file, String, default: lazy { "#{conf_dir}/pg_ident.conf" } 25 | property :external_pid_file, String, default: lazy { "/var/run/postgresql/#{version}-main.pid" } 26 | property :stats_temp_directory, String, default: lazy { "/var/run/postgresql/#{version}-main.pg_stat_tmp" } 27 | property :port, Integer, default: 5432 28 | property :additional_config, Hash, default: {} 29 | property :cookbook, String, default: 'postgresql' 30 | 31 | action :modify do 32 | template "#{conf_dir}/postgresql.conf" do 33 | cookbook new_resource.cookbook 34 | source 'postgresql.conf.erb' 35 | owner 'postgres' 36 | group 'postgres' 37 | mode '0644' 38 | variables( 39 | data_dir: new_resource.data_directory, 40 | hba_file: new_resource.hba_file, 41 | ident_file: new_resource.ident_file, 42 | external_pid_file: new_resource.external_pid_file, 43 | stats_temp_directory: new_resource.stats_temp_directory, 44 | port: new_resource.port, 45 | additional_config: new_resource.additional_config 46 | ) 47 | end 48 | end 49 | 50 | action_class do 51 | include PostgresqlCookbook::Helpers 52 | end 53 | -------------------------------------------------------------------------------- /cookbooks/postgresql/resources/database.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: postgresql 3 | # Resource:: database 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | property :template, String, default: 'template1' 19 | property :encoding, String, default: 'UTF-8' 20 | property :locale, String, default: 'en_US.UTF-8' 21 | property :owner, String 22 | 23 | # Connection prefernces 24 | property :user, String, default: 'postgres' 25 | property :database, String, name_property: true 26 | property :host, String 27 | property :port, Integer, default: 5432 28 | 29 | action :create do 30 | createdb = 'createdb' 31 | createdb << " -E #{new_resource.encoding}" if new_resource.encoding 32 | createdb << " -l #{new_resource.locale}" if new_resource.locale 33 | createdb << " -T #{new_resource.template}" unless new_resource.template.empty? 34 | createdb << " -O #{new_resource.owner}" if new_resource.owner 35 | createdb << " -U #{new_resource.user}" if new_resource.user 36 | createdb << " -h #{new_resource.host}" if new_resource.host 37 | createdb << " -p #{new_resource.port}" if new_resource.port 38 | createdb << " #{new_resource.database}" 39 | 40 | bash "Create Database #{new_resource.database}" do 41 | code createdb 42 | user new_resource.user 43 | not_if { follower? } 44 | not_if { database_exists?(new_resource) } 45 | end 46 | end 47 | 48 | action :drop do 49 | converge_by "Drop PostgreSQL Database #{new_resource.database}" do 50 | dropdb = 'dropdb' 51 | dropdb << " -U #{new_resource.user}" if new_resource.user 52 | dropdb << " --host #{new_resource.host}" if new_resource.host 53 | dropdb << " --port #{new_resource.port}" if new_resource.port 54 | dropdb << " #{new_resource.database}" 55 | 56 | bash "drop postgresql database #{new_resource.database})" do 57 | user 'postgres' 58 | code dropdb 59 | not_if { follower? } 60 | only_if { database_exists?(new_resource) } 61 | end 62 | end 63 | end 64 | 65 | action_class do 66 | include PostgresqlCookbook::Helpers 67 | end 68 | -------------------------------------------------------------------------------- /cookbooks/postgresql/resources/user.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: postgresql 3 | # Resource:: user 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | property :create_user, String, name_property: true 19 | property :superuser, [true, false], default: false 20 | property :createdb, [true, false], default: false 21 | property :createrole, [true, false], default: false 22 | property :inherit, [true, false], default: true 23 | property :replication, [true, false], default: false 24 | property :login, [true, false], default: true 25 | property :password, String 26 | property :encrypted_password, String 27 | property :valid_until, String 28 | property :attributes, Hash, default: {} 29 | 30 | # Connection prefernces 31 | property :user, String, default: 'postgres' 32 | property :database, String 33 | property :host, String 34 | property :port, Integer, default: 5432 35 | 36 | action :create do 37 | Chef::Log.warn('You cannot use "attributes" property with create action.') unless new_resource.attributes.empty? 38 | 39 | execute "create postgresql user #{new_resource.create_user}" do 40 | user 'postgres' 41 | command create_user_sql(new_resource) 42 | sensitive new_resource.sensitive 43 | environment(psql_environment) 44 | not_if { follower? || user_exists?(new_resource) } 45 | end 46 | end 47 | 48 | action :update do 49 | if new_resource.attributes.empty? 50 | execute "update postgresql user #{new_resource.create_user}" do 51 | user 'postgres' 52 | command update_user_sql(new_resource) 53 | environment(psql_environment) 54 | sensitive true 55 | not_if { follower? } 56 | only_if { user_exists?(new_resource) } 57 | end 58 | else 59 | new_resource.attributes.each do |attr, value| 60 | v = if value.is_a?(TrueClass) || value.is_a?(FalseClass) 61 | value.to_s 62 | else 63 | "'#{value}'" 64 | end 65 | 66 | execute "Update postgresql user #{new_resource.create_user} to set #{attr}" do 67 | user 'postgres' 68 | command update_user_with_attributes_sql(new_resource, v) 69 | environment(psql_environment) 70 | sensitive true 71 | not_if { follower? } 72 | only_if { user_exists?(new_resource) } 73 | end 74 | end 75 | end 76 | end 77 | 78 | action :drop do 79 | execute "drop postgresql user #{new_resource.create_user}" do 80 | user 'postgres' 81 | command drop_user_sql(new_resource) 82 | environment(psql_environment) 83 | sensitive true 84 | not_if { follower? } 85 | only_if { user_exists?(new_resource) } 86 | end 87 | end 88 | 89 | action_class do 90 | include PostgresqlCookbook::Helpers 91 | end 92 | -------------------------------------------------------------------------------- /cookbooks/postgresql/resources/server_install.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: postgresql 3 | # Resource:: server_install 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | include PostgresqlCookbook::Helpers 19 | 20 | property :version, String, default: '9.6' 21 | property :setup_repo, [true, false], default: true 22 | property :hba_file, String, default: lazy { "#{conf_dir}/main/pg_hba.conf" } 23 | property :ident_file, String, default: lazy { "#{conf_dir}/main/pg_ident.conf" } 24 | property :external_pid_file, String, default: lazy { "/var/run/postgresql/#{version}-main.pid" } 25 | property :password, [String, nil], default: 'generate' # Set to nil if we do not want to set a password 26 | property :port, Integer, default: 5432 27 | property :initdb_locale, String 28 | property :initdb_encoding, String 29 | 30 | # Connection preferences 31 | property :user, String, default: 'postgres' 32 | property :database, String 33 | property :host, [String, nil] 34 | 35 | action :install do 36 | node.run_state['postgresql'] ||= {} 37 | node.run_state['postgresql']['version'] = new_resource.version 38 | 39 | postgresql_client_install 'Install PostgreSQL Client' do 40 | version new_resource.version 41 | setup_repo new_resource.setup_repo 42 | end 43 | 44 | # First install the postgresql-common package 45 | if platform_family?('debian') 46 | package 'postgresql-common' 47 | 48 | initdb_options = '' 49 | initdb_options << "--locale #{new_resource.initdb_locale}" if new_resource.initdb_locale 50 | initdb_options << " -E #{new_resource.initdb_encoding}" if new_resource.initdb_encoding 51 | 52 | template '/etc/postgresql-common/createcluster.conf' do 53 | source 'createcluster.conf.erb' 54 | cookbook 'postgresql' 55 | variables( 56 | initdb_options: initdb_options 57 | ) 58 | end 59 | end 60 | 61 | package server_pkg_name 62 | end 63 | 64 | action :create do 65 | execute 'init_db' do 66 | command rhel_init_db_command(new_resource) 67 | user new_resource.user 68 | not_if { initialized? } 69 | only_if { platform_family?('rhel', 'fedora', 'amazon') } 70 | end 71 | 72 | # We use to use find_resource here. 73 | # But that required the user to do the same in their recipe. 74 | # This also seemed to never trigger notifications, therefore requiring a log resource 75 | # to notify the enable/start on the service, which always fires (Check v7.0 tag for more) 76 | service 'postgresql' do 77 | service_name platform_service_name 78 | supports restart: true, status: true, reload: true 79 | action [:enable, :start] 80 | end 81 | 82 | # Generate a random password or set it as per new_resource.password. 83 | bash 'generate-postgres-password' do 84 | user 'postgres' 85 | code alter_role_sql(new_resource) 86 | not_if { user_has_password?(new_resource) } 87 | not_if { new_resource.password.nil? } 88 | end 89 | end 90 | 91 | action_class do 92 | include PostgresqlCookbook::Helpers 93 | end 94 | -------------------------------------------------------------------------------- /cookbooks/postgresql/resources/repository.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | # 3 | # Cookbook:: postgresql 4 | # Resource:: repository 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | property :version, String, default: '9.6' 20 | property :enable_pgdg, [true, false], default: true 21 | property :enable_pgdg_source, [true, false], default: false 22 | property :enable_pgdg_updates_testing, [true, false], default: false 23 | property :enable_pgdg_source_updates_testing, [true, false], default: false 24 | property :yum_gpg_key_uri, String, default: 'https://download.postgresql.org/pub/repos/yum/RPM-GPG-KEY-PGDG' 25 | property :apt_gpg_key_uri, String, default: 'https://download.postgresql.org/pub/repos/apt/ACCC4CF8.asc' 26 | 27 | action :add do 28 | case node['platform_family'] 29 | 30 | when 'rhel', 'fedora', 'amazon' 31 | remote_file "/etc/pki/rpm-gpg/RPM-GPG-KEY-PGDG-#{new_resource.version}" do 32 | source new_resource.yum_gpg_key_uri 33 | end 34 | 35 | yum_repository "PostgreSQL #{new_resource.version}" do 36 | repositoryid "pgdg#{new_resource.version}" 37 | description "PostgreSQL.org #{new_resource.version}" 38 | baseurl yum_repo_url('https://download.postgresql.org/pub/repos/yum') 39 | enabled new_resource.enable_pgdg 40 | gpgcheck true 41 | gpgkey "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-PGDG-#{new_resource.version}" 42 | end 43 | 44 | yum_repository "PostgreSQL #{new_resource.version} - source " do 45 | repositoryid "pgdg#{new_resource.version}-source" 46 | description "PostgreSQL.org #{new_resource.version} Source" 47 | baseurl yum_repo_url('https://download.postgresql.org/pub/repos/yum/srpms') 48 | enabled new_resource.enable_pgdg_source 49 | gpgcheck true 50 | gpgkey "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-PGDG-#{new_resource.version}" 51 | end 52 | 53 | yum_repository "PostgreSQL #{new_resource.version} - updates testing" do 54 | repositoryid "pgdg#{new_resource.version}-updates-testing" 55 | description "PostgreSQL.org #{new_resource.version} Updates Testing" 56 | baseurl yum_repo_url('https://download.postgresql.org/pub/repos/yum/testing') 57 | enabled new_resource.enable_pgdg_updates_testing 58 | gpgcheck true 59 | gpgkey "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-PGDG-#{new_resource.version}" 60 | end 61 | 62 | yum_repository "PostgreSQL #{new_resource.version} - source - updates testing" do 63 | repositoryid "pgdg#{new_resource.version}-source-updates-testing" 64 | description "PostgreSQL.org #{new_resource.version} Source Updates Testing" 65 | baseurl yum_repo_url('https://download.postgresql.org/pub/repos/yum/srpms/testing') 66 | enabled new_resource.enable_pgdg_source_updates_testing 67 | gpgcheck true 68 | gpgkey "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-PGDG-#{new_resource.version}" 69 | end 70 | 71 | when 'debian' 72 | apt_update 73 | 74 | package 'apt-transport-https' 75 | 76 | apt_repository 'postgresql_org_repository' do 77 | uri 'https://download.postgresql.org/pub/repos/apt/' 78 | components ['main', new_resource.version.to_s] 79 | distribution "#{node['lsb']['codename']}-pgdg" 80 | key new_resource.apt_gpg_key_uri 81 | cache_rebuild true 82 | end 83 | else 84 | raise "The platform_family '#{node['platform_family']}' or platform '#{node['platform']}' is not supported by the postgresql_repository resource. If you believe this platform can/should be supported by this resource please file and issue or open a pull request at https://github.com/sous-chefs/postgresql" 85 | end 86 | end 87 | 88 | action_class do 89 | include PostgresqlCookbook::Helpers 90 | end 91 | -------------------------------------------------------------------------------- /cookbooks/postgresql/spec/libraries/helpers_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | require_relative '../../libraries/helpers.rb' 3 | 4 | RSpec.describe PostgresqlCookbook::Helpers do 5 | class DummyClass < Chef::Node 6 | include PostgresqlCookbook::Helpers 7 | end 8 | subject { DummyClass.new } 9 | 10 | describe '#data_dir(version)' do 11 | before do 12 | allow(subject).to receive(:[]).with('platform_family').and_return(platform_family) 13 | end 14 | 15 | let(:pg_version) { '9.6' } 16 | 17 | context 'with rhel family and Postgres 9.6' do 18 | let(:platform_family) { 'rhel' } 19 | 20 | it 'returns the correct path' do 21 | expect(subject.data_dir(pg_version)).to eq '/var/lib/pgsql/9.6/data' 22 | end 23 | end 24 | 25 | context 'with debian family and Postgres 9.6' do 26 | let(:platform_family) { 'debian' } 27 | 28 | it 'returns the correct path' do 29 | expect(subject.data_dir(pg_version)).to eq '/var/lib/postgresql/9.6/main' 30 | end 31 | end 32 | end 33 | 34 | describe '#conf_dir(version)' do 35 | before do 36 | allow(subject).to receive(:[]).with('platform_family').and_return(platform_family) 37 | end 38 | 39 | let(:pg_version) { '9.6' } 40 | 41 | context 'with rhel family and Postgres 9.6' do 42 | let(:platform_family) { 'rhel' } 43 | 44 | it 'returns the correct path' do 45 | expect(subject.conf_dir(pg_version)).to eq '/var/lib/pgsql/9.6/data' 46 | end 47 | end 48 | 49 | context 'with debian family and Postgres 9.6' do 50 | let(:platform_family) { 'debian' } 51 | 52 | it 'returns the correct path' do 53 | expect(subject.conf_dir(pg_version)).to eq '/etc/postgresql/9.6/main' 54 | end 55 | end 56 | end 57 | 58 | describe '#platform_service_name(version)' do 59 | before do 60 | allow(subject).to receive(:[]).with('platform_family').and_return(platform_family) 61 | end 62 | 63 | let(:pg_version) { '9.6' } 64 | 65 | context 'with rhel family and Postgres 9.6' do 66 | let(:platform_family) { 'rhel' } 67 | 68 | it 'returns the correct service name' do 69 | expect(subject.platform_service_name(pg_version)).to eq 'postgresql-9.6' 70 | end 71 | end 72 | 73 | context 'with debian family and Postgres 9.6' do 74 | let(:platform_family) { 'debian' } 75 | 76 | it 'returns the correct service name' do 77 | expect(subject.platform_service_name(pg_version)).to eq 'postgresql' 78 | end 79 | end 80 | end 81 | 82 | describe '#psql_command_string' do 83 | before do 84 | @new_resource = double(database: 'db_foo', 85 | user: 'postgres', 86 | host: 'localhost', 87 | port: '5432' 88 | ) 89 | @query = 'THIS IS A COMMAND STRING' 90 | end 91 | 92 | it 'returns a full command string given all the parameters' do 93 | grep_string = 'FOO' 94 | result = %(/usr/bin/psql -c "THIS IS A COMMAND STRING" -d db_foo -U postgres --host localhost --port 5432 | grep FOO) 95 | 96 | expect(subject.psql_command_string(@new_resource, @query, grep_for: grep_string)).to eq(result) 97 | end 98 | 99 | it 'returns a command without grep' do 100 | result = %(/usr/bin/psql -c "THIS IS A COMMAND STRING" -d db_foo -U postgres --host localhost --port 5432) 101 | 102 | expect(subject.psql_command_string(@new_resource, @query)).to eq(result) 103 | end 104 | 105 | it 'Allow us to connect to postgresql without specifying the database name' do 106 | new_resource = double(database: 'test_1234', 107 | user: 'postgres', 108 | port: '5432', 109 | host: nil 110 | ) 111 | res = double( 112 | user: new_resource.user, 113 | port: new_resource.port, 114 | database: nil, 115 | host: nil 116 | ) 117 | 118 | db_query = 'SELECT datname from pg_database WHERE datname=\'test_1234\'' 119 | grep_string = 'test_1234' 120 | 121 | result = %(/usr/bin/psql -c "SELECT datname from pg_database WHERE datname='test_1234'" -U postgres --port 5432 | grep test_1234) 122 | 123 | expect(subject.psql_command_string(res, db_query, grep_for: grep_string)).to eq(result) 124 | end 125 | 126 | it 'Allows new_resource.database to be nil or not set' do 127 | new_resource = double(database: nil, 128 | user: 'postgres', 129 | port: '5432', 130 | host: '127.0.0.1' 131 | ) 132 | db_query = 'SELECT datname from pg_database WHERE datname=\'test_1234\'' 133 | result = %(/usr/bin/psql -c "SELECT datname from pg_database WHERE datname='test_1234'" -U postgres --host 127.0.0.1 --port 5432) 134 | 135 | expect(subject.psql_command_string(new_resource, db_query)).to eq(result) 136 | end 137 | 138 | it 'Allow the host to not be set' do 139 | new_resource = double(database: nil, 140 | user: 'postgres', 141 | port: '5432', 142 | host: nil 143 | ) 144 | query = 'SELECT datname from pg_database WHERE datname=\'postgres\'' 145 | result = %(/usr/bin/psql -c "SELECT datname from pg_database WHERE datname='postgres'" -U postgres --port 5432) 146 | 147 | expect(subject.psql_command_string(new_resource, query)).to eq(result) 148 | end 149 | end 150 | 151 | describe '#role_sql' do 152 | it 'Should return a correctly formatted role creation string' do 153 | new_resource = double( 154 | create_user: 'sous_chef', 155 | superuser: true, 156 | password: '67890', 157 | createdb: nil, 158 | sensitive: false, 159 | createrole: nil, 160 | inherit: nil, 161 | replication: nil, 162 | login: true, 163 | encrypted_password: nil, 164 | valid_until: nil 165 | ) 166 | result = %(\\"sous_chef\\" WITH SUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT NOREPLICATION LOGIN PASSWORD '67890') 167 | 168 | expect(subject.role_sql(new_resource)).to eq result 169 | end 170 | end 171 | 172 | describe '#alter_role_sql' do 173 | it 'should return a correct SQL string to set a password' do 174 | new_resource = double( 175 | version: '9.6', 176 | setup_repo: true, 177 | hba_file: nil, 178 | ident_file: nil, 179 | external_pid_file: nil, 180 | password: '12345', 181 | port: '5432', 182 | initdb_locale: 'UTF-8', 183 | user: 'postgres', 184 | database: nil, 185 | host: nil 186 | ) 187 | result = %(/usr/bin/psql -c "ALTER ROLE postgres ENCRYPTED PASSWORD '12345';" -U postgres --port 5432) 188 | 189 | expect(subject.alter_role_sql(new_resource)).to eq result 190 | end 191 | end 192 | 193 | describe '#create_extension_sql' do 194 | it 'should return sql formatted correctly' do 195 | new_resource = double( 196 | extension: 'plpgsql', 197 | old_version: nil, 198 | user: 'postgres', 199 | database: nil, 200 | host: nil, 201 | port: 5432 202 | ) 203 | result = %(/usr/bin/psql -c "CREATE EXTENSION IF NOT EXISTS plpgsql" -U postgres --port 5432) 204 | 205 | expect(subject.create_extension_sql(new_resource)).to eq result 206 | end 207 | 208 | context 'when using hyphenated extension' do 209 | it 'should return sql formatted correctly with quotes' do 210 | new_resource = double( 211 | extension: '"uuid-ossp"', 212 | old_version: nil, 213 | user: 'postgres', 214 | database: nil, 215 | host: nil, 216 | port: 5432 217 | ) 218 | result = %(/usr/bin/psql -c "CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\"" -U postgres --port 5432) 219 | 220 | expect(subject.create_extension_sql(new_resource)).to eq result 221 | end 222 | end 223 | end 224 | end 225 | -------------------------------------------------------------------------------- /cookbooks/postgresql/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # postgresql Cookbook CHANGELOG 2 | 3 | This file is used to list changes made in the last 3 major versions of the postgresql cookbook. 4 | 5 | ## v7.1.9 (2020-05-14) 6 | 7 | - resolved cookstyle error: resources/access.rb:30:28 convention: `Layout/TrailingWhitespace` 8 | - resolved cookstyle error: resources/access.rb:30:29 refactor: `ChefModernize/FoodcriticComments` 9 | - resolved cookstyle error: resources/access.rb:54:44 convention: `Layout/TrailingWhitespace` 10 | - resolved cookstyle error: resources/access.rb:54:45 refactor: `ChefModernize/FoodcriticComments` 11 | - resolved cookstyle error: resources/ident.rb:50:44 convention: `Layout/TrailingWhitespace` 12 | - resolved cookstyle error: resources/ident.rb:50:45 refactor: `ChefModernize/FoodcriticComments` 13 | - resolved cookstyle error: resources/repository.rb:35:59 convention: `Layout/TrailingWhitespace` 14 | - resolved cookstyle error: resources/repository.rb:35:60 refactor: `ChefModernize/FoodcriticComments` 15 | - resolved cookstyle error: resources/user.rb:39:66 convention: `Layout/TrailingWhitespace` 16 | - resolved cookstyle error: resources/user.rb:39:67 refactor: `ChefModernize/FoodcriticComments` 17 | 18 | ## v7.1.8 (2020-02-22) 19 | 20 | - Fix incorrect ubuntu platform family value in `postgresql_server_install` 21 | - Re-add unit tests that were skipped 22 | 23 | ## v7.1.7 (2020-02-21) 24 | 25 | - Correctly configure postgres-common on Ubuntu hosts (fixes #596) 26 | 27 | ## v7.1.6 (2020-02-20) 28 | 29 | - Remove unnecessary nil default in resource properties 30 | - Migrate to GitHub Actions for testing 31 | 32 | ## v7.1.5 (2019-11-18) 33 | 34 | - Allow to install extensions with hyphens, ex: `postgresql_extension '"uuid-ossp"'` 35 | - Update Circle CI config to match sous-chefs defaults #617 36 | - Remove Fedora testing from CI, not an official supported OS by sous-chefs, PR welcome #617 37 | 38 | ## v7.1.4 (2019-03-28) 39 | 40 | - Fix installation of extensions. 41 | 42 | ## v7.1.3 (2019-01-15) 43 | 44 | - Added support for dash in database role name. 45 | 46 | ## v7.1.2 (2019-06-01) 47 | 48 | - Cleanup and update the user resource documentation and code. Removed extraneous 'sensitive' property which is a common property in all Chef resources. 49 | - Change default permissions on the postgres.conf to be world readable so that psql can work. 50 | 51 | ## v7.1.1 (2018-09-26) 52 | 53 | - Rename slave to follower 54 | - Use CircleCI for testing 55 | - Simplyfy extension resource 56 | 57 | ## v7.1.0 (2018-06-22) 58 | 59 | - Update the `initdb` script to use initdb rather than a service. #542 60 | - Refactor database commands to use the common connect method. #535 61 | - Increase the unit test coverage. 62 | 63 | ## v7.0.0 (2018-05-25) 64 | 65 | _Breaking Change_ Please see UPGRADING.md and the README.md for information how to use. 66 | 67 | - Add custom resources for: 68 | 69 | - `postgresql_client_install` 70 | - `postgresql_server_install` 71 | - `postgresql_repository` 72 | - `postgresql_pg_gem` 73 | 74 | - Deprecate recipes: 75 | 76 | - `apt_pgdg_postgresql` 77 | - `config_initdb` 78 | - `config_pgtune` 79 | - `contrib` 80 | - `ruby` 81 | - `yum_pgdg_postgresql` 82 | 83 | - Remove deprecated tests 84 | 85 | ## v6.1.3 (2018-04-18) 86 | 87 | - Fix recipes referencing the old helpers 88 | 89 | ## v6.1.2 (2018-04-16) 90 | 91 | this will be the last release of the 6.0 series before all recipes are removed from the cookbook 92 | 93 | - Deprecate all recipes 94 | 95 | ## v6.1.1 (2017-03-08) 96 | 97 | - Fix pg gem installation on non-omnibus chef runs 98 | - Resolve resource cloning deprecation warnings in the ruby recipe 99 | - Fix issues resolving the timezone on CentOS 7 and probably other distros 100 | - Test with Delivery local instead of Rake 101 | 102 | ## v6.1.0 (2017-02-18) 103 | 104 | - Fix a method name conflict that caused errors if Chef Sugar was also being used on the run list 105 | - Revert a previous PR that added support for Postgresql 9.6 as it introduced incorrect configuration values 106 | - Added Fedora 25 support for pgdg packages 107 | - Added RHEL 5 support for Postgresql 9.4 pgdg packages 108 | - Removed testing for RHEL 5 and Ubuntu 12.04 as they are scheduled for EoL in the near future 109 | - Improvements to Test Kitchen testing to allow more extensive testing in Travis CI 110 | - Fixed the client recipe on Fedora 111 | - Added Inspec tests for client installs 112 | 113 | ## v6.0.1 (2017-01-04 114 | 115 | - Fix systemd unit file template 116 | 117 | ## v6.0.0 (2017-01-03) 118 | 119 | - This cookbook now requires Chef 12.1 or later 120 | - Removed the dependency on the apt cookbook as this functionality is built into modern chef client releases 121 | - Added a new custom resource for installing extensions. This acts as a replacement for the contrib recipe with minimal backwards compatibility. You can now install / remove extensions into any database. This adds the compat_resource cookbook dependency so we can continue to support Chef 12.1-12.4, which lack custom resource support. 122 | - The unused get_result_orig helper has been removed. If you utilized this you'll want to move it to your own wrapper cookbook 123 | - Updates for compatibility with Postgresql 9.5 and 9.6 124 | - Fixed client package installation on openSUSE Leap 42.2 125 | - ca-certificates recipe has been deprecated. If ca-certificates package needs to be upgraded the user should do so prior to including this recipe. Package upgrades in community cookbooks are generally a bad idea as this bring in updated packages to production systems. The recipe currently warns if used and will be removed with the next major cookbook release. 126 | - Fixed RHEL platform detection in the Ruby recipe 127 | - systemd fixes for RHEL systems 128 | - Fix systemd service file include when using pgdg packages 129 | - Package installation now uses multi-package installs to speed up converge times 130 | - Added integration testing in Travis of the client recipe using a new test cookbook. This will be expanded in the future to cover server installation as well 131 | - Expanded the specs to test converges on multiple platforms 132 | 133 | ## v5.2.0 (2016-12-30) 134 | 135 | - Updated contacts and links to point to Sous Chefs now 136 | - Added a Code of Conduct (the Chef CoC) 137 | - Removed duplicate platforms in the metadata 138 | - Fix Chef runs with local mode in the server recipe 139 | - Fix the ruby recipe to not fail when you specify enabling both the apt and yum repos for mixed distro environments 140 | - Set the postgresql data directory to 700 permissions 141 | - Added node['postgresql']['pg_gem']['version'] to specify the version of the pg gem to install 142 | - Cookstyle fixes for the latest cookstyle release 143 | - Removed test deps from the Gemfile. Rely on ChefDK for base testing deps instead 144 | 145 | ## v5.1.0 (2016-11-01) 146 | 147 | - Maintenance of this cookbook has been migrated from Heavy Water to Sous Chefs - 148 | - Add support for Chef-Zero (local mode) 149 | - Don't hardcode the UID / GID on RHEL/Amazon/Suse platforms 150 | - Add PGDG yum RPMs for 9.5 / 9.6 151 | 152 | ## v5.0.0 (2016-10-25) 153 | 154 | ### Breaking changes 155 | 156 | - Switched from Librarian to Berkshelf 157 | - Remove support for the following platforms 158 | 159 | - SLES < 12 160 | - openSUSE < 13 161 | - Debian < 7 162 | - Ubuntu < 12.04 163 | - RHEL < 6 164 | - Amazon < 2013 165 | - Unsupported (EOL) Fedora releases 166 | 167 | ### Other changes 168 | 169 | - Added support for Ubuntu 16.04 170 | - Loosened cookbook dependencies to not prevent pulling in the latest community cookbooks 171 | - Added chef_version metadata 172 | - Switched from rubocop to cookstyle and fix all warnings 173 | - Removed minitests and the minitest handler 174 | - Added support for opensuse / opensuseleap 175 | - Added support for Fedora 23/24 176 | - Added a chefignore file to limit the files uploaded to the chef server 177 | - Updated Test Kitchen config to test on modern platform releases 178 | - Added a Rakefile and updated Travis to test with ChefDK and that rakefile 179 | - Avoid installing packages included in build-essential twice in the ruby recipe 180 | - Require at least build-essential 2.0 181 | - Don't cleanup the old PPA files in the apt_pgdg_postgresql recipe anymore. These should be long gone everywhere 182 | - Remove logic in the apt_pgdg_postgresql recipe that made Chef fail when new distro releases came out 183 | - Avoid node.set deprecation warnings 184 | - Avoid managed_home deprecation warnings in server_redhat recipe 185 | -------------------------------------------------------------------------------- /cookbooks/postgresql/libraries/helpers.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: postgresql 3 | # Library:: helpers 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | module PostgresqlCookbook 19 | module Helpers 20 | include Chef::Mixin::ShellOut 21 | 22 | require 'securerandom' 23 | 24 | def psql_command_string(new_resource, query, grep_for: nil, value_only: false) 25 | cmd = %(/usr/bin/psql -c "#{query}") 26 | cmd << " -d #{new_resource.database}" if new_resource.database 27 | cmd << " -U #{new_resource.user}" if new_resource.user 28 | cmd << " --host #{new_resource.host}" if new_resource.host 29 | cmd << " --port #{new_resource.port}" if new_resource.port 30 | cmd << ' --tuples-only' if value_only 31 | cmd << " | grep #{grep_for}" if grep_for 32 | cmd 33 | end 34 | 35 | def execute_sql(new_resource, query) 36 | # If we don't pass in a user to the resource 37 | # default to the postgres user 38 | user = new_resource.user || 'postgres' 39 | 40 | # Query could be a String or an Array of Strings 41 | statement = query.is_a?(String) ? query : query.join("\n") 42 | 43 | cmd = shell_out(statement, user: user, environment: psql_environment) 44 | 45 | # Pass back cmd so we can decide what to do with it in the calling method. 46 | cmd 47 | end 48 | 49 | def database_exists?(new_resource) 50 | sql = %(SELECT datname from pg_database WHERE datname='#{new_resource.database}') 51 | 52 | exists = psql_command_string(new_resource, sql, grep_for: new_resource.database) 53 | 54 | cmd = execute_sql(new_resource, exists) 55 | cmd.exitstatus == 0 56 | end 57 | 58 | def user_exists?(new_resource) 59 | sql = %(SELECT rolname FROM pg_roles WHERE rolname='#{new_resource.create_user}';) 60 | 61 | exists = psql_command_string(new_resource, sql, grep_for: new_resource.create_user) 62 | 63 | cmd = execute_sql(new_resource, exists) 64 | cmd.exitstatus == 0 65 | end 66 | 67 | def extension_installed?(new_resource) 68 | query = %(SELECT extversion FROM pg_extension WHERE extname='#{new_resource.extension}';) 69 | check_extension_version = psql_command_string(new_resource, query, value_only: true) 70 | version_result = execute_sql(new_resource, check_extension_version) 71 | if new_resource.version 72 | version_result.stdout == new_resource.version 73 | else 74 | !version_result.stdout.chomp.empty? 75 | end 76 | end 77 | 78 | def alter_role_sql(new_resource) 79 | sql = %(ALTER ROLE postgres ENCRYPTED PASSWORD '#{postgres_password(new_resource)}';) 80 | psql_command_string(new_resource, sql) 81 | end 82 | 83 | def create_extension_sql(new_resource) 84 | sql = %(CREATE EXTENSION IF NOT EXISTS #{new_resource.extension}) 85 | sql << " FROM \"#{new_resource.old_version}\"" if new_resource.old_version 86 | 87 | psql_command_string(new_resource, sql) 88 | end 89 | 90 | def user_has_password?(new_resource) 91 | sql = %(SELECT rolpassword from pg_authid WHERE rolname='postgres' AND rolpassword IS NOT NULL;) 92 | cmd = psql_command_string(new_resource, sql) 93 | 94 | res = execute_sql(new_resource, cmd) 95 | res.stdout =~ /1 row/ ? true : false 96 | end 97 | 98 | def role_sql(new_resource) 99 | sql = %(\\"#{new_resource.create_user}\\" WITH ) 100 | 101 | %w(superuser createdb createrole inherit replication login).each do |perm| 102 | sql << "#{'NO' unless new_resource.send(perm)}#{perm.upcase} " 103 | end 104 | 105 | sql << if new_resource.encrypted_password 106 | "ENCRYPTED PASSWORD '#{new_resource.encrypted_password}'" 107 | elsif new_resource.password 108 | "PASSWORD '#{new_resource.password}'" 109 | else 110 | '' 111 | end 112 | 113 | sql << if new_resource.valid_until 114 | " VALID UNTIL '#{new_resource.valid_until}'" 115 | else 116 | '' 117 | end 118 | end 119 | 120 | def create_user_sql(new_resource) 121 | sql = %(CREATE ROLE #{role_sql(new_resource)}) 122 | psql_command_string(new_resource, sql) 123 | end 124 | 125 | def update_user_sql(new_resource) 126 | sql = %(ALTER ROLE #{role_sql(new_resource)}) 127 | psql_command_string(new_resource, sql) 128 | end 129 | 130 | def update_user_with_attributes_sql(new_resource, value) 131 | sql = %(ALTER ROLE '#{new_resource.create_user}' SET #{attr} = #{value}) 132 | psql_command_string(new_resource, sql) 133 | end 134 | 135 | def drop_user_sql(new_resource) 136 | sql = %(DROP ROLE IF EXISTS '#{new_resource.create_user}') 137 | psql_command_string(new_resource, sql) 138 | end 139 | 140 | def data_dir(version = node.run_state['postgresql']['version']) 141 | case node['platform_family'] 142 | when 'rhel', 'fedora' 143 | "/var/lib/pgsql/#{version}/data" 144 | when 'amazon' 145 | if node['virtualization']['system'] == 'docker' 146 | "/var/lib/pgsql#{version.delete('.')}/data" 147 | else 148 | "/var/lib/pgsql/#{version}/data" 149 | end 150 | when 'debian' 151 | "/var/lib/postgresql/#{version}/main" 152 | end 153 | end 154 | 155 | def conf_dir(version = node.run_state['postgresql']['version']) 156 | case node['platform_family'] 157 | when 'rhel', 'fedora' 158 | "/var/lib/pgsql/#{version}/data" 159 | when 'amazon' 160 | if node['virtualization']['system'] == 'docker' 161 | "/var/lib/pgsql#{version.delete('.')}/data" 162 | else 163 | "/var/lib/pgsql/#{version}/data" 164 | end 165 | when 'debian' 166 | "/etc/postgresql/#{version}/main" 167 | end 168 | end 169 | 170 | # determine the platform specific service name 171 | def platform_service_name(version = node.run_state['postgresql']['version']) 172 | case node['platform_family'] 173 | when 'rhel', 'fedora' 174 | "postgresql-#{version}" 175 | when 'amazon' 176 | if node['virtualization']['system'] == 'docker' 177 | "postgresql#{version.delete('.')}" 178 | else 179 | "postgresql-#{version}" 180 | end 181 | else 182 | 'postgresql' 183 | end 184 | end 185 | 186 | def follower? 187 | ::File.exist? "#{data_dir}/recovery.conf" 188 | end 189 | 190 | def initialized? 191 | return true if ::File.exist?("#{conf_dir}/PG_VERSION") 192 | false 193 | end 194 | 195 | def secure_random 196 | r = SecureRandom.hex 197 | Chef::Log.debug "Generated password: #{r}" 198 | r 199 | end 200 | 201 | # determine the platform specific server package name 202 | def server_pkg_name 203 | platform_family?('debian') ? "postgresql-#{new_resource.version}" : "postgresql#{new_resource.version.delete('.')}-server" 204 | end 205 | 206 | # determine the appropriate DB init command to run based on RHEL/Fedora/Amazon release 207 | # initdb defaults to the execution environment. 208 | # https://www.postgresql.org/docs/9.5/static/locale.html 209 | def rhel_init_db_command(new_resource) 210 | cmd = if platform_family?('amazon') 211 | '/usr/bin/initdb' 212 | else 213 | "/usr/pgsql-#{new_resource.version}/bin/initdb" 214 | end 215 | cmd << " --locale '#{new_resource.initdb_locale}'" if new_resource.initdb_locale 216 | cmd << " -E '#{new_resource.initdb_encoding}'" if new_resource.initdb_encoding 217 | cmd << " -D '#{data_dir(new_resource.version)}'" 218 | end 219 | 220 | # Given the base URL build the complete URL string for a yum repo 221 | def yum_repo_url(base_url) 222 | "#{base_url}/#{new_resource.version}/#{yum_repo_platform_family_string}/#{yum_repo_platform_string}" 223 | end 224 | 225 | # The postgresql yum repos URLs are organized into redhat and fedora directories.s 226 | # route things to the right place based on platform_family 227 | def yum_repo_platform_family_string 228 | platform_family?('fedora') ? 'fedora' : 'redhat' 229 | end 230 | 231 | # Build the platform string that makes up the final component of the yum repo URL 232 | def yum_repo_platform_string 233 | platform = platform?('fedora') ? 'fedora' : 'rhel' 234 | release = platform?('amazon') ? '6' : '$releasever' 235 | "#{platform}-#{release}-$basearch" 236 | end 237 | 238 | # On Amazon use the RHEL 6 packages. Otherwise use the releasever yum variable 239 | def yum_releasever 240 | platform?('amazon') ? '6' : '$releasever' 241 | end 242 | 243 | # Fedora doesn't seem to know the right symbols for psql 244 | def psql_environment 245 | return {} unless platform?('fedora') 246 | { LD_LIBRARY_PATH: '/usr/lib64' } 247 | end 248 | 249 | # Generate a password if the value is set to generate. 250 | def postgres_password(new_resource) 251 | new_resource.password == 'generate' ? secure_random : new_resource.password 252 | end 253 | end 254 | end 255 | -------------------------------------------------------------------------------- /cookbooks/postgresql/LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /cookbooks/postgresql/README.md: -------------------------------------------------------------------------------- 1 | # PostgreSQL cookbook 2 | 3 | [![Cookbook Version](https://img.shields.io/cookbook/v/postgresql.svg)](https://supermarket.chef.io/cookbooks/postgresql) 4 | [![Build Status](https://img.shields.io/circleci/project/github/sous-chefs/postgresql/master.svg)](https://circleci.com/gh/sous-chefs/postgresql) 5 | [![OpenCollective](https://opencollective.com/sous-chefs/backers/badge.svg)](#backers) 6 | [![OpenCollective](https://opencollective.com/sous-chefs/sponsors/badge.svg)](#sponsors) 7 | [![License](https://img.shields.io/badge/License-Apache%202.0-green.svg)](https://opensource.org/licenses/Apache-2.0) 8 | 9 | Installs and configures PostgreSQL as a client or a server. 10 | 11 | ## Maintainers 12 | 13 | This cookbook is maintained by the Sous Chefs. The Sous Chefs are a community of Chef cookbook maintainers working together to maintain important cookbooks. If you’d like to know more please visit [sous-chefs.org](https://sous-chefs.org/) or come chat with us on the Chef Community Slack in [#sous-chefs](https://chefcommunity.slack.com/messages/C2V7B88SF). 14 | 15 | ## Upgrading 16 | 17 | If you are wondering where all the recipes went in v7.0+, or how on earth I use this new cookbook please see upgrading.md for a full description. 18 | 19 | ## Requirements 20 | 21 | ### Platforms 22 | 23 | - Amazon Linux 24 | - Debian 7+ 25 | - Ubuntu 14.04+ 26 | - Red Hat/CentOS/Scientific 6+ 27 | 28 | ### PostgreSQL version 29 | 30 | We follow the currently supported versions listed on 31 | 32 | ### Chef 33 | 34 | - Chef 13.8+ 35 | 36 | ### Cookbook Dependencies 37 | 38 | None. 39 | 40 | ## Resources 41 | 42 | ### postgresql_client_install 43 | 44 | This resource installs PostgreSQL client packages. 45 | 46 | #### Actions 47 | 48 | - `install` - (default) Install client packages 49 | 50 | #### Properties 51 | 52 | Name | Types | Description | Default | Required? 53 | ------------------- | ----------------- | ------------------------------------------------------------- | ----------------------------------------- | --------- 54 | `version` | String | Version of PostgreSQL to install | '9.6' | no 55 | `setup_repo` | Boolean | Define if you want to add the PostgreSQL repo | true | no 56 | `hba_file` | String | | `#{conf_dir}/main/pg_hba.conf` | no 57 | `ident_file` | String | | `#{conf_dir}/main/pg_ident.conf` | no 58 | `external_pid_file` | String | | `/var/run/postgresql/#{version}-main.pid` | no 59 | `password` | String, nil | Pass in a password, or have the cookbook generate one for you | random string | no 60 | 61 | #### Examples 62 | 63 | To install version 9.5: 64 | 65 | ```ruby 66 | postgresql_client_install 'My PostgreSQL Client install' do 67 | version '9.5' 68 | end 69 | ``` 70 | 71 | ### postgresql_server_install 72 | 73 | This resource installs PostgreSQL client and server packages. 74 | 75 | #### Actions 76 | 77 | - `install` - (default) Install client and server packages 78 | - `create` - Initialize the database 79 | 80 | #### Properties 81 | 82 | Name | Types | Description | Default | Required? 83 | ------------------- | --------------- | --------------------------------------------- | -------------------------------------------------- | --------- 84 | `version` | String | Version of PostgreSQL to install | '9.6' | no 85 | `setup_repo` | Boolean | Define if you want to add the PostgreSQL repo | true | no 86 | `hba_file` | String | Path of pg_hba.conf file | `/pg_hba.conf'` | no 87 | `ident_file` | String | Path of pg_ident.conf file | `/pg_ident.conf` | no 88 | `external_pid_file` | String | Path of PID file | `/var/run/postgresql/-main.pid` | no 89 | `password` | String, nil | Set PostgreSQL user password | 'generate' | no 90 | `port` | Integer | Set listen port of PostgreSQL service | 5432 | no 91 | `initdb_locale` | String | Locale to initialise the database with | 'C' | no 92 | 93 | #### Examples 94 | 95 | To install PostgreSQL server, set your own postgres password using non-default service port. 96 | 97 | ```ruby 98 | postgresql_server_install 'My PostgreSQL Server install' do 99 | action :install 100 | end 101 | 102 | postgresql_server_install 'Setup my PostgreSQL 9.6 server' do 103 | password 'MyP4ssw0rd' 104 | port 5433 105 | action :create 106 | end 107 | ``` 108 | 109 | #### Known issues 110 | 111 | On some platforms (e.g. Ubuntu 18.04), your `initdb_locale` should be set to the 112 | same as the template database [GH-555](https://github.com/sous-chefs/postgresql/issues/555). 113 | 114 | ### postgresql_server_conf 115 | 116 | This resource manages postgresql.conf configuration file. 117 | 118 | #### Actions 119 | 120 | - `modify` - (default) Manager PostgreSQL configuration file (postgresql.conf) 121 | 122 | #### Properties 123 | 124 | Name | Types | Description | Default | Required? 125 | ---------------------- | ------- | --------------------------------------- | --------------------------------------------------- | --------- 126 | `version` | String | Version of PostgreSQL to install | '9.6' | no 127 | `data_directory` | String | Path of PostgreSQL data directory | `` | no 128 | `hba_file` | String | Path of pg_hba.conf file | `/pg_hba.conf` | no 129 | `ident_file` | String | Path of pg_ident.conf file | `/pg_ident.conf` | no 130 | `external_pid_file` | String | Path of PID file | `/var/run/postgresql/-main.pid` | no 131 | `stats_temp_directory` | String | Path of stats file | `/var/run/postgresql/version>-main.pg_stat_tmp` | no 132 | `port` | Integer | Set listen port of PostgreSQL service | 5432 | no 133 | `additional_config` | Hash | Extra configuration for the config file | {} | no 134 | 135 | #### Examples 136 | 137 | To setup your PostgreSQL configuration with a specific data directory. If you have installed a specific version of PostgreSQL (different from 9.6), you must specify version in this resource too. 138 | 139 | ```ruby 140 | postgresql_server_conf 'My PostgreSQL Config' do 141 | version '9.5' 142 | data_directory '/data/postgresql/9.5/main' 143 | notifies :reload, 'service[postgresql]' 144 | end 145 | ``` 146 | 147 | ### postgresql_extension 148 | 149 | This resource manages PostgreSQL extensions for a given database. 150 | 151 | #### Actions 152 | 153 | - `create` - (default) Creates an extension in a given database 154 | - `drop` - Drops an extension from the database 155 | 156 | #### Properties 157 | 158 | Name | Types | Description | Default | Required? 159 | ------------- | ------ | -------------------------------------------------------------------------------- | ---------------- | --------- 160 | `database` | String | Name of the database to install the extension into | | yes 161 | `extension` | String | Name of the extension to install the database | Name of resource | yes 162 | `version` | String | Version of the extension to install | | no 163 | `old_version` | String | Older module name for new extension replacement. Appends FROM to extension query | | no 164 | 165 | #### Examples 166 | 167 | To install the `adminpack` extension: 168 | 169 | ```ruby 170 | # Add the contrib package in Ubuntu/Debian 171 | package 'postgresql-contrib-9.6' 172 | 173 | # Install adminpack extension 174 | postgresql_extension 'postgres adminpack' do 175 | database 'postgres' 176 | extension 'adminpack' 177 | end 178 | ``` 179 | 180 | ### postgresql_access 181 | 182 | This resource uses the accumulator pattern to build up the `pg_hba.conf` file via chef resources instead of piling on a mountain of chef attributes to make this cookbook more reusable. It directly mirrors the configuration options of the postgres hba file in the resource and by default notifies the server with a reload to avoid a full restart, causing a potential outage of service. To revoke access, simply remove the resource and the access change won't be computed into the final `pg_hba.conf` 183 | 184 | #### Actions 185 | 186 | - `grant` - (default) Creates an access line inside of `pg_hba.conf` 187 | 188 | #### Properties 189 | 190 | Name | Types | Description | Default | Required? 191 | --------------- | ------ | ----------------------------------------------------------------------------------------- | ----------------- | --------- 192 | `name` | String | Name of the access resource, this is left as a comment inside the `pg_hba` config | Resource name | yes 193 | `source` | String | The cookbook template filename if you want to use your own custom template | 'pg_hba.conf.erb' | yes 194 | `cookbook` | String | The cookbook to look in for the template source | 'postgresql' | yes 195 | `comment` | String | A comment to leave above the entry in `pg_hba` | nil | no 196 | `access_type` | String | The type of access, e.g. local or host | 'local' | yes 197 | `access_db` | String | The database to access. Can use 'all' for all databases | 'all' | yes 198 | `access_user` | String | The user accessing the database. Can use 'all' for any user | 'all' | yes 199 | `access_addr` | String | The address(es) allowed access. Can be nil if method ident is used since it is local then | nil | no 200 | `access_method` | String | Authentication method to use | 'ident' | yes 201 | 202 | #### Examples 203 | 204 | To grant access to the PostgreSQL user with ident authentication: 205 | 206 | ```ruby 207 | postgresql_access 'local_postgres_superuser' do 208 | comment 'Local postgres superuser access' 209 | access_type 'local' 210 | access_db 'all' 211 | access_user 'postgres' 212 | access_addr nil 213 | access_method 'ident' 214 | end 215 | ``` 216 | 217 | This generates the following line in the `pg_hba.conf`: 218 | 219 | ```config 220 | # Local postgres superuser access 221 | local all postgres ident 222 | ``` 223 | 224 | **Note**: The template by default generates a local access for Unix domain sockets only to support running the SQL execute resources. In Postgres version 9.1 and higher, the method is 'peer' instead of 'ident' which is identical. It looks like this: 225 | 226 | ```config 227 | # "local" is for Unix domain socket connections only 228 | local all all peer 229 | ``` 230 | 231 | ### postgresql_ident 232 | 233 | This resource generate `pg_ident.conf` configuration file to manage user mapping between system and PostgreSQL users. 234 | 235 | #### Actions 236 | 237 | - `create` - (default) Creates an mapping line inside of `pg_ident.conf` 238 | 239 | #### Properties 240 | 241 | Name | Types | Description | Default | Required? 242 | -------------- | ----------- | -------------------------------------------------------------------------- | ------------------- | --------- 243 | `mapname` | String | Name of the user mapping | Resource name | yes 244 | `source` | String | The cookbook template filename if you want to use your own custom template | 'pg_ident.conf.erb' | no 245 | `cookbook` | String | The cookbook to look in for the template source | 'postgresql' | no 246 | `comment` | String, nil | A comment to leave above the entry in `pg_ident` | nil | no 247 | `system_user` | String | System user or regexp used for the mapping | None | yes 248 | `pg_user` | String | Pg user or regexp used for the mapping | None | yes 249 | 250 | #### Examples 251 | 252 | Creates a `mymapping` mapping that map `john` system user to `user1` PostgreSQL user: 253 | 254 | ```ruby 255 | postgresql_ident 'Map john to user1' do 256 | comment 'John Mapping' 257 | mapname 'mymapping' 258 | system_user 'john' 259 | pg_user 'user1' 260 | end 261 | ``` 262 | 263 | This generates the following line in the `pg_ident.conf`: 264 | 265 | ```config 266 | # MAPNAME SYSTEM-USERNAME PG-USERNAME 267 | 268 | # John Mapping 269 | mymapping john user1 270 | ``` 271 | 272 | To grant access to the foo user with password authentication: 273 | 274 | ```ruby 275 | postgresql_access 'local_foo_user' do 276 | comment 'Foo user access' 277 | access_type 'host' 278 | access_db 'all' 279 | access_user 'foo' 280 | access_addr '127.0.0.1/32' 281 | access_method 'md5' 282 | end 283 | ``` 284 | 285 | This generates the following line in the `pg_hba.conf`: 286 | 287 | ```config 288 | # Local postgres superuser access 289 | host all foo 127.0.0.1/32 ident 290 | ``` 291 | 292 | ### postgresql_database 293 | 294 | This resource manages PostgreSQL databases. 295 | 296 | #### Actions 297 | 298 | - `create` - (default) Creates the given database. 299 | - `drop` - Drops the given database. 300 | 301 | #### Properties 302 | 303 | Name | Types | Description | Default | Required? 304 | ---------- | ------- | ------------------------------------------------------------------- | ------------------- | --------- 305 | `database` | String | Name of the database to create | Resource name | yes 306 | `user` | String | User which run psql command | 'postgres' | no 307 | `template` | String | Template used to create the new database | 'template1' | no 308 | `host` | String | Define the host server where the database creation will be executed | Not set (localhost) | no 309 | `port` | Integer | Define the port of PostgreSQL server | 5432 | no 310 | `encoding` | String | Define database encoding | 'UTF-8' | no 311 | `locale` | String | Define database locale | 'en_US.UTF-8' | no 312 | `owner` | String | Define the owner of the database | Not set | no 313 | 314 | #### Examples 315 | 316 | To create database named 'my_app' with owner 'user1': 317 | 318 | ```ruby 319 | postgresql_database 'my_app' do 320 | owner 'user1' 321 | end 322 | ``` 323 | 324 | #### Known issues 325 | 326 | On some platforms (e.g. Ubuntu 18.04), your `initdb_locale` should be set to the 327 | same as the template database [GH-555](https://github.com/sous-chefs/postgresql/issues/555). 328 | 329 | ### postgresql_user 330 | 331 | This resource manage PostgreSQL users. 332 | 333 | #### Actions 334 | 335 | - `create` - (default) Creates the given user with default or given privileges. 336 | - `update` - Update user privilieges. 337 | - `drop` - Deletes the given user. 338 | 339 | #### Properties 340 | 341 | Name | Types | Description | Default | Required? 342 | -------------------- | ------- | ----------------------------------------------- | -------- | --------- 343 | `create_user` | String | User to create (defaults to the resource name) | | Yes 344 | `superuser` | Boolean | Define if user needs superuser role | false | no 345 | `createdb` | Boolean | Define if user needs createdb role | false | no 346 | `createrole` | Boolean | Define if user needs createrole role | false | no 347 | `inherit` | Boolean | Define if user inherits the privileges of roles | true | no 348 | `replication` | Boolean | Define if user needs replication role | false | no 349 | `login` | Boolean | Define if user can login | true | no 350 | `password` | String | Set user's password | | no 351 | `encrypted_password` | String | Set user's password with an hashed password | | no 352 | `valid_until` | String | Define an account expiration date | | no 353 | `attributes` | Hash | Additional attributes for :update action | {} | no 354 | `user` | String | User for command | postgres | no 355 | `database` | String | Database for command | | no 356 | `host` | String | Hostname for command | | no 357 | `port` | Integer | Port number to connect to postgres | 5432 | no 358 | 359 | #### Examples 360 | 361 | Create a user `user1` with a password, with `createdb` role and set an expiration date to 2018, Dec 21. 362 | 363 | ```ruby 364 | postgresql_user 'user1' do 365 | password 'UserP4ssword' 366 | createdb true 367 | valid_until '2018-12-31' 368 | end 369 | ``` 370 | 371 | Create a user `user1` with a password, with `createdb` role and set an expiration date to 2018, Dec 21. 372 | 373 | ```ruby 374 | postgresql_user 'user1' do 375 | password 'UserP4ssword' 376 | createdb true 377 | valid_until '2018-12-31' 378 | end 379 | ``` 380 | 381 | ## Usage 382 | 383 | To install and configure your PostgreSQL instance you need to create your own cookbook and call needed resources with your own parameters. 384 | 385 | More examples can be found in `test/cookbooks/test/recipes` 386 | 387 | ## Example Usage 388 | 389 | ```ruby 390 | # cookbooks/my_postgresql/recipes/default.rb 391 | 392 | postgresql_client_install 'PostgreSQL Client' do 393 | setup_repo false 394 | version '10.6' 395 | end 396 | 397 | postgresql_server_install 'PostgreSQL Server' do 398 | version '10.6' 399 | setup_repo false 400 | password 'P0stgresP4ssword' 401 | end 402 | 403 | postgresql_server_conf 'PostgreSQL Config' do 404 | notifies :reload, 'service[postgresql]' 405 | end 406 | ``` 407 | 408 | ## Contributors 409 | 410 | This project exists thanks to all the people who [contribute.](https://opencollective.com/sous-chefs/contributors.svg?width=890&button=false) 411 | 412 | ### Backers 413 | 414 | Thank you to all our backers! 415 | 416 | ![https://opencollective.com/sous-chefs#backers](https://opencollective.com/sous-chefs/backers.svg?width=600&avatarHeight=40) 417 | 418 | ### Sponsors 419 | 420 | Support this project by becoming a sponsor. Your logo will show up here with a link to your website. 421 | 422 | ![https://opencollective.com/sous-chefs/sponsor/0/website](https://opencollective.com/sous-chefs/sponsor/0/avatar.svg?avatarHeight=100) 423 | ![https://opencollective.com/sous-chefs/sponsor/1/website](https://opencollective.com/sous-chefs/sponsor/1/avatar.svg?avatarHeight=100) 424 | ![https://opencollective.com/sous-chefs/sponsor/2/website](https://opencollective.com/sous-chefs/sponsor/2/avatar.svg?avatarHeight=100) 425 | ![https://opencollective.com/sous-chefs/sponsor/3/website](https://opencollective.com/sous-chefs/sponsor/3/avatar.svg?avatarHeight=100) 426 | ![https://opencollective.com/sous-chefs/sponsor/4/website](https://opencollective.com/sous-chefs/sponsor/4/avatar.svg?avatarHeight=100) 427 | ![https://opencollective.com/sous-chefs/sponsor/5/website](https://opencollective.com/sous-chefs/sponsor/5/avatar.svg?avatarHeight=100) 428 | ![https://opencollective.com/sous-chefs/sponsor/6/website](https://opencollective.com/sous-chefs/sponsor/6/avatar.svg?avatarHeight=100) 429 | ![https://opencollective.com/sous-chefs/sponsor/7/website](https://opencollective.com/sous-chefs/sponsor/7/avatar.svg?avatarHeight=100) 430 | ![https://opencollective.com/sous-chefs/sponsor/8/website](https://opencollective.com/sous-chefs/sponsor/8/avatar.svg?avatarHeight=100) 431 | ![https://opencollective.com/sous-chefs/sponsor/9/website](https://opencollective.com/sous-chefs/sponsor/9/avatar.svg?avatarHeight=100) 432 | --------------------------------------------------------------------------------