├── .github
└── workflows
│ ├── commitlint.yml
│ └── kitchen.vagrant.yml
├── .gitignore
├── .gitlab-ci.yml
├── .pre-commit-config.yaml
├── .rstcheck.cfg
├── .rubocop.yml
├── .salt-lint
├── .travis.yml
├── .yamllint
├── AUTHORS.md
├── CHANGELOG.md
├── CODEOWNERS
├── FORMULA
├── Gemfile
├── Gemfile.lock
├── LICENSE
├── bin
├── install-hooks
└── kitchen
├── commitlint.config.js
├── docs
├── AUTHORS.rst
├── CHANGELOG.rst
├── README.rst
└── TOFS_pattern.rst
├── kitchen.vagrant.yml
├── kitchen.yml
├── pillar.example
├── postgres
├── _mapdata
│ ├── _mapdata.jinja
│ └── init.sls
├── client
│ ├── init.sls
│ └── remove.sls
├── codenamemap.yaml
├── defaults.yaml
├── dev
│ ├── init.sls
│ └── remove.sls
├── dropped.sls
├── init.sls
├── libtofs.jinja
├── macos
│ ├── init.sls
│ └── postgresapp.sls
├── macros.jinja
├── manage.sls
├── map.jinja
├── osfamilymap.yaml
├── osmap.yaml
├── python.sls
├── repo.yaml
├── server
│ ├── image.sls
│ ├── init.sls
│ └── remove.sls
├── templates
│ ├── limit.maxfiles.plist
│ ├── mac_shortcut.sh
│ ├── pg_hba.conf.j2
│ ├── pg_ident.conf.j2
│ └── postgres.sh.j2
└── upstream.sls
├── pre-commit_semantic-release.sh
├── release-rules.js
├── release.config.js
└── test
├── integration
├── default
│ ├── README.md
│ ├── controls
│ │ ├── services.rb
│ │ └── share.rb
│ └── inspec.yml
├── repo
│ ├── README.md
│ ├── controls
│ │ ├── repository.rb
│ │ ├── services.rb
│ │ └── share.rb
│ └── inspec.yml
└── share
│ ├── README.md
│ ├── controls
│ ├── command.rb
│ └── config.rb
│ ├── inspec.yml
│ └── libraries
│ └── system.rb
└── salt
└── pillar
├── postgres.sls
└── repo.sls
/.github/workflows/commitlint.yml:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # vim: ft=yaml
3 | ---
4 | name: Commitlint
5 | 'on': [pull_request]
6 |
7 | jobs:
8 | lint:
9 | runs-on: ubuntu-latest
10 | env:
11 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
12 | steps:
13 | - uses: actions/checkout@v2
14 | with:
15 | fetch-depth: 0
16 | - uses: wagoid/commitlint-github-action@v1
17 |
--------------------------------------------------------------------------------
/.github/workflows/kitchen.vagrant.yml:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # vim: ft=yaml
3 | ---
4 | name: 'Kitchen Vagrant (FreeBSD)'
5 | 'on': ['push', 'pull_request']
6 |
7 | env:
8 | KITCHEN_LOCAL_YAML: 'kitchen.vagrant.yml'
9 |
10 | jobs:
11 | test:
12 | runs-on: 'macos-10.15'
13 | strategy:
14 | fail-fast: false
15 | matrix:
16 | instance:
17 | - default-freebsd-130-master-py3
18 | # - freebsd-130-master-py3
19 | - default-freebsd-123-master-py3
20 | # - freebsd-123-master-py3
21 | # - default-freebsd-130-3004-0-py3
22 | # - default-freebsd-123-3004-0-py3
23 | steps:
24 | - name: 'Check out code'
25 | uses: 'actions/checkout@v2'
26 | - name: 'Set up Bundler cache'
27 | uses: 'actions/cache@v1'
28 | with:
29 | path: 'vendor/bundle'
30 | key: "${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}"
31 | restore-keys: "${{ runner.os }}-gems-"
32 | - name: 'Run Bundler'
33 | run: |
34 | ruby --version
35 | bundle config path vendor/bundle
36 | bundle install --jobs 4 --retry 3
37 | - name: 'Run Test Kitchen'
38 | run: 'bundle exec kitchen verify ${{ matrix.instance }}'
39 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | env/
12 | build/
13 | develop-eggs/
14 | dist/
15 | downloads/
16 | eggs/
17 | .eggs/
18 | lib/
19 | lib64/
20 | parts/
21 | sdist/
22 | var/
23 | wheels/
24 | *.egg-info/
25 | .installed.cfg
26 | *.egg
27 |
28 | # PyInstaller
29 | # Usually these files are written by a python script from a packager
30 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
31 | *.manifest
32 | *.spec
33 |
34 | # Installer logs
35 | pip-log.txt
36 | pip-delete-this-directory.txt
37 |
38 | # Unit test / coverage reports
39 | htmlcov/
40 | .tox/
41 | .coverage
42 | .coverage.*
43 | .cache
44 | nosetests.xml
45 | coverage.xml
46 | *.cover
47 | .hypothesis/
48 | .kitchen
49 | .kitchen.local.yml
50 | kitchen.local.yml
51 | junit-*.xml
52 |
53 | # Translations
54 | *.mo
55 | *.pot
56 |
57 | # Django stuff:
58 | *.log
59 | local_settings.py
60 |
61 | # Flask stuff:
62 | instance/
63 | .webassets-cache
64 |
65 | # Scrapy stuff:
66 | .scrapy
67 |
68 | # Sphinx documentation
69 | docs/_build/
70 |
71 | # PyBuilder
72 | target/
73 |
74 | # Jupyter Notebook
75 | .ipynb_checkpoints
76 |
77 | # pyenv
78 | .python-version
79 |
80 | # celery beat schedule file
81 | celerybeat-schedule
82 |
83 | # SageMath parsed files
84 | *.sage.py
85 |
86 | # dotenv
87 | .env
88 |
89 | # virtualenv
90 | .venv
91 | venv/
92 | ENV/
93 |
94 | # visual studio
95 | .vs/
96 |
97 | # Spyder project settings
98 | .spyderproject
99 | .spyproject
100 |
101 | # Rope project settings
102 | .ropeproject
103 |
104 | # mkdocs documentation
105 | /site
106 |
107 | # mypy
108 | .mypy_cache/
109 |
110 | # Bundler
111 | .bundle/
112 |
113 | # copied `.md` files used for conversion to `.rst` using `m2r`
114 | docs/*.md
115 |
116 | # Vim
117 | *.sw?
118 |
119 | ## Collected when centralising formulas (check and sort)
120 | # `collectd-formula`
121 | .pytest_cache/
122 | /.idea/
123 | Dockerfile.*_*
124 | ignore/
125 | tmp/
126 |
127 | # `salt-formula` -- Vagrant Specific files
128 | .vagrant
129 | top.sls
130 | !test/salt/pillar/top.sls
131 |
132 | # `suricata-formula` -- Platform binaries
133 | *.rpm
134 | *.deb
135 |
--------------------------------------------------------------------------------
/.gitlab-ci.yml:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # vim: ft=yaml
3 | ---
4 | ###############################################################################
5 | # Define all YAML node anchors
6 | ###############################################################################
7 | .node_anchors:
8 | # `only` (also used for `except` where applicable)
9 | only_branch_master_parent_repo: &only_branch_master_parent_repo
10 | - 'master@saltstack-formulas/postgres-formula'
11 | # `stage`
12 | stage_lint: &stage_lint 'lint'
13 | stage_release: &stage_release 'release'
14 | stage_test: &stage_test 'test'
15 | # `image`
16 | image_commitlint: &image_commitlint 'myii/ssf-commitlint:11'
17 | image_dindruby: &image_dindruby 'myii/ssf-dind-ruby:2.7.1-r3'
18 | image_precommit: &image_precommit
19 | name: 'myii/ssf-pre-commit:2.9.2'
20 | entrypoint: ['/bin/bash', '-c']
21 | image_rubocop: &image_rubocop 'pipelinecomponents/rubocop:latest'
22 | image_semantic-release: &image_semanticrelease 'myii/ssf-semantic-release:15.14'
23 | # `services`
24 | services_docker_dind: &services_docker_dind
25 | - 'docker:dind'
26 | # `variables`
27 | # https://forum.gitlab.com/t/gitlab-com-ci-caching-rubygems/5627/3
28 | # https://bundler.io/v1.16/bundle_config.html
29 | variables_bundler: &variables_bundler
30 | BUNDLE_CACHE_PATH: '${CI_PROJECT_DIR}/.cache/bundler'
31 | BUNDLE_WITHOUT: 'production'
32 | # `cache`
33 | cache_bundler: &cache_bundler
34 | key: '${CI_JOB_STAGE}'
35 | paths:
36 | - '${BUNDLE_CACHE_PATH}'
37 |
38 | ###############################################################################
39 | # Define stages and global variables
40 | ###############################################################################
41 | stages:
42 | - *stage_lint
43 | - *stage_test
44 | - *stage_release
45 | variables:
46 | DOCKER_DRIVER: 'overlay2'
47 |
48 | ###############################################################################
49 | # `lint` stage: `commitlint`, `pre-commit` & `rubocop` (latest, failure allowed)
50 | ###############################################################################
51 | commitlint:
52 | stage: *stage_lint
53 | image: *image_commitlint
54 | script:
55 | # Add `upstream` remote to get access to `upstream/master`
56 | - 'git remote add upstream
57 | https://gitlab.com/saltstack-formulas/postgres-formula.git'
58 | - 'git fetch --all'
59 | # Set default commit hashes for `--from` and `--to`
60 | - 'export COMMITLINT_FROM="$(git merge-base upstream/master HEAD)"'
61 | - 'export COMMITLINT_TO="${CI_COMMIT_SHA}"'
62 | # `coqbot` adds a merge commit to test PRs on top of the latest commit in
63 | # the repo; amend this merge commit message to avoid failure
64 | - |
65 | if [ "${GITLAB_USER_LOGIN}" = "coqbot" ] \
66 | && [ "${CI_COMMIT_BRANCH}" != "master" ]; then
67 | git commit --amend -m \
68 | 'chore: reword coqbot merge commit message for commitlint'
69 | export COMMITLINT_TO=HEAD
70 | fi
71 | # Run `commitlint`
72 | - 'commitlint --from "${COMMITLINT_FROM}"
73 | --to "${COMMITLINT_TO}"
74 | --verbose'
75 |
76 | pre-commit:
77 | stage: *stage_lint
78 | image: *image_precommit
79 | # https://pre-commit.com/#gitlab-ci-example
80 | variables:
81 | PRE_COMMIT_HOME: '${CI_PROJECT_DIR}/.cache/pre-commit'
82 | cache:
83 | key: '${CI_JOB_NAME}'
84 | paths:
85 | - '${PRE_COMMIT_HOME}'
86 | script:
87 | - 'pre-commit run --all-files --color always --verbose'
88 |
89 | # Use a separate job for `rubocop` other than the one potentially run by `pre-commit`
90 | # - The `pre-commit` check will only be available for formulas that pass the default
91 | # `rubocop` check -- and must continue to do so
92 | # - This job is allowed to fail, so can be used for all formulas
93 | # - Furthermore, this job uses all of the latest `rubocop` features & cops,
94 | # which will help when upgrading the `rubocop` linter used in `pre-commit`
95 | rubocop:
96 | allow_failure: true
97 | stage: *stage_lint
98 | image: *image_rubocop
99 | script:
100 | - 'rubocop -d -P -S --enable-pending-cops'
101 |
102 | ###############################################################################
103 | # Define `test` template
104 | ###############################################################################
105 | .test_instance: &test_instance
106 | stage: *stage_test
107 | image: *image_dindruby
108 | services: *services_docker_dind
109 | variables: *variables_bundler
110 | cache: *cache_bundler
111 | before_script:
112 | # TODO: This should work from the env vars above automatically
113 | - 'bundle config set path "${BUNDLE_CACHE_PATH}"'
114 | - 'bundle config set without "${BUNDLE_WITHOUT}"'
115 | - 'bundle install'
116 | script:
117 | # Alternative value to consider: `${CI_JOB_NAME}`
118 | - 'bin/kitchen verify "${DOCKER_ENV_CI_JOB_NAME}"'
119 |
120 | ###############################################################################
121 | # Define `test` template (`allow_failure: true`)
122 | ###############################################################################
123 | .test_instance_failure_permitted:
124 | <<: *test_instance
125 | allow_failure: true
126 |
127 | ###############################################################################
128 | # `test` stage: each instance below uses the `test` template above
129 | ###############################################################################
130 | ## Define the rest of the matrix based on Kitchen testing
131 | # Make sure the instances listed below match up with
132 | # the `platforms` defined in `kitchen.yml`
133 | # yamllint disable rule:line-length
134 | # default-debian-11-tiamat-py3: {extends: '.test_instance'}
135 | # default-debian-10-tiamat-py3: {extends: '.test_instance'}
136 | # default-debian-9-tiamat-py3: {extends: '.test_instance'}
137 | # default-ubuntu-2204-tiamat-py3: {extends: '.test_instance_failure_permitted'}
138 | # default-ubuntu-2004-tiamat-py3: {extends: '.test_instance'}
139 | # default-ubuntu-1804-tiamat-py3: {extends: '.test_instance'}
140 | # default-centos-stream8-tiamat-py3: {extends: '.test_instance_failure_permitted'}
141 | # default-centos-7-tiamat-py3: {extends: '.test_instance'}
142 | # default-amazonlinux-2-tiamat-py3: {extends: '.test_instance'}
143 | # default-oraclelinux-8-tiamat-py3: {extends: '.test_instance'}
144 | # default-oraclelinux-7-tiamat-py3: {extends: '.test_instance'}
145 | # default-almalinux-8-tiamat-py3: {extends: '.test_instance'}
146 | # default-rockylinux-8-tiamat-py3: {extends: '.test_instance'}
147 | # default-debian-11-master-py3: {extends: '.test_instance'}
148 | # repo-debian-11-master-py3: {extends: '.test_instance'}
149 | debian-11-master-py3: {extends: '.test_instance'}
150 | # default-debian-10-master-py3: {extends: '.test_instance'}
151 | # repo-debian-10-master-py3: {extends: '.test_instance'}
152 | debian-10-master-py3: {extends: '.test_instance'}
153 | # default-debian-9-master-py3: {extends: '.test_instance'}
154 | # repo-debian-9-master-py3: {extends: '.test_instance'}
155 | debian-9-master-py3: {extends: '.test_instance'}
156 | # default-ubuntu-2204-master-py3: {extends: '.test_instance_failure_permitted'}
157 | # repo-ubuntu-2204-master-py3: {extends: '.test_instance_failure_permitted'}
158 | ubuntu-2204-master-py3: {extends: '.test_instance_failure_permitted'}
159 | # default-ubuntu-2004-master-py3: {extends: '.test_instance'}
160 | # repo-ubuntu-2004-master-py3: {extends: '.test_instance'}
161 | ubuntu-2004-master-py3: {extends: '.test_instance'}
162 | # default-ubuntu-1804-master-py3: {extends: '.test_instance'}
163 | # repo-ubuntu-1804-master-py3: {extends: '.test_instance'}
164 | ubuntu-1804-master-py3: {extends: '.test_instance'}
165 | # default-centos-stream8-master-py3: {extends: '.test_instance_failure_permitted'}
166 | # repo-centos-stream8-master-py3: {extends: '.test_instance_failure_permitted'}
167 | centos-stream8-master-py3: {extends: '.test_instance_failure_permitted'}
168 | # default-centos-7-master-py3: {extends: '.test_instance'}
169 | # repo-centos-7-master-py3: {extends: '.test_instance'}
170 | centos-7-master-py3: {extends: '.test_instance'}
171 | # default-fedora-36-master-py3: {extends: '.test_instance_failure_permitted'}
172 | # repo-fedora-36-master-py3: {extends: '.test_instance_failure_permitted'}
173 | fedora-36-master-py3: {extends: '.test_instance_failure_permitted'}
174 | # default-fedora-35-master-py3: {extends: '.test_instance'}
175 | # repo-fedora-35-master-py3: {extends: '.test_instance'}
176 | fedora-35-master-py3: {extends: '.test_instance'}
177 | # default-opensuse-leap-153-master-py3: {extends: '.test_instance'}
178 | # repo-opensuse-leap-153-master-py3: {extends: '.test_instance'}
179 | opensuse-leap-153-master-py3: {extends: '.test_instance'}
180 | default-opensuse-tmbl-latest-master-py3: {extends: '.test_instance_failure_permitted'}
181 | # opensuse-tmbl-latest-master-py3: {extends: '.test_instance_failure_permitted'}
182 | # default-amazonlinux-2-master-py3: {extends: '.test_instance'}
183 | # repo-amazonlinux-2-master-py3: {extends: '.test_instance'}
184 | amazonlinux-2-master-py3: {extends: '.test_instance'}
185 | # default-oraclelinux-8-master-py3: {extends: '.test_instance'}
186 | # repo-oraclelinux-8-master-py3: {extends: '.test_instance'}
187 | oraclelinux-8-master-py3: {extends: '.test_instance'}
188 | # default-oraclelinux-7-master-py3: {extends: '.test_instance'}
189 | # repo-oraclelinux-7-master-py3: {extends: '.test_instance'}
190 | oraclelinux-7-master-py3: {extends: '.test_instance'}
191 | default-arch-base-latest-master-py3: {extends: '.test_instance'}
192 | # arch-base-latest-master-py3: {extends: '.test_instance'}
193 | # default-gentoo-stage3-latest-master-py3: {extends: '.test_instance'}
194 | # gentoo-stage3-latest-master-py3: {extends: '.test_instance'}
195 | # default-gentoo-stage3-systemd-master-py3: {extends: '.test_instance'}
196 | # gentoo-stage3-systemd-master-py3: {extends: '.test_instance'}
197 | # default-almalinux-8-master-py3: {extends: '.test_instance'}
198 | # repo-almalinux-8-master-py3: {extends: '.test_instance'}
199 | almalinux-8-master-py3: {extends: '.test_instance'}
200 | # default-rockylinux-8-master-py3: {extends: '.test_instance'}
201 | # repo-rockylinux-8-master-py3: {extends: '.test_instance'}
202 | rockylinux-8-master-py3: {extends: '.test_instance'}
203 | # default-debian-11-3004-1-py3: {extends: '.test_instance'}
204 | # default-debian-10-3004-1-py3: {extends: '.test_instance'}
205 | # default-debian-9-3004-1-py3: {extends: '.test_instance'}
206 | # default-ubuntu-2204-3004-1-py3: {extends: '.test_instance_failure_permitted'}
207 | # default-ubuntu-2004-3004-1-py3: {extends: '.test_instance'}
208 | # default-ubuntu-1804-3004-1-py3: {extends: '.test_instance'}
209 | # default-centos-stream8-3004-1-py3: {extends: '.test_instance_failure_permitted'}
210 | # default-centos-7-3004-1-py3: {extends: '.test_instance'}
211 | # default-fedora-36-3004-1-py3: {extends: '.test_instance_failure_permitted'}
212 | # default-fedora-35-3004-1-py3: {extends: '.test_instance'}
213 | # default-amazonlinux-2-3004-1-py3: {extends: '.test_instance'}
214 | # default-oraclelinux-8-3004-1-py3: {extends: '.test_instance'}
215 | # default-oraclelinux-7-3004-1-py3: {extends: '.test_instance'}
216 | # default-arch-base-latest-3004-1-py3: {extends: '.test_instance'}
217 | # default-gentoo-stage3-latest-3004-1-py3: {extends: '.test_instance'}
218 | # default-gentoo-stage3-systemd-3004-1-py3: {extends: '.test_instance'}
219 | # default-almalinux-8-3004-1-py3: {extends: '.test_instance'}
220 | # default-rockylinux-8-3004-1-py3: {extends: '.test_instance'}
221 | # default-opensuse-leap-153-3004-0-py3: {extends: '.test_instance'}
222 | # default-opensuse-tmbl-latest-3004-0-py3: {extends: '.test_instance_failure_permitted'}
223 | # default-debian-10-3003-4-py3: {extends: '.test_instance'}
224 | # default-debian-9-3003-4-py3: {extends: '.test_instance'}
225 | # default-ubuntu-2004-3003-4-py3: {extends: '.test_instance'}
226 | # default-ubuntu-1804-3003-4-py3: {extends: '.test_instance'}
227 | # default-centos-stream8-3003-4-py3: {extends: '.test_instance_failure_permitted'}
228 | # default-centos-7-3003-4-py3: {extends: '.test_instance'}
229 | # default-amazonlinux-2-3003-4-py3: {extends: '.test_instance'}
230 | # default-oraclelinux-8-3003-4-py3: {extends: '.test_instance'}
231 | # default-oraclelinux-7-3003-4-py3: {extends: '.test_instance'}
232 | # default-almalinux-8-3003-4-py3: {extends: '.test_instance'}
233 | # yamllint enable rule:line-length
234 |
235 | ###############################################################################
236 | # `release` stage: `semantic-release`
237 | ###############################################################################
238 | semantic-release:
239 | only: *only_branch_master_parent_repo
240 | stage: *stage_release
241 | image: *image_semanticrelease
242 | variables:
243 | MAINTAINER_TOKEN: '${GH_TOKEN}'
244 | script:
245 | # Update `AUTHORS.md`
246 | - '${HOME}/go/bin/maintainer contributor'
247 | # Run `semantic-release`
248 | - 'semantic-release'
249 |
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # vim: ft=yaml
3 | ---
4 | # See https://pre-commit.com for more information
5 | # See https://pre-commit.com/hooks.html for more hooks
6 | ci:
7 | autofix_commit_msg: |
8 | ci(pre-commit.ci): apply auto fixes from pre-commit.com hooks
9 |
10 | For more information, see https://pre-commit.ci
11 | autofix_prs: true
12 | autoupdate_branch: ''
13 | autoupdate_commit_msg: |
14 | ci(pre-commit.ci): perform `pre-commit` autoupdate
15 | autoupdate_schedule: quarterly
16 | skip: []
17 | submodules: false
18 | default_stages: [commit]
19 | repos:
20 | - repo: https://github.com/dafyddj/commitlint-pre-commit-hook
21 | rev: v2.3.0
22 | hooks:
23 | - id: commitlint
24 | name: Check commit message using commitlint
25 | description: Lint commit message against @commitlint/config-conventional rules
26 | stages: [commit-msg]
27 | additional_dependencies: ['@commitlint/config-conventional@8.3.4']
28 | - id: commitlint-travis
29 | stages: [manual]
30 | additional_dependencies: ['@commitlint/config-conventional@8.3.4']
31 | always_run: true
32 | - repo: https://github.com/rubocop-hq/rubocop
33 | rev: v1.30.1
34 | hooks:
35 | - id: rubocop
36 | name: Check Ruby files with rubocop
37 | args: [--debug]
38 | always_run: true
39 | pass_filenames: false
40 | - repo: https://github.com/shellcheck-py/shellcheck-py
41 | rev: v0.8.0.4
42 | hooks:
43 | - id: shellcheck
44 | name: Check shell scripts with shellcheck
45 | files: ^.*\.(sh|bash|ksh)$
46 | types: []
47 | - repo: https://github.com/adrienverge/yamllint
48 | rev: v1.26.3
49 | hooks:
50 | - id: yamllint
51 | name: Check YAML syntax with yamllint
52 | args: [--strict, '.']
53 | always_run: true
54 | pass_filenames: false
55 | - repo: https://github.com/warpnet/salt-lint
56 | rev: v0.8.0
57 | hooks:
58 | - id: salt-lint
59 | name: Check Salt files using salt-lint
60 | files: ^.*\.(sls|jinja|j2|tmpl|tst)$
61 | - repo: https://github.com/myint/rstcheck
62 | rev: 3f929574
63 | hooks:
64 | - id: rstcheck
65 | name: Check reST files using rstcheck
66 | exclude: 'docs/CHANGELOG.rst'
67 | - repo: https://github.com/saltstack-formulas/mirrors-rst-lint
68 | rev: v1.3.2
69 | hooks:
70 | - id: rst-lint
71 | name: Check reST files using rst-lint
72 | exclude: |
73 | (?x)^(
74 | docs/CHANGELOG.rst|
75 | docs/TOFS_pattern.rst|
76 | )$
77 | additional_dependencies: [pygments==2.9.0]
78 |
--------------------------------------------------------------------------------
/.rstcheck.cfg:
--------------------------------------------------------------------------------
1 | [rstcheck]
2 | report=info
3 | ignore_language=rst
4 | ignore_messages=(Duplicate (ex|im)plicit target.*|Hyperlink target ".*" is not referenced\.$)
5 |
--------------------------------------------------------------------------------
/.rubocop.yml:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # vim: ft=yaml
3 | ---
4 | # General overrides used across formulas in the org
5 | Layout/LineLength:
6 | # Increase from default of `80`
7 | # Based on https://github.com/PyCQA/flake8-bugbear#opinionated-warnings (`B950`)
8 | Max: 88
9 | Metrics/BlockLength:
10 | IgnoredMethods:
11 | - control
12 | - describe
13 | # Increase from default of `25`
14 | Max: 30
15 | Security/YAMLLoad:
16 | Exclude:
17 | - test/integration/**/_mapdata.rb
18 |
19 | # General settings across all cops in this formula
20 | AllCops:
21 | NewCops: enable
22 |
23 | # Any offenses that should be fixed, e.g. collected via. `rubocop --auto-gen-config`
24 |
--------------------------------------------------------------------------------
/.salt-lint:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # vim: ft=yaml
3 | ---
4 | exclude_paths: []
5 | rules: {}
6 | skip_list:
7 | # Using `salt-lint` for linting other files as well, such as Jinja macros/templates
8 | - 205 # Use ".sls" as a Salt State file extension
9 | # Skipping `207` and `208` because `210` is sufficient, at least for the time-being
10 | # I.e. Allows 3-digit unquoted codes to still be used, such as `644` and `755`
11 | - 207 # File modes should always be encapsulated in quotation marks
12 | - 208 # File modes should always contain a leading zero
13 | tags: []
14 | verbosity: 1
15 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # vim: ft=yaml
3 | ---
4 | ################################################################################
5 | # NOTE: This file is UNMAINTAINED; it is provided for references purposes only.
6 | # No guarantees are tendered that this structure will work after 2020.
7 | ################################################################################
8 | # * https://en.wikipedia.org/wiki/Travis_CI:
9 | # - "... free open-source plans were removed in [sic] the end of 2020"
10 | # - https://blog.travis-ci.com/2020-11-02-travis-ci-new-billing
11 | # - https://ropensci.org/technotes/2020/11/19/moving-away-travis/
12 | ################################################################################
13 | ## Machine config
14 | os: 'linux'
15 | arch: 'amd64'
16 | dist: 'bionic'
17 | version: '~> 1.0'
18 |
19 | ## Language and cache config
20 | language: 'ruby'
21 | cache: 'bundler'
22 |
23 | ## Services config
24 | services:
25 | - docker
26 |
27 | ## Script to run for the test stage
28 | script:
29 | - bin/kitchen verify "${INSTANCE}"
30 |
31 | ## Stages and jobs matrix
32 | stages:
33 | - test
34 | # # As part of the switch away from Travis CI, ensure that the `release` stage
35 | # # is not run inadvertently
36 | # - name: 'release'
37 | # if: 'branch = master AND type != pull_request'
38 | jobs:
39 | include:
40 | ## Define the test stage that runs the linters (and testing matrix, if applicable)
41 |
42 | # Run all of the linters in a single job
43 | - language: 'node_js'
44 | node_js: 'lts/*'
45 | env: 'Lint'
46 | name: 'Lint: salt-lint, yamllint, rubocop, shellcheck & commitlint'
47 | before_install: 'skip'
48 | script:
49 | # Install and run `salt-lint`
50 | - pip install --user salt-lint
51 | - git ls-files -- '*.sls' '*.jinja' '*.j2' '*.tmpl' '*.tst'
52 | | xargs salt-lint
53 | # Install and run `yamllint`
54 | # Need at least `v1.17.0` for the `yaml-files` setting
55 | - pip install --user yamllint>=1.17.0
56 | - yamllint -s .
57 | # Install and run `rubocop`
58 | - gem install rubocop
59 | - rubocop -d
60 | # Run `shellcheck` (already pre-installed in Travis)
61 | - shellcheck --version
62 | - git ls-files -- '*.sh' '*.bash' '*.ksh'
63 | | xargs shellcheck
64 | # Install and run `commitlint`
65 | - npm i -D @commitlint/config-conventional
66 | @commitlint/travis-cli
67 | - commitlint-travis
68 |
69 | # Run `pre-commit` linters in a single job
70 | - language: 'python'
71 | env: 'Lint_pre-commit'
72 | name: 'Lint: pre-commit'
73 | before_install: 'skip'
74 | cache:
75 | directories:
76 | - $HOME/.cache/pre-commit
77 | script:
78 | # Install and run `pre-commit`
79 | - pip install pre-commit==2.7.1
80 | - pre-commit run --all-files --color always --verbose
81 | - pre-commit run --color always --hook-stage manual --verbose commitlint-travis
82 |
83 | ## Define the rest of the matrix based on Kitchen testing
84 | # Make sure the instances listed below match up with
85 | # the `platforms` defined in `kitchen.yml`
86 | # - env: INSTANCE=default-debian-11-tiamat-py3
87 | # - env: INSTANCE=default-debian-10-tiamat-py3
88 | # - env: INSTANCE=default-debian-9-tiamat-py3
89 | # - env: INSTANCE=default-ubuntu-2204-tiamat-py3
90 | # - env: INSTANCE=default-ubuntu-2004-tiamat-py3
91 | # - env: INSTANCE=default-ubuntu-1804-tiamat-py3
92 | # - env: INSTANCE=default-centos-stream8-tiamat-py3
93 | # - env: INSTANCE=default-centos-7-tiamat-py3
94 | # - env: INSTANCE=default-amazonlinux-2-tiamat-py3
95 | # - env: INSTANCE=default-oraclelinux-8-tiamat-py3
96 | # - env: INSTANCE=default-oraclelinux-7-tiamat-py3
97 | # - env: INSTANCE=default-almalinux-8-tiamat-py3
98 | # - env: INSTANCE=default-rockylinux-8-tiamat-py3
99 | # - env: INSTANCE=default-debian-11-master-py3
100 | # - env: INSTANCE=repo-debian-11-master-py3
101 | - env: INSTANCE=debian-11-master-py3
102 | # - env: INSTANCE=default-debian-10-master-py3
103 | # - env: INSTANCE=repo-debian-10-master-py3
104 | - env: INSTANCE=debian-10-master-py3
105 | # - env: INSTANCE=default-debian-9-master-py3
106 | # - env: INSTANCE=repo-debian-9-master-py3
107 | - env: INSTANCE=debian-9-master-py3
108 | # - env: INSTANCE=default-ubuntu-2204-master-py3
109 | # - env: INSTANCE=repo-ubuntu-2204-master-py3
110 | - env: INSTANCE=ubuntu-2204-master-py3
111 | # - env: INSTANCE=default-ubuntu-2004-master-py3
112 | # - env: INSTANCE=repo-ubuntu-2004-master-py3
113 | - env: INSTANCE=ubuntu-2004-master-py3
114 | # - env: INSTANCE=default-ubuntu-1804-master-py3
115 | # - env: INSTANCE=repo-ubuntu-1804-master-py3
116 | - env: INSTANCE=ubuntu-1804-master-py3
117 | # - env: INSTANCE=default-centos-stream8-master-py3
118 | # - env: INSTANCE=repo-centos-stream8-master-py3
119 | - env: INSTANCE=centos-stream8-master-py3
120 | # - env: INSTANCE=default-centos-7-master-py3
121 | # - env: INSTANCE=repo-centos-7-master-py3
122 | - env: INSTANCE=centos-7-master-py3
123 | # - env: INSTANCE=default-fedora-36-master-py3
124 | # - env: INSTANCE=repo-fedora-36-master-py3
125 | - env: INSTANCE=fedora-36-master-py3
126 | # - env: INSTANCE=default-fedora-35-master-py3
127 | # - env: INSTANCE=repo-fedora-35-master-py3
128 | - env: INSTANCE=fedora-35-master-py3
129 | # - env: INSTANCE=default-opensuse-leap-153-master-py3
130 | # - env: INSTANCE=repo-opensuse-leap-153-master-py3
131 | - env: INSTANCE=opensuse-leap-153-master-py3
132 | - env: INSTANCE=default-opensuse-tmbl-latest-master-py3
133 | # - env: INSTANCE=opensuse-tmbl-latest-master-py3
134 | # - env: INSTANCE=default-amazonlinux-2-master-py3
135 | # - env: INSTANCE=repo-amazonlinux-2-master-py3
136 | - env: INSTANCE=amazonlinux-2-master-py3
137 | # - env: INSTANCE=default-oraclelinux-8-master-py3
138 | # - env: INSTANCE=repo-oraclelinux-8-master-py3
139 | - env: INSTANCE=oraclelinux-8-master-py3
140 | # - env: INSTANCE=default-oraclelinux-7-master-py3
141 | # - env: INSTANCE=repo-oraclelinux-7-master-py3
142 | - env: INSTANCE=oraclelinux-7-master-py3
143 | - env: INSTANCE=default-arch-base-latest-master-py3
144 | # - env: INSTANCE=arch-base-latest-master-py3
145 | # - env: INSTANCE=default-gentoo-stage3-latest-master-py3
146 | # - env: INSTANCE=gentoo-stage3-latest-master-py3
147 | # - env: INSTANCE=default-gentoo-stage3-systemd-master-py3
148 | # - env: INSTANCE=gentoo-stage3-systemd-master-py3
149 | # - env: INSTANCE=default-almalinux-8-master-py3
150 | # - env: INSTANCE=repo-almalinux-8-master-py3
151 | - env: INSTANCE=almalinux-8-master-py3
152 | # - env: INSTANCE=default-rockylinux-8-master-py3
153 | # - env: INSTANCE=repo-rockylinux-8-master-py3
154 | - env: INSTANCE=rockylinux-8-master-py3
155 | # - env: INSTANCE=default-debian-11-3004-1-py3
156 | # - env: INSTANCE=default-debian-10-3004-1-py3
157 | # - env: INSTANCE=default-debian-9-3004-1-py3
158 | # - env: INSTANCE=default-ubuntu-2204-3004-1-py3
159 | # - env: INSTANCE=default-ubuntu-2004-3004-1-py3
160 | # - env: INSTANCE=default-ubuntu-1804-3004-1-py3
161 | # - env: INSTANCE=default-centos-stream8-3004-1-py3
162 | # - env: INSTANCE=default-centos-7-3004-1-py3
163 | # - env: INSTANCE=default-fedora-36-3004-1-py3
164 | # - env: INSTANCE=default-fedora-35-3004-1-py3
165 | # - env: INSTANCE=default-amazonlinux-2-3004-1-py3
166 | # - env: INSTANCE=default-oraclelinux-8-3004-1-py3
167 | # - env: INSTANCE=default-oraclelinux-7-3004-1-py3
168 | # - env: INSTANCE=default-arch-base-latest-3004-1-py3
169 | # - env: INSTANCE=default-gentoo-stage3-latest-3004-1-py3
170 | # - env: INSTANCE=default-gentoo-stage3-systemd-3004-1-py3
171 | # - env: INSTANCE=default-almalinux-8-3004-1-py3
172 | # - env: INSTANCE=default-rockylinux-8-3004-1-py3
173 | # - env: INSTANCE=default-opensuse-leap-153-3004-0-py3
174 | # - env: INSTANCE=default-opensuse-tmbl-latest-3004-0-py3
175 | # - env: INSTANCE=default-debian-10-3003-4-py3
176 | # - env: INSTANCE=default-debian-9-3003-4-py3
177 | # - env: INSTANCE=default-ubuntu-2004-3003-4-py3
178 | # - env: INSTANCE=default-ubuntu-1804-3003-4-py3
179 | # - env: INSTANCE=default-centos-stream8-3003-4-py3
180 | # - env: INSTANCE=default-centos-7-3003-4-py3
181 | # - env: INSTANCE=default-amazonlinux-2-3003-4-py3
182 | # - env: INSTANCE=default-oraclelinux-8-3003-4-py3
183 | # - env: INSTANCE=default-oraclelinux-7-3003-4-py3
184 | # - env: INSTANCE=default-almalinux-8-3003-4-py3
185 |
186 | ## Define the release stage that runs `semantic-release`
187 | - stage: 'release'
188 | language: 'node_js'
189 | node_js: 'lts/*'
190 | env: 'Release'
191 | name: 'Run semantic-release inc. file updates to AUTHORS, CHANGELOG & FORMULA'
192 | before_install: 'skip'
193 | script:
194 | # Update `AUTHORS.md`
195 | - export MAINTAINER_TOKEN=${GH_TOKEN}
196 | - go get github.com/myii/maintainer
197 | - maintainer contributor
198 |
199 | # Install all dependencies required for `semantic-release`
200 | - npm i -D @semantic-release/changelog@3
201 | @semantic-release/exec@3
202 | @semantic-release/git@7
203 | deploy:
204 | provider: 'script'
205 | # Opt-in to `dpl v2` to complete the Travis build config validation (beta)
206 | # * https://docs.travis-ci.com/user/build-config-validation
207 | # Deprecated `skip_cleanup` can now be avoided, `cleanup: false` is by default
208 | edge: true
209 | # Run `semantic-release`
210 | script: 'npx semantic-release@15.14'
211 |
212 | # Notification options: `always`, `never` or `change`
213 | notifications:
214 | webhooks:
215 | if: 'repo = saltstack-formulas/postgres-formula'
216 | urls:
217 | - https://saltstack-formulas.zulipchat.com/api/v1/external/travis?api_key=HsIq3o5QmLxdnVCKF9is0FUIpkpAY79P&stream=CI&topic=saltstack-formulas%2Fpostgres-formula&ignore_pull_requests=true
218 | on_success: always # default: always
219 | on_failure: always # default: always
220 | on_start: always # default: never
221 | on_cancel: always # default: always
222 | on_error: always # default: always
223 |
--------------------------------------------------------------------------------
/.yamllint:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # vim: ft=yaml
3 | ---
4 | # Extend the `default` configuration provided by `yamllint`
5 | extends: 'default'
6 |
7 | # Files to ignore completely
8 | # 1. All YAML files under directory `.bundle/`, introduced if gems are installed locally
9 | # 2. All YAML files under directory `.cache/`, introduced during the CI run
10 | # 3. All YAML files under directory `.git/`
11 | # 4. All YAML files under directory `node_modules/`, introduced during the CI run
12 | # 5. Any SLS files under directory `test/`, which are actually state files
13 | # 6. Any YAML files under directory `.kitchen/`, introduced during local testing
14 | # 7. `kitchen.vagrant.yml`, which contains Embedded Ruby (ERB) template syntax
15 | # 8. All YAML files heavily reliant on Jinja; these can be tackled in a subsequent PR
16 | ignore: |
17 | .bundle/
18 | .cache/
19 | .git/
20 | node_modules/
21 | test/**/states/**/*.sls
22 | .kitchen/
23 | kitchen.vagrant.yml
24 | pillar.example
25 | postgres/codenamemap.yaml
26 | postgres/osfamilymap.yaml
27 | postgres/osmap.yaml
28 | postgres/repo.yaml
29 | test/salt/pillar/postgres.sls
30 |
31 | yaml-files:
32 | # Default settings
33 | - '*.yaml'
34 | - '*.yml'
35 | - .salt-lint
36 | - .yamllint
37 | # SaltStack Formulas additional settings
38 | - '*.example'
39 | - test/**/*.sls
40 |
41 | rules:
42 | empty-values:
43 | forbid-in-block-mappings: true
44 | forbid-in-flow-mappings: true
45 | line-length:
46 | # Increase from default of `80`
47 | # Based on https://github.com/PyCQA/flake8-bugbear#opinionated-warnings (`B950`)
48 | max: 88
49 | octal-values:
50 | forbid-implicit-octal: true
51 | forbid-explicit-octal: true
52 |
--------------------------------------------------------------------------------
/AUTHORS.md:
--------------------------------------------------------------------------------
1 | # Authors
2 |
3 | This list is sorted by the number of commits per contributor in _descending_ order.
4 |
5 | Avatar|Contributor|Contributions
6 | :-:|---|:-:
7 |
|[@myii](https://github.com/myii)|229
8 |
|[@noelmcloughlin](https://github.com/noelmcloughlin)|79
9 |
|[@aboe76](https://github.com/aboe76)|54
10 |
|[@gravyboat](https://github.com/gravyboat)|41
11 |
|[@javierbertoli](https://github.com/javierbertoli)|24
12 |
|[@nmadhok](https://github.com/nmadhok)|19
13 |
|[@vutny](https://github.com/vutny)|18
14 |
|[@puneetk](https://github.com/puneetk)|11
15 |
|[@EvaSDK](https://github.com/EvaSDK)|9
16 |
|[@dferramosi](https://github.com/dferramosi)|8
17 |
|[@johnkeates](https://github.com/johnkeates)|8
18 |
|[@litnialex](https://github.com/litnialex)|8
19 |
|[@whiteinge](https://github.com/whiteinge)|8
20 |
|[@wolodjawentland](https://github.com/wolodjawentland)|8
21 |
|[@iggy](https://github.com/iggy)|7
22 |
|[@dynjnelson](https://github.com/dynjnelson)|7
23 |
|[@rominf](https://github.com/rominf)|7
24 |
|[@alxwr](https://github.com/alxwr)|5
25 |
|[@audreyfeldroy](https://github.com/audreyfeldroy)|5
26 |
|[@blast-hardcheese](https://github.com/blast-hardcheese)|5
27 |
|[@gilou](https://github.com/gilou)|5
28 |
|[@techhat](https://github.com/techhat)|5
29 |
|[@t0fik](https://github.com/t0fik)|5
30 |
|[@stp-ip](https://github.com/stp-ip)|4
31 |
|[@blbradley](https://github.com/blbradley)|3
32 |
|[@dafyddj](https://github.com/dafyddj)|3
33 |
|[@abrefort](https://github.com/abrefort)|3
34 |
|[@renoirb](https://github.com/renoirb)|3
35 |
|[@Ken-2scientists](https://github.com/Ken-2scientists)|2
36 |
|[@madssj](https://github.com/madssj)|2
37 |
|[@tgoodaire](https://github.com/tgoodaire)|2
38 |
|[@sticky-note](https://github.com/sticky-note)|2
39 |
|[@durana](https://github.com/durana)|1
40 |
|[@bebosudo](https://github.com/bebosudo)|1
41 |
|[@sarcastic-coder](https://github.com/sarcastic-coder)|1
42 |
|[@SuperTux88](https://github.com/SuperTux88)|1
43 |
|[@brot](https://github.com/brot)|1
44 |
|[@xbglowx](https://github.com/xbglowx)|1
45 |
|[@cro](https://github.com/cro)|1
46 |
|[@campbellmc](https://github.com/campbellmc)|1
47 |
|[@baby-gnu](https://github.com/baby-gnu)|1
48 |
|[@UtahDave](https://github.com/UtahDave)|1
49 |
|[@fcrozat](https://github.com/fcrozat)|1
50 |
|[@Laogeodritt](https://github.com/Laogeodritt)|1
51 |
|[@itbabu](https://github.com/itbabu)|1
52 |
|[@mkotsbak](https://github.com/mkotsbak)|1
53 |
|[@mattysads](https://github.com/mattysads)|1
54 |
|[@mbrannigan](https://github.com/mbrannigan)|1
55 |
|[@n-rodriguez](https://github.com/n-rodriguez)|1
56 |
|[@SamJoan](https://github.com/SamJoan)|1
57 |
|[@rmoorman](https://github.com/rmoorman)|1
58 |
|[@skurfer](https://github.com/skurfer)|1
59 |
|[@RobRuana](https://github.com/RobRuana)|1
60 |
|[@sbrefort](https://github.com/sbrefort)|1
61 |
|[@sbellem](https://github.com/sbellem)|1
62 |
|[@retrry](https://github.com/retrry)|1
63 |
|[@thomasrossetto](https://github.com/thomasrossetto)|1
64 |
|[@thatch45](https://github.com/thatch45)|1
65 |
|[@tobio](https://github.com/tobio)|1
66 |
|[@XRasher](https://github.com/XRasher)|1
67 |
|[@YetAnotherMinion](https://github.com/YetAnotherMinion)|1
68 |
|[@ek9](https://github.com/ek9)|1
69 |
|[@Strade288](https://github.com/Strade288)|1
70 |
|[@daks](https://github.com/daks)|1
71 |
72 | ---
73 |
74 | Auto-generated by a [forked version](https://github.com/myii/maintainer) of [gaocegege/maintainer](https://github.com/gaocegege/maintainer) on 2022-07-18.
75 |
--------------------------------------------------------------------------------
/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners
2 |
3 | # SECTION: Owner(s) for everything in the repo, unless a later match takes precedence
4 | # FILE PATTERN OWNER(S)
5 | * @vutny @myii
6 |
7 | # SECTION: Owner(s) for specific directories
8 | # FILE PATTERN OWNER(S)
9 |
10 | # SECTION: Owner(s) for files/directories related to `semantic-release`
11 | # FILE PATTERN OWNER(S)
12 | /.github/workflows/ @saltstack-formulas/ssf
13 | /bin/install-hooks @saltstack-formulas/ssf
14 | /bin/kitchen @saltstack-formulas/ssf
15 | /docs/AUTHORS.rst @saltstack-formulas/ssf
16 | /docs/CHANGELOG.rst @saltstack-formulas/ssf
17 | /docs/TOFS_pattern.rst @saltstack-formulas/ssf
18 | /*/_mapdata/ @saltstack-formulas/ssf
19 | /*/libsaltcli.jinja @saltstack-formulas/ssf
20 | /*/libtofs.jinja @saltstack-formulas/ssf
21 | /test/integration/**/_mapdata.rb @saltstack-formulas/ssf
22 | /test/integration/**/libraries/system.rb @saltstack-formulas/ssf
23 | /test/integration/**/inspec.yml @saltstack-formulas/ssf
24 | /test/integration/**/README.md @saltstack-formulas/ssf
25 | /test/salt/pillar/top.sls @saltstack-formulas/ssf
26 | /.gitignore @saltstack-formulas/ssf
27 | /.cirrus.yml @saltstack-formulas/ssf
28 | /.gitlab-ci.yml @saltstack-formulas/ssf
29 | /.pre-commit-config.yaml @saltstack-formulas/ssf
30 | /.rstcheck.cfg @saltstack-formulas/ssf
31 | /.rubocop.yml @saltstack-formulas/ssf
32 | /.salt-lint @saltstack-formulas/ssf
33 | /.travis.yml @saltstack-formulas/ssf
34 | /.yamllint @saltstack-formulas/ssf
35 | /AUTHORS.md @saltstack-formulas/ssf
36 | /CHANGELOG.md @saltstack-formulas/ssf
37 | /CODEOWNERS @saltstack-formulas/ssf
38 | /commitlint.config.js @saltstack-formulas/ssf
39 | /FORMULA @saltstack-formulas/ssf
40 | /Gemfile @saltstack-formulas/ssf
41 | /Gemfile.lock @saltstack-formulas/ssf
42 | /kitchen.yml @saltstack-formulas/ssf
43 | /kitchen.vagrant.yml @saltstack-formulas/ssf
44 | /kitchen.windows.yml @saltstack-formulas/ssf
45 | /pre-commit_semantic-release.sh @saltstack-formulas/ssf
46 | /release-rules.js @saltstack-formulas/ssf
47 | /release.config.js @saltstack-formulas/ssf
48 |
49 | # SECTION: Owner(s) for specific files
50 | # FILE PATTERN OWNER(S)
51 |
--------------------------------------------------------------------------------
/FORMULA:
--------------------------------------------------------------------------------
1 | name: postgres
2 | os: Debian, Ubuntu, Raspbian, RedHat, Fedora, CentOS, Suse, openSUSE, Gentoo, Funtoo, Arch, Manjaro, Alpine, FreeBSD, OpenBSD, Solaris, SmartOS, Windows, MacOS
3 | os_family: Debian, RedHat, Suse, Gentoo, Arch, Alpine, FreeBSD, OpenBSD, Solaris, Windows, MacOS
4 | version: 0.45.0
5 | release: 1
6 | minimum_version: 2016.11
7 | summary: Postgres formula
8 | description: Formula to install and configure PostgreSQL
9 | top_level_dir: postgres
10 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | source ENV.fetch('PROXY_RUBYGEMSORG', 'https://rubygems.org')
4 |
5 | # Install the `inspec` gem using `git` because versions after `4.22.22`
6 | # suppress diff output; this version fixes this for our uses.
7 | # rubocop:disable Layout/LineLength
8 | gem 'inspec', git: 'https://gitlab.com/saltstack-formulas/infrastructure/inspec', branch: 'ssf'
9 | # rubocop:enable Layout/LineLength
10 |
11 | # Install the `kitchen-docker` gem using `git` in order to gain a performance
12 | # improvement: avoid package installations which are already covered by the
13 | # `salt-image-builder` (i.e. the pre-salted images that we're using)
14 | # rubocop:disable Layout/LineLength
15 | gem 'kitchen-docker', git: 'https://gitlab.com/saltstack-formulas/infrastructure/kitchen-docker', branch: 'ssf'
16 | # rubocop:enable Layout/LineLength
17 |
18 | gem 'kitchen-inspec', '>= 2.5.0'
19 | gem 'kitchen-salt', '>= 0.7.2'
20 |
21 | group :vagrant do
22 | gem 'kitchen-vagrant'
23 | end
24 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013-2015 Salt Stack Formulas
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 |
--------------------------------------------------------------------------------
/bin/install-hooks:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | set -o nounset # Treat unset variables as an error and immediately exit
3 | set -o errexit # If a command fails exit the whole script
4 |
5 | if [ "${DEBUG:-false}" = "true" ]; then
6 | set -x # Run the entire script in debug mode
7 | fi
8 |
9 | if ! command -v pre-commit >/dev/null 2>&1; then
10 | echo "pre-commit not found: please install or check your PATH" >&2
11 | echo "See https://pre-commit.com/#installation" >&2
12 | exit 1
13 | fi
14 |
15 | pre-commit install --install-hooks
16 | pre-commit install --hook-type commit-msg --install-hooks
17 |
--------------------------------------------------------------------------------
/bin/kitchen:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | #
5 | # This file was generated by Bundler.
6 | #
7 | # The application 'kitchen' is installed as part of a gem, and
8 | # this file is here to facilitate running it.
9 | #
10 |
11 | require 'pathname'
12 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
13 | Pathname.new(__FILE__).realpath)
14 |
15 | bundle_binstub = File.expand_path('bundle', __dir__)
16 |
17 | if File.file?(bundle_binstub)
18 | if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19 | load(bundle_binstub)
20 | else
21 | abort(
22 | 'Your `bin/bundle` was not generated by Bundler, ' \
23 | 'so this binstub cannot run. Replace `bin/bundle` by running ' \
24 | '`bundle binstubs bundler --force`, then run this command again.'
25 | )
26 | end
27 | end
28 |
29 | require 'rubygems'
30 | require 'bundler/setup'
31 |
32 | load Gem.bin_path('test-kitchen', 'kitchen')
33 |
--------------------------------------------------------------------------------
/commitlint.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['@commitlint/config-conventional'],
3 | rules: {
4 | 'body-max-line-length': [2, 'always', 120],
5 | 'footer-max-line-length': [2, 'always', 120],
6 | 'header-max-length': [2, 'always', 72],
7 | },
8 | };
9 |
--------------------------------------------------------------------------------
/docs/AUTHORS.rst:
--------------------------------------------------------------------------------
1 | .. role:: raw-html-m2r(raw)
2 | :format: html
3 |
4 |
5 | Authors
6 | =======
7 |
8 | This list is sorted by the number of commits per contributor in *descending* order.
9 |
10 | .. list-table::
11 | :header-rows: 1
12 |
13 | * - Avatar
14 | - Contributor
15 | - Contributions
16 | * - :raw-html-m2r:`
`
17 | - `@myii `_
18 | - 201
19 | * - :raw-html-m2r:`
`
20 | - `@noelmcloughlin `_
21 | - 79
22 | * - :raw-html-m2r:`
`
23 | - `@aboe76 `_
24 | - 54
25 | * - :raw-html-m2r:`
`
26 | - `@gravyboat `_
27 | - 41
28 | * - :raw-html-m2r:`
`
29 | - `@javierbertoli `_
30 | - 24
31 | * - :raw-html-m2r:`
`
32 | - `@nmadhok `_
33 | - 19
34 | * - :raw-html-m2r:`
`
35 | - `@vutny `_
36 | - 18
37 | * - :raw-html-m2r:`
`
38 | - `@puneetk `_
39 | - 11
40 | * - :raw-html-m2r:`
`
41 | - `@EvaSDK `_
42 | - 9
43 | * - :raw-html-m2r:`
`
44 | - `@dferramosi `_
45 | - 8
46 | * - :raw-html-m2r:`
`
47 | - `@johnkeates `_
48 | - 8
49 | * - :raw-html-m2r:`
`
50 | - `@litnialex `_
51 | - 8
52 | * - :raw-html-m2r:`
`
53 | - `@whiteinge `_
54 | - 8
55 | * - :raw-html-m2r:`
`
56 | - `@babilen `_
57 | - 8
58 | * - :raw-html-m2r:`
`
59 | - `@iggy `_
60 | - 7
61 | * - :raw-html-m2r:`
`
62 | - `@dynjnelson `_
63 | - 7
64 | * - :raw-html-m2r:`
`
65 | - `@rominf `_
66 | - 7
67 | * - :raw-html-m2r:`
`
68 | - `@alxwr `_
69 | - 5
70 | * - :raw-html-m2r:`
`
71 | - `@audreyfeldroy `_
72 | - 5
73 | * - :raw-html-m2r:`
`
74 | - `@blast-hardcheese `_
75 | - 5
76 | * - :raw-html-m2r:`
`
77 | - `@gilou `_
78 | - 5
79 | * - :raw-html-m2r:`
`
80 | - `@techhat `_
81 | - 5
82 | * - :raw-html-m2r:`
`
83 | - `@t0fik `_
84 | - 5
85 | * - :raw-html-m2r:`
`
86 | - `@stp-ip `_
87 | - 4
88 | * - :raw-html-m2r:`
`
89 | - `@blbradley `_
90 | - 3
91 | * - :raw-html-m2r:`
`
92 | - `@dafyddj `_
93 | - 3
94 | * - :raw-html-m2r:`
`
95 | - `@abrefort `_
96 | - 3
97 | * - :raw-html-m2r:`
`
98 | - `@renoirb `_
99 | - 3
100 | * - :raw-html-m2r:`
`
101 | - `@Ken-2scientists `_
102 | - 2
103 | * - :raw-html-m2r:`
`
104 | - `@madssj `_
105 | - 2
106 | * - :raw-html-m2r:`
`
107 | - `@tgoodaire `_
108 | - 2
109 | * - :raw-html-m2r:`
`
110 | - `@sticky-note `_
111 | - 2
112 | * - :raw-html-m2r:`
`
113 | - `@durana `_
114 | - 1
115 | * - :raw-html-m2r:`
`
116 | - `@bebosudo `_
117 | - 1
118 | * - :raw-html-m2r:`
`
119 | - `@sarcastic-coder `_
120 | - 1
121 | * - :raw-html-m2r:`
`
122 | - `@SuperTux88 `_
123 | - 1
124 | * - :raw-html-m2r:`
`
125 | - `@brot `_
126 | - 1
127 | * - :raw-html-m2r:`
`
128 | - `@xbglowx `_
129 | - 1
130 | * - :raw-html-m2r:`
`
131 | - `@cro `_
132 | - 1
133 | * - :raw-html-m2r:`
`
134 | - `@campbellmc `_
135 | - 1
136 | * - :raw-html-m2r:`
`
137 | - `@baby-gnu `_
138 | - 1
139 | * - :raw-html-m2r:`
`
140 | - `@UtahDave `_
141 | - 1
142 | * - :raw-html-m2r:`
`
143 | - `@fcrozat `_
144 | - 1
145 | * - :raw-html-m2r:`
`
146 | - `@Laogeodritt `_
147 | - 1
148 | * - :raw-html-m2r:`
`
149 | - `@itbabu `_
150 | - 1
151 | * - :raw-html-m2r:`
`
152 | - `@mkotsbak `_
153 | - 1
154 | * - :raw-html-m2r:`
`
155 | - `@mattysads `_
156 | - 1
157 | * - :raw-html-m2r:`
`
158 | - `@mbrannigan `_
159 | - 1
160 | * - :raw-html-m2r:`
`
161 | - `@n-rodriguez `_
162 | - 1
163 | * - :raw-html-m2r:`
`
164 | - `@SamJoan `_
165 | - 1
166 | * - :raw-html-m2r:`
`
167 | - `@rmoorman `_
168 | - 1
169 | * - :raw-html-m2r:`
`
170 | - `@skurfer `_
171 | - 1
172 | * - :raw-html-m2r:`
`
173 | - `@RobRuana `_
174 | - 1
175 | * - :raw-html-m2r:`
`
176 | - `@sbrefort `_
177 | - 1
178 | * - :raw-html-m2r:`
`
179 | - `@sbellem `_
180 | - 1
181 | * - :raw-html-m2r:`
`
182 | - `@retrry `_
183 | - 1
184 | * - :raw-html-m2r:`
`
185 | - `@thomasrossetto `_
186 | - 1
187 | * - :raw-html-m2r:`
`
188 | - `@thatch45 `_
189 | - 1
190 | * - :raw-html-m2r:`
`
191 | - `@tobio `_
192 | - 1
193 | * - :raw-html-m2r:`
`
194 | - `@XRasher `_
195 | - 1
196 | * - :raw-html-m2r:`
`
197 | - `@YetAnotherMinion `_
198 | - 1
199 | * - :raw-html-m2r:`
`
200 | - `@ek9 `_
201 | - 1
202 | * - :raw-html-m2r:`
`
203 | - `@Strade288 `_
204 | - 1
205 | * - :raw-html-m2r:`
`
206 | - `@daks `_
207 | - 1
208 |
209 |
210 | ----
211 |
212 | Auto-generated by a `forked version `_ of `gaocegege/maintainer `_ on 2022-02-07.
213 |
--------------------------------------------------------------------------------
/docs/README.rst:
--------------------------------------------------------------------------------
1 | postgres-formula
2 | ================
3 |
4 | |img_travis| |img_sr|
5 |
6 | .. |img_travis| image:: https://travis-ci.com/saltstack-formulas/postgres-formula.svg?branch=master
7 | :alt: Travis CI Build Status
8 | :scale: 100%
9 | :target: https://travis-ci.com/saltstack-formulas/postgres-formula
10 | .. |img_sr| image:: https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg
11 | :alt: Semantic Release
12 | :scale: 100%
13 | :target: https://github.com/semantic-release/semantic-release
14 |
15 | A formula to install and configure PostgreSQL server.
16 |
17 | .. contents:: **Table of Contents**
18 |
19 | General notes
20 | -------------
21 |
22 | See the full `SaltStack Formulas installation and usage instructions
23 | `_.
24 |
25 | If you are interested in writing or contributing to formulas, please pay attention to the `Writing Formula Section
26 | `_.
27 |
28 | If you want to use this formula, please pay attention to the ``FORMULA`` file and/or ``git tag``,
29 | which contains the currently released version. This formula is versioned according to `Semantic Versioning `_.
30 |
31 | See `Formula Versioning Section `_ for more details.
32 |
33 | Contributing to this repo
34 | -------------------------
35 |
36 | **Commit message formatting is significant!!**
37 |
38 | Please see `How to contribute `_ for more details.
39 |
40 | Available states
41 | ----------------
42 |
43 | .. contents::
44 | :local:
45 |
46 | ``postgres``
47 | ^^^^^^^^^^^^
48 |
49 | Installs and configures both PostgreSQL server and client with creation of various DB objects in
50 | the cluster. This state applies to both Linux and MacOS.
51 |
52 | ``postgres.client``
53 | ^^^^^^^^^^^^^^^^^^^
54 |
55 | Installs the PostgreSQL client binaries and libraries on Linux.
56 |
57 | ``postgres.manage``
58 | ^^^^^^^^^^^^^^^^^^^
59 |
60 | Creates such DB objects as: users, tablespaces, databases, schemas and extensions.
61 | See ``pillar.example`` file for details.
62 |
63 | ``postgres.python``
64 | ^^^^^^^^^^^^^^^^^^^
65 |
66 | Installs the PostgreSQL adapter for Python on Linux.
67 |
68 | ``postgres.server``
69 | ^^^^^^^^^^^^^^^^^^^
70 |
71 | Installs the PostgreSQL server package on Linux, prepares the DB cluster and starts the server using
72 | packaged init script, job or unit.
73 |
74 |
75 | .. note::
76 |
77 | For PostgreSQL server before version 10 to work inside a **FreeBSD Jail**
78 | set ``sysvshm=new`` and ``sysvsem=new``.
79 | DO NOT SET ``allow.sysvipc=1``. It defeats the purpose of using Jails.
80 |
81 | Further information: https://blog.tyk.nu/blog/freebsd-jails-and-sysv-ipc/
82 |
83 |
84 | **Running inside a container** (using Packer, Docker or similar tools), when OS ``init`` process
85 | is not available to start the service and enable it on "boot", set pillar value:
86 |
87 | .. code:: yaml
88 |
89 | postgres:
90 | bake_image: True
91 |
92 | This toggles starting PostgreSQL daemon by issuing raw ``pg_ctl`` or ``pg_ctlcluster`` command.
93 |
94 | ``postgres.upstream``
95 | ^^^^^^^^^^^^^^^^^^^^^
96 |
97 | Configures the PostgreSQL Official (upstream) repository on target system if
98 | applicable.
99 |
100 | The state relies on the ``postgres:use_upstream_repo`` Pillar value which could be set as following:
101 |
102 | * ``True`` (default): adds the upstream repository to install packages from
103 | * ``False``: makes sure that the repository configuration is absent
104 | * ``'postgresapp'`` (MacOS) uses upstream PostgresApp package repository.
105 | * ``'homebrew'`` (MacOS) uses Homebrew postgres
106 |
107 | The ``postgres:version`` Pillar controls which version of the PostgreSQL packages should be
108 | installed from the upstream Linux repository. Defaults to ``9.5``.
109 |
110 |
111 | Removal states
112 | --------------
113 |
114 | ``postgres.dropped``
115 | ^^^^^^^^^^^^^^^^^^^^
116 |
117 | Meta state to remove Postgres software. By default the release installed by formula is targeted only. To target multiple releases, set pillar ``postgres.remove.multiple_releases: True``.
118 |
119 | ``postgres.server.remove``
120 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
121 |
122 | Remove server, lib, and contrib packages. The ``postgres.server.remove`` will retain data by default (no data loss) - set pillar ``postgres.remove.data: True`` to remove data and configuration directories also.
123 |
124 | ``postgres.client.remove``
125 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
126 |
127 | Remove client package.
128 |
129 | ``postgres.dev.remove``
130 | ^^^^^^^^^^^^^^^^^^^^^^^
131 |
132 | Remove development and python packages.
133 |
134 |
135 | Testing
136 | -------
137 |
138 | Linux testing is done with ``kitchen-salt``.
139 |
140 | ``kitchen converge``
141 | ^^^^^^^^^^^^^^^^^^^^
142 |
143 | Creates the docker instance and runs the ``postgres`` main state, ready for testing.
144 |
145 | ``kitchen verify``
146 | ^^^^^^^^^^^^^^^^^^
147 |
148 | Runs the ``inspec`` tests on the actual instance.
149 |
150 | ``kitchen destroy``
151 | ^^^^^^^^^^^^^^^^^^^
152 |
153 | Removes the docker instance.
154 |
155 | ``kitchen test``
156 | ^^^^^^^^^^^^^^^^
157 |
158 | Runs all of the stages above in one go: i.e. ``destroy`` + ``converge`` + ``verify`` + ``destroy``.
159 |
160 | ``kitchen login``
161 | ^^^^^^^^^^^^^^^^^
162 |
163 | Gives you SSH access to the instance for manual testing.
164 |
165 | Testing with Vagrant
166 | --------------------
167 |
168 | Windows/FreeBSD/OpenBSD testing is done with ``kitchen-salt``.
169 |
170 | Requirements
171 | ^^^^^^^^^^^^
172 |
173 | * Ruby
174 | * Virtualbox
175 | * Vagrant
176 |
177 | Setup
178 | ^^^^^
179 |
180 | .. code-block:: bash
181 |
182 | $ gem install bundler
183 | $ bundle install --with=vagrant
184 | $ bin/kitchen test [platform]
185 |
186 | Where ``[platform]`` is the platform name defined in ``kitchen.vagrant.yml``,
187 | e.g. ``windows-81-latest-py3``.
188 |
189 | Note
190 | ^^^^
191 |
192 | When testing using Vagrant you must set the environment variable ``KITCHEN_LOCAL_YAML`` to ``kitchen.vagrant.yml``. For example:
193 |
194 | .. code-block:: bash
195 |
196 | $ KITCHEN_LOCAL_YAML=kitchen.vagrant.yml bin/kitchen test # Alternatively,
197 | $ export KITCHEN_LOCAL_YAML=kitchen.vagrant.yml
198 | $ bin/kitchen test
199 |
200 | Then run the following commands as needed.
201 |
202 | ``bin/kitchen converge``
203 | ^^^^^^^^^^^^^^^^^^^^^^^^
204 |
205 | Creates the Vagrant instance and runs the ``postgres`` main state, ready for testing.
206 |
207 | ``bin/kitchen verify``
208 | ^^^^^^^^^^^^^^^^^^^^^^
209 |
210 | Runs the ``inspec`` tests on the actual instance.
211 |
212 | ``bin/kitchen destroy``
213 | ^^^^^^^^^^^^^^^^^^^^^^^
214 |
215 | Removes the Vagrant instance.
216 |
217 | ``bin/kitchen test``
218 | ^^^^^^^^^^^^^^^^^^^^
219 |
220 | Runs all of the stages above in one go: i.e. ``destroy`` + ``converge`` + ``verify`` + ``destroy``.
221 |
222 | ``bin/kitchen login``
223 | ^^^^^^^^^^^^^^^^^^^^^
224 |
225 | Gives you RDP/SSH access to the instance for manual testing.
226 |
227 | .. vim: fenc=utf-8 spell spl=en cc=100 tw=99 fo=want sts=2 sw=2 et
228 |
--------------------------------------------------------------------------------
/docs/TOFS_pattern.rst:
--------------------------------------------------------------------------------
1 | .. _tofs_pattern:
2 |
3 | TOFS: A pattern for using SaltStack
4 | ===================================
5 |
6 | .. list-table::
7 | :name: tofs-authors
8 | :header-rows: 1
9 | :stub-columns: 1
10 | :widths: 2,2,3,2
11 |
12 | * -
13 | - Person
14 | - Contact
15 | - Date
16 | * - Authored by
17 | - Roberto Moreda
18 | - moreda@allenta.com
19 | - 29/12/2014
20 | * - Modified by
21 | - Daniel Dehennin
22 | - daniel.dehennin@baby-gnu.org
23 | - 07/02/2019
24 | * - Modified by
25 | - Imran Iqbal
26 | - https://github.com/myii
27 | - 23/02/2019
28 |
29 | All that follows is a proposal based on my experience with `SaltStack `_. The good thing of a piece of software like this is that you can "bend it" to suit your needs in many possible ways, and this is one of them. All the recommendations and thoughts are given "as it is" with no warranty of any type.
30 |
31 | .. contents:: **Table of Contents**
32 |
33 | Usage of values in pillar vs templates in ``file_roots``
34 | --------------------------------------------------------
35 |
36 | Among other functions, the *master* (or *salt-master*) serves files to the *minions* (or *salt-minions*). The `file_roots `_ is the list of directories used in sequence to find a file when a minion requires it: the first match is served to the minion. Those files could be `state files `_ or configuration templates, among others.
37 |
38 | Using SaltStack is a simple and effective way to implement configuration management, but even in a `non-multitenant `_ scenario, it is not a good idea to generally access some data (e.g. the database password in our `Zabbix `_ server configuration file or the private key of our `Nginx `_ TLS certificate).
39 |
40 | To avoid this situation we can use the `pillar mechanism `_, which is designed to provide controlled access to data from the minions based on some selection rules. As pillar data could be easily integrated in the `Jinja `_ templates, it is a good mechanism to store values to be used in the final rendering of state files and templates.
41 |
42 | There are a variety of approaches on the usage of pillar and templates as seen in the `saltstack-formulas `_' repositories. `Some `_ `developments `_ stress the initial purpose of pillar data into a storage for most of the possible variables for a determined system configuration. This, in my opinion, is shifting too much load from the original template files approach. Adding up some `non-trivial Jinja `_ code as essential part of composing the state file definitely makes SaltStack state files (hence formulas) more difficult to read. The extreme of this approach is that we could end up with a new render mechanism, implemented in Jinja, storing everything needed in pillar data to compose configurations. Additionally, we are establishing a strong dependency with the Jinja renderer.
43 |
44 | In opposition to the *put the code in file_roots and the data in pillars* approach, there is the *pillar as a store for a set of key-values* approach. A full-blown configuration file abstracted in pillar and jinja is complicated to develop, understand and maintain. I think a better and simpler approach is to keep a configuration file templated using just a basic (non-extensive but extensible) set of pillar values.
45 |
46 | On the reusability of SaltStack state files
47 | -------------------------------------------
48 |
49 | There is a brilliant initiative of the SaltStack community called `salt-formulas `_. Their goal is to provide state files, pillar examples and configuration templates ready to be used for provisioning. I am a contributor for two small ones: `zabbix-formula `_ and `varnish-formula `_.
50 |
51 | The `design guidelines `_ for formulas are clear in many aspects and it is a recommended reading for anyone willing to write state files, even non-formulaic ones.
52 |
53 | In the next section, I am going to describe my proposal to extend further the reusability of formulas, suggesting some patterns of usage.
54 |
55 | The Template Override and Files Switch (TOFS) pattern
56 | -----------------------------------------------------
57 |
58 | I understand a formula as a **complete, independent set of SaltStack state and configuration template files sufficient to configure a system**. A system could be something as simple as an NTP server or some other much more complex service that requires many state and configuration template files.
59 |
60 | The customization of a formula should be done mainly by providing pillar data used later to render either the state or the configuration template files.
61 |
62 | Example: NTP before applying TOFS
63 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
64 |
65 | Let's work with the NTP example. A basic formula that follows the `design guidelines `_ has the following files and directories tree:
66 |
67 | .. code-block:: console
68 |
69 | /srv/saltstack/salt-formulas/ntp-saltstack-formula/
70 | ntp/
71 | map.jinja
72 | init.sls
73 | conf.sls
74 | files/
75 | default/
76 | etc/
77 | ntp.conf.jinja
78 |
79 | In order to use it, let's assume a `masterless configuration `_ and this relevant section of ``/etc/salt/minion``:
80 |
81 | .. code-block:: yaml
82 |
83 | pillar_roots:
84 | base:
85 | - /srv/saltstack/pillar
86 | file_client: local
87 | file_roots:
88 | base:
89 | - /srv/saltstack/salt
90 | - /srv/saltstack/salt-formulas/ntp-saltstack-formula
91 |
92 | .. code-block:: jinja
93 |
94 | {#- /srv/saltstack/salt-formulas/ntp-saltstack-formula/ntp/map.jinja #}
95 | {%- set ntp = salt['grains.filter_by']({
96 | 'default': {
97 | 'pkg': 'ntp',
98 | 'service': 'ntp',
99 | 'config': '/etc/ntp.conf',
100 | },
101 | }, merge=salt['pillar.get']('ntp:lookup')) %}
102 |
103 | In ``init.sls`` we have the minimal states required to have NTP configured. In many cases ``init.sls`` is almost equivalent to an ``apt-get install`` or a ``yum install`` of the package.
104 |
105 | .. code-block:: sls
106 |
107 | ## /srv/saltstack/salt-formulas/ntp-saltstack-formula/ntp/init.sls
108 | {%- from 'ntp/map.jinja' import ntp with context %}
109 |
110 | Install NTP:
111 | pkg.installed:
112 | - name: {{ ntp.pkg }}
113 |
114 | Enable and start NTP:
115 | service.running:
116 | - name: {{ ntp.service }}
117 | - enabled: True
118 | - require:
119 | - pkg: Install NTP package
120 |
121 | In ``conf.sls`` we have the configuration states. In most cases, that is just managing configuration file templates and making them to be watched by the service.
122 |
123 | .. code-block:: sls
124 |
125 | ## /srv/saltstack/salt-formulas/ntp-saltstack-formula/ntp/conf.sls
126 | include:
127 | - ntp
128 |
129 | {%- from 'ntp/map.jinja' import ntp with context %}
130 |
131 | Configure NTP:
132 | file.managed:
133 | - name: {{ ntp.config }}
134 | - template: jinja
135 | - source: salt://ntp/files/default/etc/ntp.conf.jinja
136 | - watch_in:
137 | - service: Enable and start NTP service
138 | - require:
139 | - pkg: Install NTP package
140 |
141 | Under ``files/default``, there is a structure that mimics the one in the minion in order to avoid clashes and confusion on where to put the needed templates. There you can find a mostly standard template for the configuration file.
142 |
143 | .. code-block:: jinja
144 |
145 | {#- /srv/saltstack/salt-formulas/ntp-saltstack-formula/ntp/files/default/etc/ntp.conf.jinja #}
146 | {#- Managed by saltstack #}
147 | {#- Edit pillars or override this template in saltstack if you need customization #}
148 | {%- set settings = salt['pillar.get']('ntp', {}) %}
149 | {%- set default_servers = ['0.ubuntu.pool.ntp.org',
150 | '1.ubuntu.pool.ntp.org',
151 | '2.ubuntu.pool.ntp.org',
152 | '3.ubuntu.pool.ntp.org'] %}
153 |
154 | driftfile /var/lib/ntp/ntp.drift
155 | statistics loopstats peerstats clockstats
156 | filegen loopstats file loopstats type day enable
157 | filegen peerstats file peerstats type day enable
158 | filegen clockstats file clockstats type day enable
159 |
160 | {%- for server in settings.get('servers', default_servers) %}
161 | server {{ server }}
162 | {%- endfor %}
163 |
164 | restrict -4 default kod notrap nomodify nopeer noquery
165 | restrict -6 default kod notrap nomodify nopeer noquery
166 |
167 | restrict 127.0.0.1
168 | restrict ::1
169 |
170 | With all this, it is easy to install and configure a simple NTP server by just running ``salt-call state.sls ntp.conf``: the package will be installed, the service will be running and the configuration should be correct for most of cases, even without pillar data.
171 |
172 | Alternatively, you can define a highstate in ``/srv/saltstack/salt/top.sls`` and run ``salt-call state.highstate``.
173 |
174 | .. code-block:: sls
175 |
176 | ## /srv/saltstack/salt/top.sls
177 | base:
178 | '*':
179 | - ntp.conf
180 |
181 | **Customizing the formula just with pillar data**, we have the option to define the NTP servers.
182 |
183 | .. code-block:: sls
184 |
185 | ## /srv/saltstack/pillar/top.sls
186 | base:
187 | '*':
188 | - ntp
189 |
190 | .. code-block:: sls
191 |
192 | ## /srv/saltstack/pillar/ntp.sls
193 | ntp:
194 | servers:
195 | - 0.ch.pool.ntp.org
196 | - 1.ch.pool.ntp.org
197 | - 2.ch.pool.ntp.org
198 | - 3.ch.pool.ntp.org
199 |
200 | Template Override
201 | ^^^^^^^^^^^^^^^^^
202 |
203 | If the customization based on pillar data is not enough, we can override the template by creating a new one in ``/srv/saltstack/salt/ntp/files/default/etc/ntp.conf.jinja``
204 |
205 | .. code-block:: jinja
206 |
207 | {#- /srv/saltstack/salt/ntp/files/default/etc/ntp.conf.jinja #}
208 | {#- Managed by saltstack #}
209 | {#- Edit pillars or override this template in saltstack if you need customization #}
210 |
211 | {#- Some bizarre configurations here #}
212 | {#- ... #}
213 |
214 | {%- for server in settings.get('servers', default_servers) %}
215 | server {{ server }}
216 | {%- endfor %}
217 |
218 | This way we are locally **overriding the template files** offered by the formula in order to make a more complex adaptation. Of course, this could be applied as well to any of the files, including the state files.
219 |
220 | Files Switch
221 | ^^^^^^^^^^^^
222 |
223 | To bring some order into the set of template files included in a formula, as we commented, we suggest having a similar structure to a normal final file system under ``files/default``.
224 |
225 | We can make different templates coexist for different minions, classified by any `grain `_ value, by simply creating new directories under ``files``. This mechanism is based on **using values of some grains as a switch for the directories under** ``files/``.
226 |
227 | If we decide that we want ``os_family`` as switch, then we could provide the formula template variants for both the ``RedHat`` and ``Debian`` families.
228 |
229 | .. code-block:: console
230 |
231 | /srv/saltstack/salt-formulas/ntp-saltstack-formula/ntp/files/
232 | default/
233 | etc/
234 | ntp.conf.jinja
235 | RedHat/
236 | etc/
237 | ntp.conf.jinja
238 | Debian/
239 | etc/
240 | ntp.conf.jinja
241 |
242 | To make this work we need a ``conf.sls`` state file that takes a list of possible files as the configuration template.
243 |
244 | .. code-block:: sls
245 |
246 | ## /srv/saltstack/salt-formulas/ntp-saltstack-formula/ntp/conf.sls
247 | include:
248 | - ntp
249 |
250 | {%- from 'ntp/map.jinja' import ntp with context %}
251 |
252 | Configure NTP:
253 | file.managed:
254 | - name: {{ ntp.config }}
255 | - template: jinja
256 | - source:
257 | - salt://ntp/files/{{ grains.get('os_family', 'default') }}/etc/ntp.conf.jinja
258 | - salt://ntp/files/default/etc/ntp.conf.jinja
259 | - watch_in:
260 | - service: Enable and start NTP service
261 | - require:
262 | - pkg: Install NTP package
263 |
264 | If we want to cover the possibility of a special template for a minion identified by ``node01`` then we could have a specific template in ``/srv/saltstack/salt/ntp/files/node01/etc/ntp.conf.jinja``.
265 |
266 | .. code-block:: jinja
267 |
268 | {#- /srv/saltstack/salt/ntp/files/node01/etc/ntp.conf.jinja #}
269 | {#- Managed by saltstack #}
270 | {#- Edit pillars or override this template in saltstack if you need customization #}
271 |
272 | {#- Some crazy configurations here for node01 #}
273 | {#- ... #}
274 |
275 | To make this work we could write a specially crafted ``conf.sls``.
276 |
277 | .. code-block:: sls
278 |
279 | ## /srv/saltstack/salt-formulas/ntp-saltstack-formula/ntp/conf.sls
280 | include:
281 | - ntp
282 |
283 | {%- from 'ntp/map.jinja' import ntp with context %}
284 |
285 | Configure NTP:
286 | file.managed:
287 | - name: {{ ntp.config }}
288 | - template: jinja
289 | - source:
290 | - salt://ntp/files/{{ grains.get('id') }}/etc/ntp.conf.jinja
291 | - salt://ntp/files/{{ grains.get('os_family') }}/etc/ntp.conf.jinja
292 | - salt://ntp/files/default/etc/ntp.conf.jinja
293 | - watch_in:
294 | - service: Enable and start NTP service
295 | - require:
296 | - pkg: Install NTP package
297 |
298 | Using the ``files_switch`` macro
299 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
300 |
301 | We can simplify the ``conf.sls`` with the new ``files_switch`` macro to use in the ``source`` parameter for the ``file.managed`` state.
302 |
303 | .. code-block:: sls
304 |
305 | ## /srv/saltstack/salt-formulas/ntp-saltstack-formula/ntp/conf.sls
306 | include:
307 | - ntp
308 |
309 | {%- set tplroot = tpldir.split('/')[0] %}
310 | {%- from 'ntp/map.jinja' import ntp with context %}
311 | {%- from 'ntp/libtofs.jinja' import files_switch %}
312 |
313 | Configure NTP:
314 | file.managed:
315 | - name: {{ ntp.config }}
316 | - template: jinja
317 | - source: {{ files_switch(['/etc/ntp.conf.jinja'],
318 | lookup='Configure NTP'
319 | )
320 | }}
321 | - watch_in:
322 | - service: Enable and start NTP service
323 | - require:
324 | - pkg: Install NTP package
325 |
326 |
327 | * This uses ``config.get``, searching for ``ntp:tofs:source_files:Configure NTP`` to determine the list of template files to use.
328 | * If this returns a result, the default of ``['/etc/ntp.conf.jinja']`` will be appended to it.
329 | * If this does not yield any results, the default of ``['/etc/ntp.conf.jinja']`` will be used.
330 |
331 | In ``libtofs.jinja``, we define this new macro ``files_switch``.
332 |
333 | .. literalinclude:: ../template/libtofs.jinja
334 | :caption: /srv/saltstack/salt-formulas/ntp-saltstack-formula/ntp/libtofs.jinja
335 | :language: jinja
336 |
337 | How to customise the ``source`` further
338 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
339 |
340 | The examples below are based on an ``Ubuntu`` minion called ``theminion`` being configured via. pillar.
341 |
342 | Using the default settings of the ``files_switch`` macro above,
343 | the ``source`` will be:
344 |
345 | .. code-block:: sls
346 |
347 | - source:
348 | - salt://ntp/files/theminion/etc/ntp.conf.jinja
349 | - salt://ntp/files/Debian/etc/ntp.conf.jinja
350 | - salt://ntp/files/default/etc/ntp.conf.jinja
351 |
352 | Customise ``files``
353 | ~~~~~~~~~~~~~~~~~~~
354 |
355 | The ``files`` portion can be customised:
356 |
357 | .. code-block:: sls
358 |
359 | ntp:
360 | tofs:
361 | dirs:
362 | files: files_alt
363 |
364 | Resulting in:
365 |
366 | .. code-block:: sls
367 |
368 | - source:
369 | - salt://ntp/files_alt/theminion/etc/ntp.conf.jinja
370 | - salt://ntp/files_alt/Debian/etc/ntp.conf.jinja
371 | - salt://ntp/files_alt/default/etc/ntp.conf.jinja
372 |
373 | Customise the use of grains
374 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~
375 |
376 | Grains can be customised and even arbitrary paths can be supplied:
377 |
378 | .. code-block:: sls
379 |
380 | ntp:
381 | tofs:
382 | files_switch:
383 | - any/path/can/be/used/here
384 | - id
385 | - os
386 | - os_family
387 |
388 | Resulting in:
389 |
390 | .. code-block:: sls
391 |
392 | - source:
393 | - salt://ntp/files/any/path/can/be/used/here/etc/ntp.conf.jinja
394 | - salt://ntp/files/theminion/etc/ntp.conf.jinja
395 | - salt://ntp/files/Ubuntu/etc/ntp.conf.jinja
396 | - salt://ntp/files/Debian/etc/ntp.conf.jinja
397 | - salt://ntp/files/default/etc/ntp.conf.jinja
398 |
399 | Customise the ``default`` path
400 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
401 |
402 | The ``default`` portion of the path can be customised:
403 |
404 | .. code-block:: sls
405 |
406 | ntp:
407 | tofs:
408 | dirs:
409 | default: default_alt
410 |
411 | Resulting in:
412 |
413 | .. code-block:: sls
414 |
415 | - source:
416 | ...
417 | - salt://ntp/files/default_alt/etc/ntp.conf.jinja
418 |
419 | Customise the list of ``source_files``
420 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
421 |
422 | The list of ``source_files`` can be given:
423 |
424 | .. code-block:: sls
425 |
426 | ntp:
427 | tofs:
428 | source_files:
429 | Configure NTP:
430 | - '/etc/ntp.conf_alt.jinja'
431 |
432 | Resulting in:
433 |
434 | .. code-block:: sls
435 |
436 | - source:
437 | - salt://ntp/files/theminion/etc/ntp.conf_alt.jinja
438 | - salt://ntp/files/theminion/etc/ntp.conf.jinja
439 | - salt://ntp/files/Debian/etc/ntp.conf_alt.jinja
440 | - salt://ntp/files/Debian/etc/ntp.conf.jinja
441 | - salt://ntp/files/default/etc/ntp.conf_alt.jinja
442 | - salt://ntp/files/default/etc/ntp.conf.jinja
443 |
444 | Note: This does *not* override the default value.
445 | Rather, the value from the pillar/config is prepended to the default.
446 |
447 | Using sub-directories for ``components``
448 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
449 |
450 | If your formula is composed of several components, you may prefer to provides files under sub-directories, like in the `systemd-formula `_.
451 |
452 | .. code-block:: console
453 |
454 | /srv/saltstack/systemd-formula/
455 | systemd/
456 | init.sls
457 | libtofs.jinja
458 | map.jinja
459 | networkd/
460 | init.sls
461 | files/
462 | default/
463 | network/
464 | 99-default.link
465 | resolved/
466 | init.sls
467 | files/
468 | default/
469 | resolved.conf
470 | timesyncd/
471 | init.sls
472 | files/
473 | Arch/
474 | resolved.conf
475 | Debian/
476 | resolved.conf
477 | default/
478 | resolved.conf
479 | Ubuntu/
480 | resolved.conf
481 |
482 | For example, the following ``formula.component.config`` SLS:
483 |
484 | .. code-block:: sls
485 |
486 | {%- from "formula/libtofs.jinja" import files_switch with context %}
487 |
488 | formula configuration file:
489 | file.managed:
490 | - name: /etc/formula.conf
491 | - user: root
492 | - group: root
493 | - mode: 644
494 | - template: jinja
495 | - source: {{ files_switch(['formula.conf'],
496 | lookup='formula',
497 | use_subpath=True
498 | )
499 | }}
500 |
501 | will be rendered on a ``Debian`` minion named ``salt-formula.ci.local`` as:
502 |
503 | .. code-block:: sls
504 |
505 | formula configuration file:
506 | file.managed:
507 | - name: /etc/formula.conf
508 | - user: root
509 | - group: root
510 | - mode: 644
511 | - template: jinja
512 | - source:
513 | - salt://formula/component/files/salt-formula.ci.local/formula.conf
514 | - salt://formula/component/files/Debian/formula.conf
515 | - salt://formula/component/files/default/formula.conf
516 | - salt://formula/files/salt-formula.ci.local/formula.conf
517 | - salt://formula/files/Debian/formula.conf
518 | - salt://formula/files/default/formula.conf
519 |
--------------------------------------------------------------------------------
/kitchen.vagrant.yml:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # vim: ft=yaml
3 | ---
4 | driver:
5 | name: vagrant
6 | cache_directory: false
7 | customize:
8 | usbxhci: 'off'
9 | gui: false
10 | ssh:
11 | shell: /bin/sh
12 | linked_clone: true
13 | <% unless ENV['CI'] %>
14 | synced_folders:
15 | - - '.kitchen/kitchen-vagrant/%{instance_name}/vagrant'
16 | - '/vagrant'
17 | - 'create: true, disabled: false'
18 | <% end %>
19 |
20 | platforms:
21 | - name: freebsd-130-master-py3
22 | driver:
23 | box: myii/freebsd-13.0-master-py3
24 | - name: freebsd-123-master-py3
25 | driver:
26 | box: myii/freebsd-12.3-master-py3
27 | - name: freebsd-130-3004-0-py3
28 | driver:
29 | box: myii/freebsd-13.0-3004.0-py3
30 | - name: freebsd-123-3004-0-py3
31 | driver:
32 | box: myii/freebsd-12.3-3004.0-py3
33 |
--------------------------------------------------------------------------------
/kitchen.yml:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # vim: ft=yaml
3 | ---
4 | # For help on this file's format, see https://kitchen.ci/
5 | driver:
6 | name: docker
7 | use_sudo: false
8 | privileged: true
9 | run_command: /usr/lib/systemd/systemd
10 |
11 | provisioner:
12 | name: salt_solo
13 | log_level: debug
14 | salt_install: none
15 | require_chef: false
16 | formula: postgres
17 | salt_copy_filter:
18 | - .kitchen
19 | - .git
20 |
21 | platforms:
22 | ## SALT `tiamat`
23 | - name: debian-11-tiamat-py3
24 | driver:
25 | image: saltimages/salt-tiamat-py3:debian-11
26 | run_command: /lib/systemd/systemd
27 | - name: debian-10-tiamat-py3
28 | driver:
29 | image: saltimages/salt-tiamat-py3:debian-10
30 | run_command: /lib/systemd/systemd
31 | - name: debian-9-tiamat-py3
32 | driver:
33 | image: saltimages/salt-tiamat-py3:debian-9
34 | run_command: /lib/systemd/systemd
35 | - name: ubuntu-2204-tiamat-py3
36 | driver:
37 | image: saltimages/salt-tiamat-py3:ubuntu-22.04
38 | run_command: /lib/systemd/systemd
39 | - name: ubuntu-2004-tiamat-py3
40 | driver:
41 | image: saltimages/salt-tiamat-py3:ubuntu-20.04
42 | run_command: /lib/systemd/systemd
43 | - name: ubuntu-1804-tiamat-py3
44 | driver:
45 | image: saltimages/salt-tiamat-py3:ubuntu-18.04
46 | run_command: /lib/systemd/systemd
47 | - name: centos-stream8-tiamat-py3
48 | driver:
49 | image: saltimages/salt-tiamat-py3:centos-stream8
50 | - name: centos-7-tiamat-py3
51 | driver:
52 | image: saltimages/salt-tiamat-py3:centos-7
53 | - name: amazonlinux-2-tiamat-py3
54 | driver:
55 | image: saltimages/salt-tiamat-py3:amazonlinux-2
56 | - name: oraclelinux-8-tiamat-py3
57 | driver:
58 | image: saltimages/salt-tiamat-py3:oraclelinux-8
59 | - name: oraclelinux-7-tiamat-py3
60 | driver:
61 | image: saltimages/salt-tiamat-py3:oraclelinux-7
62 | - name: almalinux-8-tiamat-py3
63 | driver:
64 | image: saltimages/salt-tiamat-py3:almalinux-8
65 | - name: rockylinux-8-tiamat-py3
66 | driver:
67 | image: saltimages/salt-tiamat-py3:rockylinux-8
68 |
69 | ## SALT `master`
70 | - name: debian-11-master-py3
71 | driver:
72 | image: saltimages/salt-master-py3:debian-11
73 | run_command: /lib/systemd/systemd
74 | - name: debian-10-master-py3
75 | driver:
76 | image: saltimages/salt-master-py3:debian-10
77 | run_command: /lib/systemd/systemd
78 | - name: debian-9-master-py3
79 | driver:
80 | image: saltimages/salt-master-py3:debian-9
81 | run_command: /lib/systemd/systemd
82 | - name: ubuntu-2204-master-py3
83 | driver:
84 | image: saltimages/salt-master-py3:ubuntu-22.04
85 | run_command: /lib/systemd/systemd
86 | - name: ubuntu-2004-master-py3
87 | driver:
88 | image: saltimages/salt-master-py3:ubuntu-20.04
89 | run_command: /lib/systemd/systemd
90 | - name: ubuntu-1804-master-py3
91 | driver:
92 | image: saltimages/salt-master-py3:ubuntu-18.04
93 | run_command: /lib/systemd/systemd
94 | - name: centos-stream8-master-py3
95 | driver:
96 | image: saltimages/salt-master-py3:centos-stream8
97 | - name: centos-7-master-py3
98 | driver:
99 | image: saltimages/salt-master-py3:centos-7
100 | - name: fedora-36-master-py3
101 | driver:
102 | image: saltimages/salt-master-py3:fedora-36
103 | - name: fedora-35-master-py3
104 | driver:
105 | image: saltimages/salt-master-py3:fedora-35
106 | - name: opensuse-leap-153-master-py3
107 | driver:
108 | image: saltimages/salt-master-py3:opensuse-leap-15.3
109 | # Workaround to avoid intermittent failures on `opensuse-leap-15.3`:
110 | # => SCP did not finish successfully (255): (Net::SCP::Error)
111 | transport:
112 | max_ssh_sessions: 1
113 | - name: opensuse-tmbl-latest-master-py3
114 | driver:
115 | image: saltimages/salt-master-py3:opensuse-tumbleweed-latest
116 | # Workaround to avoid intermittent failures on `opensuse-tumbleweed`:
117 | # => SCP did not finish successfully (255): (Net::SCP::Error)
118 | transport:
119 | max_ssh_sessions: 1
120 | - name: amazonlinux-2-master-py3
121 | driver:
122 | image: saltimages/salt-master-py3:amazonlinux-2
123 | - name: oraclelinux-8-master-py3
124 | driver:
125 | image: saltimages/salt-master-py3:oraclelinux-8
126 | - name: oraclelinux-7-master-py3
127 | driver:
128 | image: saltimages/salt-master-py3:oraclelinux-7
129 | - name: arch-base-latest-master-py3
130 | driver:
131 | image: saltimages/salt-master-py3:arch-base-latest
132 | - name: gentoo-stage3-latest-master-py3
133 | driver:
134 | image: saltimages/salt-master-py3:gentoo-stage3-latest
135 | run_command: /sbin/init
136 | - name: gentoo-stage3-systemd-master-py3
137 | driver:
138 | image: saltimages/salt-master-py3:gentoo-stage3-systemd
139 | - name: almalinux-8-master-py3
140 | driver:
141 | image: saltimages/salt-master-py3:almalinux-8
142 | - name: rockylinux-8-master-py3
143 | driver:
144 | image: saltimages/salt-master-py3:rockylinux-8
145 |
146 | ## SALT `3004.1`
147 | - name: debian-11-3004-1-py3
148 | driver:
149 | image: saltimages/salt-3004.1-py3:debian-11
150 | run_command: /lib/systemd/systemd
151 | - name: debian-10-3004-1-py3
152 | driver:
153 | image: saltimages/salt-3004.1-py3:debian-10
154 | run_command: /lib/systemd/systemd
155 | - name: debian-9-3004-1-py3
156 | driver:
157 | image: saltimages/salt-3004.1-py3:debian-9
158 | run_command: /lib/systemd/systemd
159 | - name: ubuntu-2204-3004-1-py3
160 | driver:
161 | image: saltimages/salt-3004.1-py3:ubuntu-22.04
162 | run_command: /lib/systemd/systemd
163 | - name: ubuntu-2004-3004-1-py3
164 | driver:
165 | image: saltimages/salt-3004.1-py3:ubuntu-20.04
166 | run_command: /lib/systemd/systemd
167 | - name: ubuntu-1804-3004-1-py3
168 | driver:
169 | image: saltimages/salt-3004.1-py3:ubuntu-18.04
170 | run_command: /lib/systemd/systemd
171 | - name: centos-stream8-3004-1-py3
172 | driver:
173 | image: saltimages/salt-3004.1-py3:centos-stream8
174 | - name: centos-7-3004-1-py3
175 | driver:
176 | image: saltimages/salt-3004.1-py3:centos-7
177 | - name: fedora-36-3004-1-py3
178 | driver:
179 | image: saltimages/salt-3004.1-py3:fedora-36
180 | - name: fedora-35-3004-1-py3
181 | driver:
182 | image: saltimages/salt-3004.1-py3:fedora-35
183 | - name: amazonlinux-2-3004-1-py3
184 | driver:
185 | image: saltimages/salt-3004.1-py3:amazonlinux-2
186 | - name: oraclelinux-8-3004-1-py3
187 | driver:
188 | image: saltimages/salt-3004.1-py3:oraclelinux-8
189 | - name: oraclelinux-7-3004-1-py3
190 | driver:
191 | image: saltimages/salt-3004.1-py3:oraclelinux-7
192 | - name: arch-base-latest-3004-1-py3
193 | driver:
194 | image: saltimages/salt-3004.1-py3:arch-base-latest
195 | - name: gentoo-stage3-latest-3004-1-py3
196 | driver:
197 | image: saltimages/salt-3004.1-py3:gentoo-stage3-latest
198 | run_command: /sbin/init
199 | - name: gentoo-stage3-systemd-3004-1-py3
200 | driver:
201 | image: saltimages/salt-3004.1-py3:gentoo-stage3-systemd
202 | - name: almalinux-8-3004-1-py3
203 | driver:
204 | image: saltimages/salt-3004.1-py3:almalinux-8
205 | - name: rockylinux-8-3004-1-py3
206 | driver:
207 | image: saltimages/salt-3004.1-py3:rockylinux-8
208 |
209 | ## SALT `3004.0`
210 | - name: opensuse-leap-153-3004-0-py3
211 | driver:
212 | image: saltimages/salt-3004.0-py3:opensuse-leap-15.3
213 | # Workaround to avoid intermittent failures on `opensuse-leap-15.3`:
214 | # => SCP did not finish successfully (255): (Net::SCP::Error)
215 | transport:
216 | max_ssh_sessions: 1
217 | - name: opensuse-tmbl-latest-3004-0-py3
218 | driver:
219 | image: saltimages/salt-3004.0-py3:opensuse-tumbleweed-latest
220 | # Workaround to avoid intermittent failures on `opensuse-tumbleweed`:
221 | # => SCP did not finish successfully (255): (Net::SCP::Error)
222 | transport:
223 | max_ssh_sessions: 1
224 |
225 | ## SALT `3003.4`
226 | - name: debian-10-3003-4-py3
227 | driver:
228 | image: saltimages/salt-3003.4-py3:debian-10
229 | run_command: /lib/systemd/systemd
230 | - name: debian-9-3003-4-py3
231 | driver:
232 | image: saltimages/salt-3003.4-py3:debian-9
233 | run_command: /lib/systemd/systemd
234 | - name: ubuntu-2004-3003-4-py3
235 | driver:
236 | image: saltimages/salt-3003.4-py3:ubuntu-20.04
237 | run_command: /lib/systemd/systemd
238 | - name: ubuntu-1804-3003-4-py3
239 | driver:
240 | image: saltimages/salt-3003.4-py3:ubuntu-18.04
241 | run_command: /lib/systemd/systemd
242 | - name: centos-stream8-3003-4-py3
243 | driver:
244 | image: saltimages/salt-3003.4-py3:centos-stream8
245 | - name: centos-7-3003-4-py3
246 | driver:
247 | image: saltimages/salt-3003.4-py3:centos-7
248 | - name: amazonlinux-2-3003-4-py3
249 | driver:
250 | image: saltimages/salt-3003.4-py3:amazonlinux-2
251 | - name: oraclelinux-8-3003-4-py3
252 | driver:
253 | image: saltimages/salt-3003.4-py3:oraclelinux-8
254 | - name: oraclelinux-7-3003-4-py3
255 | driver:
256 | image: saltimages/salt-3003.4-py3:oraclelinux-7
257 | - name: almalinux-8-3003-4-py3
258 | driver:
259 | image: saltimages/salt-3003.4-py3:almalinux-8
260 |
261 | verifier:
262 | # https://www.inspec.io/
263 | name: inspec
264 | sudo: true
265 | reporter:
266 | # cli, documentation, html, progress, json, json-min, json-rspec, junit
267 | - cli
268 |
269 | suites:
270 | - name: default
271 | provisioner:
272 | state_top:
273 | base:
274 | '*':
275 | - postgres._mapdata
276 | - postgres
277 | pillars:
278 | top.sls:
279 | base:
280 | '*':
281 | - postgres
282 | pillars_from_files:
283 | postgres.sls: test/salt/pillar/postgres.sls
284 | verifier:
285 | inspec_tests:
286 | - path: test/integration/default
287 | - name: repo
288 | includes:
289 | - debian-11-tiamat-py3
290 | - debian-10-tiamat-py3
291 | - debian-9-tiamat-py3
292 | - ubuntu-2204-tiamat-py3
293 | - ubuntu-2004-tiamat-py3
294 | - ubuntu-1804-tiamat-py3
295 | - centos-stream8-tiamat-py3
296 | - centos-7-tiamat-py3
297 | - amazonlinux-2-tiamat-py3
298 | - oraclelinux-8-tiamat-py3
299 | - oraclelinux-7-tiamat-py3
300 | - almalinux-8-tiamat-py3
301 | - rockylinux-8-tiamat-py3
302 | - debian-11-master-py3
303 | - debian-10-master-py3
304 | - debian-9-master-py3
305 | - ubuntu-2204-master-py3
306 | - ubuntu-2004-master-py3
307 | - ubuntu-1804-master-py3
308 | - centos-stream8-master-py3
309 | - centos-7-master-py3
310 | - fedora-36-master-py3
311 | - fedora-35-master-py3
312 | - opensuse-leap-153-master-py3
313 | - amazonlinux-2-master-py3
314 | - oraclelinux-8-master-py3
315 | - oraclelinux-7-master-py3
316 | - almalinux-8-master-py3
317 | - rockylinux-8-master-py3
318 | - debian-11-3004-1-py3
319 | - debian-10-3004-1-py3
320 | - debian-9-3004-1-py3
321 | - ubuntu-2204-3004-1-py3
322 | - ubuntu-2004-3004-1-py3
323 | - ubuntu-1804-3004-1-py3
324 | - centos-stream8-3004-1-py3
325 | - centos-7-3004-1-py3
326 | - fedora-36-3004-1-py3
327 | - fedora-35-3004-1-py3
328 | - amazonlinux-2-3004-1-py3
329 | - oraclelinux-8-3004-1-py3
330 | - oraclelinux-7-3004-1-py3
331 | - almalinux-8-3004-1-py3
332 | - rockylinux-8-3004-1-py3
333 | - opensuse-leap-153-3004-0-py3
334 | - debian-10-3003-4-py3
335 | - debian-9-3003-4-py3
336 | - ubuntu-2004-3003-4-py3
337 | - ubuntu-1804-3003-4-py3
338 | - centos-stream8-3003-4-py3
339 | - centos-7-3003-4-py3
340 | - amazonlinux-2-3003-4-py3
341 | - oraclelinux-8-3003-4-py3
342 | - oraclelinux-7-3003-4-py3
343 | - almalinux-8-3003-4-py3
344 | provisioner:
345 | state_top:
346 | base:
347 | '*':
348 | - postgres._mapdata
349 | - postgres
350 | pillars:
351 | top.sls:
352 | base:
353 | '*':
354 | - postgres
355 | - repo
356 | pillars_from_files:
357 | postgres.sls: test/salt/pillar/postgres.sls
358 | repo.sls: test/salt/pillar/repo.sls
359 | verifier:
360 | inspec_tests:
361 | - path: test/integration/repo
362 |
--------------------------------------------------------------------------------
/pillar.example:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # vim: ft=yaml
3 | ---
4 | # Port to use for the cluster -- can be used to provide a non-standard port
5 | # NOTE: If already set in the minion config, that value takes priority
6 | postgres.port: '5432'
7 |
8 | postgres:
9 | # UPSTREAM REPO
10 | # Set true to configure upstream postgresql.org repository for YUM/APT/ZYPP
11 | use_upstream_repo: false
12 | # Version to install from upstream repository (if upstream_repo: true)
13 | version: '13'
14 | # Set true to add a file in /etc/profile.d adding the bin dir in $PATH
15 | # as packages from upstream put them somewhere like /usr/pgsql-10/bin
16 | add_profile: false
17 | # If automatic package installation fails, use `fromrepo` to specify the
18 | # upstream repo to install packages from [#133, #185] (if upstream_repo: true)
19 | fromrepo: 'jessie-pgdg'
20 |
21 | ### MACOS
22 | # Set to 'postgresapp' OR 'homebrew' for MacOS
23 | # use_upstream_repo: 'postgresapp'
24 | # use_upstream_repo: 'homebrew'
25 |
26 | # PACKAGE
27 | # These pillars are typically never required.
28 | # pkg: 'postgresql'
29 | # pkg_client: 'postgresql-client'
30 | # service:
31 | # name: 'postgresql'
32 | # flags: -w -s -m fast
33 | # sysrc: true
34 | pkgs_extra:
35 | {%- if grains.os_family not in ('FreeBSD',) %}
36 | - postgresql-contrib
37 | {%- endif %}
38 | - postgresql-plpython
39 |
40 | # CLUSTER
41 | # The default `encoding` is derived from the `locale` so not recommended
42 | # to provide a value for it unless necessary
43 | cluster:
44 | locale: en_US.UTF-8
45 | # encoding: UTF8
46 |
47 | # 'Alternatives system' priority incremental. 0 disables feature.
48 | linux:
49 | altpriority: 30
50 |
51 | # macos limits
52 | limits:
53 | soft: 64000
54 | hard: 128000
55 |
56 | # POSTGRES
57 | # Append the lines under this item to your postgresql.conf file.
58 | # Pay attention to indent exactly with 4 spaces for all lines.
59 | postgresconf: |-
60 | listen_addresses = '*' # listen on all interfaces
61 |
62 | # Path to the `pg_hba.conf` file Jinja template on Salt Fileserver
63 | pg_hba.conf: salt://postgres/templates/pg_hba.conf.j2
64 |
65 | # This section covers ACL management in the ``pg_hba.conf`` file.
66 | # acls list controls: which hosts are allowed to connect, how clients
67 | # are authenticated, which PostgreSQL user names they can use, which
68 | # databases they can access. Records take one of these forms:
69 | #
70 | # acls:
71 | # - ['local', 'DATABASE', 'USER', 'METHOD']
72 | # - ['host', 'DATABASE', 'USER', 'ADDRESS', 'METHOD']
73 | # - ['hostssl', 'DATABASE', 'USER', 'ADDRESS', 'METHOD']
74 | # - ['hostnossl', 'DATABASE', 'USER', 'ADDRESS', 'METHOD']
75 | #
76 | # The uppercase items must be replaced by actual values.
77 | # METHOD could be omitted, 'md5' will be appended by default.
78 | #
79 | # Postgres expect a valid CIDR for ADDRESS (not ipaddress)
80 | #
81 | # If ``acls`` item value is empty ('', [], null), then the contents of
82 | # ``pg_hba.conf`` file will not be touched at all.
83 | acls:
84 | - ['local', 'db0', 'connuser', 'peer map=users_as_appuser']
85 | - ['local', 'db1', 'localUser']
86 | - ['host', 'db2', 'remoteUser', '192.168.33.0/24']
87 | - ['host', 'all', 'all', '127.0.0.1/32', 'md5']
88 |
89 | identity_map:
90 | - ['users_as_appuser', 'jdoe', 'connuser']
91 | - ['users_as_appuser', 'jsmith', 'connuser']
92 |
93 | # Backup extension for configuration files, defaults to ``.bak``.
94 | # Set ``false`` to stop creation of backups when config files change.
95 | {%- if salt['status.time']|default(none) is callable %}
96 | config_backup: ".backup@{{ salt['status.time']('%y-%m-%d_%H:%M:%S') }}"
97 | {%- endif %}
98 |
99 | {%- if 'init' in grains and grains['init'] == 'unknown' %}
100 |
101 | # If Salt is unable to detect init system running in the scope of state run,
102 | # probably we are trying to bake a container/VM image with PostgreSQL.
103 | # Use ``bake_image`` setting to control how PostgreSQL will be started: if set
104 | # to ``true`` the raw ``pg_ctl`` will be utilized instead of packaged init
105 | # script, job or unit run with Salt ``service`` state.
106 | bake_image: true
107 |
108 | {%- endif %}
109 |
110 | # Create/remove users, tablespaces, databases, schema and extensions.
111 | # Each of these dictionaries contains PostgreSQL entities which
112 | # mapped to the ``postgres_*`` Salt states with arguments. See the Salt
113 | # documentation to get all supported argument for a particular state.
114 | #
115 | # Format is the following:
116 | #
117 | # :
118 | # NAME:
119 | # ensure: # 'present' is the default
120 | # ARGUMENT: VALUE
121 | # ...
122 | #
123 | # where 'NAME' is the state name, 'ARGUMENT' is the kwarg name, and
124 | # 'VALUE' is kwarg value.
125 | #
126 | # For example, the Pillar:
127 | #
128 | # users:
129 | # testUser:
130 | # password: test
131 | #
132 | # will render such state:
133 | #
134 | # postgres_user-testUser:
135 | # postgres_user.present:
136 | # - name: testUser
137 | # - password: test
138 | users:
139 | localUser:
140 | ensure: present
141 | password: '98ruj923h4rf'
142 | createdb: false
143 | createroles: false
144 | inherit: true
145 | replication: false
146 |
147 | remoteUser:
148 | ensure: present
149 | password: '98ruj923h4rf'
150 | createdb: false
151 | createroles: false
152 | inherit: true
153 | replication: false
154 |
155 | absentUser:
156 | ensure: absent
157 |
158 | # tablespaces to be created
159 | tablespaces:
160 | my_space:
161 | directory: /srv/my_tablespace
162 | owner: localUser
163 |
164 | # databases to be created
165 | databases:
166 | db1:
167 | owner: 'localUser'
168 | template: 'template0'
169 | lc_ctype: 'en_US.UTF-8'
170 | lc_collate: 'en_US.UTF-8'
171 | db2:
172 | owner: 'remoteUser'
173 | template: 'template0'
174 | lc_ctype: 'en_US.UTF-8'
175 | lc_collate: 'en_US.UTF-8'
176 | tablespace: 'my_space'
177 | # set custom schema
178 | schemas:
179 | public:
180 | owner: 'localUser'
181 | # enable per-db extension
182 | extensions:
183 | uuid-ossp:
184 | schema: 'public'
185 |
186 | # optional schemas to enable on database
187 | schemas:
188 | uuid-ossp:
189 | dbname: db1
190 | owner: localUser
191 |
192 | # optional extensions to install in schema
193 | extensions:
194 | # postgis: {}
195 | uuid-ossp:
196 | schema: uuid-ossp
197 | maintenance_db: db1
198 |
199 | remove:
200 | data: true
201 | multiple_releases: true
202 | releases: ['9.6', '10']
203 |
204 | # vim: ft=yaml ts=2 sts=2 sw=2 et
205 |
--------------------------------------------------------------------------------
/postgres/_mapdata/_mapdata.jinja:
--------------------------------------------------------------------------------
1 | # yamllint disable rule:indentation rule:line-length
2 | # {{ grains.get("osfinger", grains.os) }}
3 | ---
4 | {#- use salt.slsutil.serialize to avoid encoding errors on some platforms #}
5 | {{ salt["slsutil.serialize"](
6 | "yaml",
7 | map,
8 | default_flow_style=False,
9 | allow_unicode=True,
10 | )
11 | | regex_replace("^\s+'$", "'", multiline=True)
12 | | trim
13 | }}
14 |
--------------------------------------------------------------------------------
/postgres/_mapdata/init.sls:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # vim: ft=sls
3 | ---
4 | {#- Get the `tplroot` from `tpldir` #}
5 | {%- set tplroot = tpldir.split("/")[0] %}
6 | {%- from tplroot ~ "/map.jinja" import postgres with context %}
7 |
8 | {%- set _mapdata = {
9 | "values": postgres,
10 | } %}
11 | {%- do salt["log.debug"]("### MAP.JINJA DUMP ###\n" ~ _mapdata | yaml(False)) %}
12 |
13 | {%- set output_dir = "/temp" if grains.os_family == "Windows" else "/tmp" %}
14 | {%- set output_file = output_dir ~ "/salt_mapdata_dump.yaml" %}
15 |
16 | {{ tplroot }}-mapdata-dump:
17 | file.managed:
18 | - name: {{ output_file }}
19 | - source: salt://{{ tplroot }}/_mapdata/_mapdata.jinja
20 | - template: jinja
21 | - context:
22 | map: {{ _mapdata | yaml }}
23 |
--------------------------------------------------------------------------------
/postgres/client/init.sls:
--------------------------------------------------------------------------------
1 | {%- from salt.file.dirname(tpldir) ~ "/map.jinja" import postgres with context -%}
2 |
3 | {%- set pkgs = [] %}
4 | {%- for pkg in (postgres.pkg_client,) %}
5 | {%- if pkg %}
6 | {%- do pkgs.append(pkg) %}
7 | {%- endif %}
8 | {%- endfor %}
9 |
10 | {%- if postgres.use_upstream_repo == true %}
11 | include:
12 | - postgres.upstream
13 | {%- endif %}
14 |
15 | # Install PostgreSQL client and libraries
16 | postgresql-client-libs:
17 | pkg.installed:
18 | - pkgs: {{ pkgs | json }}
19 | {%- if 'pkg_repo' in postgres and postgres.use_upstream_repo == true %}
20 | - refresh: True
21 | - require:
22 | - pkgrepo: postgresql-repo
23 | {%- endif %}
24 | {%- if postgres.fromrepo %}
25 | - fromrepo: {{ postgres.fromrepo }}
26 | {%- endif %}
27 |
28 | # Alternatives system. Make client binaries available in $PATH
29 | {%- if 'bin_dir' in postgres and postgres.linux.altpriority %}
30 | {%- for bin in postgres.client_bins %}
31 | {%- set path = salt['file.join'](postgres.bin_dir, bin) %}
32 |
33 | postgresql-{{ bin }}-altinstall:
34 | alternatives.install:
35 | - name: {{ bin }}
36 | - link: {{ salt['file.join']('/usr/bin', bin) }}
37 | - path: {{ path }}
38 | - priority: {{ postgres.linux.altpriority }}
39 | - onlyif: test -f {{ path }}
40 | - require:
41 | - pkg: postgresql-client-libs
42 | {%- if grains['saltversioninfo'] < [2018, 11, 0, 0] %}
43 | - retry:
44 | attempts: 2
45 | until: True
46 | {%- endif %}
47 |
48 | {%- endfor %}
49 | {%- endif %}
50 |
--------------------------------------------------------------------------------
/postgres/client/remove.sls:
--------------------------------------------------------------------------------
1 | {%- from salt.file.dirname(tpldir) ~ "/map.jinja" import postgres with context -%}
2 |
3 | #remove release installed by formula
4 | postgresql-client-removed:
5 | pkg.removed:
6 | - pkgs:
7 | {% if postgres.pkg_client %}
8 | - {{ postgres.pkg_client }}
9 | {% endif %}
10 |
11 | {%- if postgres.remove.multiple_releases %}
12 | #search for and cleandown multiple releases
13 |
14 | {% for release in postgres.remove.releases %}
15 | {% if 'bin_dir' in postgres %}
16 | {%- for bin in postgres.client_bins %}
17 | {% set path = '/usr/pgsql-' + release|string + '/bin/' + bin %}
18 |
19 | postgresql{{ release }}-client-{{ bin }}-alternative-remove:
20 | alternatives.remove:
21 | - name: {{ bin }}
22 | - path: {{ path }}
23 | {% if grains.os in ('Fedora', 'CentOS',) %}
24 | {# bypass bug #}
25 | - onlyif: alternatives --display {{ bin }}
26 | {% else %}
27 | - onlyif: test -f {{ path }}
28 | {% endif %}
29 | - require_in:
30 | - pkg: postgresql{{ release }}-client-pkgs-removed
31 | {%- endfor %}
32 | {%- endif %}
33 |
34 | postgresql{{ release }}-client-pkgs-removed:
35 | pkg.purged:
36 | - pkgs:
37 | - postgresql
38 | - postgresql-{{ release }}
39 | - postgresql-{{ release|replace('.', '') }}
40 | - postgresql{{ release }}-common
41 | - postgresql{{ release }}-jdbc
42 |
43 | {% endfor %}
44 |
45 | {%- endif %}
46 |
--------------------------------------------------------------------------------
/postgres/codenamemap.yaml:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # vim: ft=yaml
3 | ---
4 | ### Set parameters based on PostgreSQL version supplied with particular distro
5 |
6 | {% import_yaml "postgres/repo.yaml" as repo %}
7 |
8 | {# Generate lookup dictionary map for OS and derivative distributions
9 | name: distro codename
10 | version: PostgreSQL release version
11 | codename: optional grain value if `name` does not match the one returned by `oscodename` grain
12 | #}
13 |
14 | {% macro debian_codename(name, version, codename=none) %}
15 |
16 | {% if repo.use_upstream_repo == true %}
17 | {% set version = repo.version %}
18 | {% set fromrepo = repo.fromrepo|default(name ~ '-pgdg', true) %}
19 | {% else %}
20 | {% set fromrepo = name %}
21 | {% endif %}
22 | {% set cluster_name = repo.cluster_name %}
23 | {% set conf_dir = '/etc/postgresql/{0}/{1}'.format(version, cluster_name) %}
24 | {% set data_dir = '/var/lib/postgresql/{0}/{1}'.format(version, cluster_name) %}
25 |
26 | {{ codename|default(name, true) }}:
27 | # PostgreSQL packages are mostly downloaded from `main` repo component
28 | conf_dir: {{ conf_dir }}
29 | data_dir: {{ data_dir }}
30 | fromrepo: {{ fromrepo }}
31 | pkg_repo:
32 | name: 'deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.gpg] http://apt.postgresql.org/pub/repos/apt {{ name }}-pgdg main'
33 | pkg: postgresql-{{ version }}
34 | pkg_client: postgresql-client-{{ version }}
35 | prepare_cluster:
36 | pgcommand: pg_createcluster {{ version }} {{ cluster_name }} -d
37 | user: root
38 | bake_image_run_cmd: pg_ctlcluster {{ version }} {{ cluster_name }} start
39 |
40 | {% endmacro %}
41 |
42 |
43 | {% macro fedora_codename(name, version, codename=none) %}
44 |
45 | {# use upstream version if configured #}
46 | {% if repo.use_upstream_repo == true %}
47 | {% set version = repo.version %}
48 | {% endif %}
49 |
50 | {{ codename|default(name, true) }}:
51 | # PostgreSQL packages are mostly downloaded from `main` repo component
52 | pkg_repo:
53 | baseurl: 'https://download.postgresql.org/pub/repos/yum/{{ version }}/fedora/fedora-$releasever-$basearch'
54 |
55 | {% endmacro %}
56 |
57 | ## Debian GNU/Linux (the second parameter refers to the postgresql package version, not the distro)
58 | # http://apt.postgresql.org/pub/repos/apt/dists/
59 | # https://packages.debian.org/search?keywords=postgresql&searchon=names
60 | {{ debian_codename('jessie', '9.4') }}
61 | {{ debian_codename('stretch', '9.6') }}
62 | {{ debian_codename('buster', '11') }}
63 | {{ debian_codename('bullseye', '13') }}
64 | {{ debian_codename('bookworm', '15') }}
65 |
66 | # `oscodename` grain has long distro name
67 | # if `lsb-release` package not installed
68 | {{ debian_codename('jessie', '9.4', 'Debian GNU/Linux 8 (jessie)') }}
69 | {{ debian_codename('stretch', '9.6', 'Debian GNU/Linux 9 (stretch)') }}
70 | {{ debian_codename('buster', '11', 'Debian GNU/Linux 10 (buster)') }}
71 | {{ debian_codename('bullseye', '13', 'Debian GNU/Linux 11 (bullseye)') }}
72 | {{ debian_codename('bookworm', '15', 'Debian GNU/Linux 12 (bookworm)') }}
73 |
74 | ## Ubuntu
75 | # http://apt.postgresql.org/pub/repos/apt/dists/
76 | # https://packages.ubuntu.com/search?keywords=postgresql&searchon=names
77 | {{ debian_codename('xenial', '9.5') }}
78 | {{ debian_codename('bionic', '10') }}
79 | {{ debian_codename('eoan', '11') }}
80 | {{ debian_codename('focal', '12') }}
81 | {{ debian_codename('jammy', '14') }}
82 |
83 | ## Fedora
84 | # https://download.postgresql.org/pub/repos/yum/13/fedora/
85 | # https://apps.fedoraproject.org/packages/postgresql
86 | {{ fedora_codename('Fedora-34', '13') }}
87 | {{ fedora_codename('Fedora-33', '13') }}
88 |
89 | ## Amazon
90 | Amazon Linux 2:
91 | pkgs_deps:
92 | - libicu
93 | - systemd-sysv
94 | pkg_repo:
95 | baseurl: 'https://download.postgresql.org/pub/repos/yum/{{ repo.version }}/redhat/rhel-7-$basearch'
96 |
97 | # vim: ft=sls
98 |
--------------------------------------------------------------------------------
/postgres/defaults.yaml:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # vim: ft=yaml
3 | ---
4 | # Default lookup dictionary
5 |
6 | postgres:
7 | use_upstream_repo: true
8 | add_profile: false # add bin_dir to $PATH, if installed from repos
9 | version: '13'
10 | pkg: postgresql
11 | pkgs_extra: []
12 | pkgs_deps: []
13 | pkg_client: postgresql-client
14 | pkg_dev: postgresql-devel
15 | pkg_dev_deps: []
16 | pkg_libpq_dev: libpq-dev
17 | pkg_libs: postgresql-libs
18 | pkg_python: python-psycopg2
19 | userhomes: /home
20 | user: postgres
21 | group: postgres
22 |
23 | prepare_cluster:
24 | run: true
25 | pgcommand: initdb -D
26 | pgtestfile: PG_VERSION
27 | user: postgres
28 | env: []
29 |
30 | cluster:
31 | name: main # Debian-based only
32 | locale: '' # Defaults to `C`
33 | encoding: '' # Defaults to `SQL_ASCII` if `locale` not provided
34 |
35 | conf_dir: /var/lib/pgsql/data
36 | data_dir: /var/lib/pgsql/data
37 | conf_dir_mode: '0700'
38 | postgresconf: ""
39 |
40 | macos:
41 | archive: postgres.dmg
42 | tmpdir: /tmp/postgrestmp
43 | postgresapp:
44 | # See: https://github.com/PostgresApp/PostgresApp/releases/
45 | # yamllint disable-line rule:line-length
46 | url: https://github.com/PostgresApp/PostgresApp/releases/download/v2.1.1/Postgres-2.1.1.dmg
47 | sum: sha256=ac0656b522a58fd337931313f09509c09610c4a6078fe0b8e469e69af1e1750b
48 | homebrew:
49 | url: ''
50 | sum: ''
51 | dl:
52 | opts: -s -L
53 | interval: 60
54 | retries: 2
55 |
56 | pg_hba.conf: salt://postgres/templates/pg_hba.conf.j2
57 | acls:
58 | # "local" is for Unix domain socket connections only
59 | - ['local', 'all', 'all', 'peer']
60 | # IPv4 local connections:
61 | - ['host', 'all', 'all', '127.0.0.1/32', 'md5']
62 | # IPv6 local connections:
63 | - ['host', 'all', 'all', '::1/128', 'md5']
64 | # Allow replication connections from localhost, by a user with the
65 | # replication privilege.
66 | - ['local', 'replication', 'all', 'peer']
67 | - ['host', 'replication', 'all', '127.0.0.1/32', 'md5']
68 | - ['host', 'replication', 'all', '::1/128', 'md5']
69 |
70 | pg_ident.conf: salt://postgres/templates/pg_ident.conf.j2
71 | identity_map: []
72 |
73 | config_backup: '.bak'
74 |
75 | service:
76 | name: postgresql
77 | sysrc: false
78 |
79 | bake_image: false
80 | bake_image_run_cmd: pg_ctl start
81 |
82 | fromrepo: ''
83 |
84 | users: {}
85 | tablespaces: {}
86 | databases: {}
87 | schemas: {}
88 | extensions: {}
89 |
90 | linux:
91 | # Alternatives system are disabled by a 'altpriority=0' pillar.
92 | altpriority: 0
93 |
94 | remove:
95 | data: false
96 | multiple_releases: false
97 | releases: ['9.2', '9.3', '9.4', '9.5', '9.6', '10']
98 |
--------------------------------------------------------------------------------
/postgres/dev/init.sls:
--------------------------------------------------------------------------------
1 | {%- from salt.file.dirname(tpldir) ~ "/map.jinja" import postgres with context -%}
2 |
3 | {% if grains.os not in ('Windows', 'MacOS',) %}
4 | {%- set pkgs = [postgres.pkg_dev, postgres.pkg_libpq_dev] + postgres.pkg_dev_deps %}
5 |
6 | {% if pkgs %}
7 | install-postgres-dev-packages:
8 | pkg.installed:
9 | - pkgs: {{ pkgs | json }}
10 | {% if postgres.fromrepo %}
11 | - fromrepo: {{ postgres.fromrepo }}
12 | {% endif %}
13 | {% endif %}
14 |
15 | # Alternatives system. Make devclient binaries available in $PATH
16 | {%- if 'bin_dir' in postgres and postgres.linux.altpriority %}
17 | {%- for bin in postgres.dev_bins %}
18 | {%- set path = salt['file.join'](postgres.bin_dir, bin) %}
19 |
20 | postgresql-{{ bin }}-altinstall:
21 | alternatives.install:
22 | - name: {{ bin }}
23 | - link: {{ salt['file.join']('/usr/bin', bin) }}
24 | - path: {{ path }}
25 | - priority: {{ postgres.linux.altpriority }}
26 | - onlyif: test -f {{ path }}
27 | {%- if grains['saltversioninfo'] < [2018, 11, 0, 0] %}
28 | - retry:
29 | attempts: 2
30 | until: True
31 | {%- endif %}
32 |
33 | {%- endfor %}
34 | {%- endif %}
35 |
36 | {% elif grains.os == 'MacOS' %}
37 |
38 | # Darwin maxfiles limits
39 | {% if postgres.limits.soft or postgres.limits.hard %}
40 |
41 | postgres_maxfiles_limits_conf:
42 | file.managed:
43 | - name: /Library/LaunchDaemons/limit.maxfiles.plist
44 | - source: salt://postgres/templates/limit.maxfiles.plist
45 | - template: jinja
46 | - context:
47 | soft_limit: {{ postgres.limits.soft }}
48 | hard_limit: {{ postgres.limits.hard }}
49 | - group: {{ postgres.group }}
50 | {% endif %}
51 |
52 | {% if postgres.use_upstream_repo == 'postgresapp' %}
53 | # Shortcut for PostgresApp
54 | postgres-desktop-shortcut-clean:
55 | file.absent:
56 | - name: '{{ postgres.userhomes }}/{{ postgres.user }}/Desktop/Postgres ({{ postgres.use_upstream_repo }})'
57 | - require_in:
58 | - file: postgres-desktop-shortcut-add
59 |
60 | postgres-desktop-shortcut-add:
61 | file.managed:
62 | - name: /tmp/mac_shortcut.sh
63 | - source: salt://postgres/templates/mac_shortcut.sh
64 | - mode: 755
65 | - template: jinja
66 | - context:
67 | user: {{ postgres.user }}
68 | homes: {{ postgres.userhomes }}
69 | cmd.run:
70 | - name: '/tmp/mac_shortcut.sh "Postgres ({{ postgres.use_upstream_repo }})"'
71 | - runas: {{ postgres.user }}
72 | - require:
73 | - file: postgres-desktop-shortcut-add
74 | {% endif %}
75 |
76 | {% endif %}
77 |
--------------------------------------------------------------------------------
/postgres/dev/remove.sls:
--------------------------------------------------------------------------------
1 | {%- from salt.file.dirname(tpldir) ~ "/map.jinja" import postgres with context -%}
2 |
3 | # remove release installed by formula
4 | postgresql-devel-removed:
5 | pkg.removed:
6 | - pkgs:
7 | {% if postgres.pkg_dev %}
8 | - {{ postgres.pkg_dev }}
9 | {% endif %}
10 | {% if postgres.pkg_libpq_dev %}
11 | - {{ postgres.pkg_libpq_dev }}
12 | {% endif %}
13 | {% if postgres.pkg_python %}
14 | - {{ postgres.pkg_python }}
15 | {% endif %}
16 |
17 | {%- if postgres.remove.multiple_releases %}
18 | #search for and cleandown multiple releases
19 |
20 | {% for release in postgres.remove.releases %}
21 | {% if 'bin_dir' in postgres %}
22 | {%- for bin in postgres.dev_bins %}
23 | {% set path = '/usr/pgsql-' + release|string + '/bin/' + bin %}
24 |
25 | postgresql{{ release }}-devel-{{ bin }}-alternative-remove:
26 | alternatives.remove:
27 | - name: {{ bin }}
28 | - path: {{ path }}
29 | {% if grains.os in ('Fedora', 'CentOS',) %}
30 | {# bypass bug #}
31 | - onlyif: alternatives --display {{ bin }}
32 | {% else %}
33 | - onlyif: test -f {{ path }}
34 | {% endif %}
35 | - require_in:
36 | - pkg: postgresql{{ release }}-devel-pkgs-removed
37 | {%- endfor %}
38 | {%- endif %}
39 |
40 | postgresql{{ release }}-devel-pkgs-removed:
41 | pkg.purged:
42 | - pkgs:
43 | - postgresql-dev
44 | - postgresql-dev-{{ release|replace('.', '') }}
45 | - postgresql-server-dev
46 | - postgresql-server-dev-{{ release|replace('.', '') }}
47 | - postgresql{{ release }}-jdbc
48 | - postgresql{{ release|replace('.', '') }}-jdbc
49 | - postgresql-{{ release }}
50 | - postgresql-{{ release|replace('.', '') }}
51 | - {{ postgres.pkg_python or "postgresql-python" }}
52 |
53 | {% endfor %}
54 |
55 | {%- endif %}
56 |
--------------------------------------------------------------------------------
/postgres/dropped.sls:
--------------------------------------------------------------------------------
1 |
2 | include:
3 | - postgres.server.remove
4 | - postgres.client.remove
5 | - postgres.dev.remove
6 |
--------------------------------------------------------------------------------
/postgres/init.sls:
--------------------------------------------------------------------------------
1 |
2 | include:
3 | {% if grains.os == 'MacOS' %}
4 | - postgres.macos
5 | {% else %}
6 | - postgres.server
7 | - postgres.client
8 | - postgres.manage
9 | {% endif %}
10 |
--------------------------------------------------------------------------------
/postgres/libtofs.jinja:
--------------------------------------------------------------------------------
1 | {%- macro files_switch(
2 | source_files,
3 | lookup=None,
4 | default_files_switch=["id", "os_family"],
5 | indent_width=6,
6 | use_subpath=False
7 | ) %}
8 | {#-
9 | Returns a valid value for the "source" parameter of a "file.managed"
10 | state function. This makes easier the usage of the Template Override and
11 | Files Switch (TOFS) pattern.
12 | Params:
13 | * source_files: ordered list of files to look for
14 | * lookup: key under ":tofs:source_files" to prepend to the
15 | list of source files
16 | * default_files_switch: if there's no config (e.g. pillar)
17 | ":tofs:files_switch" this is the ordered list of grains to
18 | use as selector switch of the directories under
19 | "/files"
20 | * indent_width: indentation of the result value to conform to YAML
21 | * use_subpath: defaults to `False` but if set, lookup the source file
22 | recursively from the current state directory up to `tplroot`
23 | Example (based on a `tplroot` of `xxx`):
24 | If we have a state:
25 | Deploy configuration:
26 | file.managed:
27 | - name: /etc/yyy/zzz.conf
28 | - source: {{ files_switch(
29 | ["/etc/yyy/zzz.conf", "/etc/yyy/zzz.conf.jinja"],
30 | lookup="Deploy configuration",
31 | ) }}
32 | - template: jinja
33 | In a minion with id=theminion and os_family=RedHat, it's going to be
34 | rendered as:
35 | Deploy configuration:
36 | file.managed:
37 | - name: /etc/yyy/zzz.conf
38 | - source:
39 | - salt://xxx/files/theminion/etc/yyy/zzz.conf
40 | - salt://xxx/files/theminion/etc/yyy/zzz.conf.jinja
41 | - salt://xxx/files/RedHat/etc/yyy/zzz.conf
42 | - salt://xxx/files/RedHat/etc/yyy/zzz.conf.jinja
43 | - salt://xxx/files/default/etc/yyy/zzz.conf
44 | - salt://xxx/files/default/etc/yyy/zzz.conf.jinja
45 | - template: jinja
46 | #}
47 | {#- Get the `tplroot` from `tpldir` #}
48 | {%- set tplroot = tpldir.split("/")[0] %}
49 | {%- set path_prefix = salt["config.get"](tplroot ~ ":tofs:path_prefix", tplroot) %}
50 | {%- set files_dir = salt["config.get"](tplroot ~ ":tofs:dirs:files", "files") %}
51 | {%- set files_switch_list = salt["config.get"](
52 | tplroot ~ ":tofs:files_switch", default_files_switch
53 | ) %}
54 | {#- Lookup source_files (v2), files (v1), or fallback to an empty list #}
55 | {%- set src_files = salt["config.get"](
56 | tplroot ~ ":tofs:source_files:" ~ lookup,
57 | salt["config.get"](tplroot ~ ":tofs:files:" ~ lookup, []),
58 | ) %}
59 | {#- Append the default source_files #}
60 | {%- set src_files = src_files + source_files %}
61 | {#- Only add to [""] when supporting older TOFS implementations #}
62 | {%- set path_prefix_exts = [""] %}
63 | {%- if use_subpath and tplroot != tpldir %}
64 | {#- Walk directory tree to find {{ files_dir }} #}
65 | {%- set subpath_parts = tpldir.lstrip(tplroot).lstrip("/").split("/") %}
66 | {%- for path in subpath_parts %}
67 | {%- set subpath = subpath_parts[0 : loop.index] | join("/") %}
68 | {%- do path_prefix_exts.append("/" ~ subpath) %}
69 | {%- endfor %}
70 | {%- endif %}
71 | {%- for path_prefix_ext in path_prefix_exts | reverse %}
72 | {%- set path_prefix_inc_ext = path_prefix ~ path_prefix_ext %}
73 | {#- For older TOFS implementation, use `files_switch` from the config #}
74 | {#- Use the default, new method otherwise #}
75 | {%- set fsl = salt["config.get"](
76 | tplroot ~ path_prefix_ext | replace("/", ":") ~ ":files_switch",
77 | files_switch_list,
78 | ) %}
79 | {#- Append an empty value to evaluate as `default` in the loop below #}
80 | {%- if "" not in fsl %}
81 | {%- set fsl = fsl + [""] %}
82 | {%- endif %}
83 | {%- for fs in fsl %}
84 | {%- for src_file in src_files %}
85 | {%- if fs %}
86 | {%- set fs_dirs = salt["config.get"](fs, fs) %}
87 | {%- else %}
88 | {%- set fs_dirs = salt["config.get"](
89 | tplroot ~ ":tofs:dirs:default", "default"
90 | ) %}
91 | {%- endif %}
92 | {#- Force the `config.get` lookup result as a list where necessary #}
93 | {#- since we need to also handle grains that are lists #}
94 | {%- if fs_dirs is string %}
95 | {%- set fs_dirs = [fs_dirs] %}
96 | {%- endif %}
97 | {%- for fs_dir in fs_dirs %}
98 | {#- strip empty elements by using a select #}
99 | {%- set url = (
100 | [
101 | "- salt:/",
102 | path_prefix_inc_ext.strip("/"),
103 | files_dir.strip("/"),
104 | fs_dir.strip("/"),
105 | src_file.strip("/"),
106 | ]
107 | | select
108 | | join("/")
109 | ) %}
110 | {{ url | indent(indent_width, true) }}
111 | {%- endfor %}
112 | {%- endfor %}
113 | {%- endfor %}
114 | {%- endfor %}
115 | {%- endmacro %}
116 |
--------------------------------------------------------------------------------
/postgres/macos/init.sls:
--------------------------------------------------------------------------------
1 | {%- from salt.file.dirname(tpldir) ~ "/map.jinja" import postgres with context -%}
2 |
3 | include:
4 | {% if postgres.use_upstream_repo == 'postgresapp' %}
5 | - postgres.macos.postgresapp
6 | {% elif postgres.use_upstream_repo == 'homebrew' %}
7 | - postgres.server
8 | - postgres.client
9 | {% endif %}
10 | - postgres.dev
11 |
--------------------------------------------------------------------------------
/postgres/macos/postgresapp.sls:
--------------------------------------------------------------------------------
1 | {%- from salt.file.dirname(tpldir) ~ "/map.jinja" import postgres as pg with context -%}
2 |
3 | pg-extract-dirs:
4 | file.directory:
5 | - names:
6 | - '{{ pg.macos.tmpdir }}'
7 | - makedirs: True
8 | - require_in:
9 | - pg-download-archive
10 |
11 | pg-download-archive:
12 | pkg.installed:
13 | - name: curl
14 | cmd.run:
15 | - name: curl {{ pg.macos.dl.opts }} -o {{ pg.macos.tmpdir }}/{{ pg.macos.archive }} {{ pg.macos.postgresapp.url }}
16 | - unless: test -f {{ pg.macos.tmpdir }}/{{ pg.macos.archive }}
17 | {% if grains['saltversioninfo'] >= [2017, 7, 0] %}
18 | - retry:
19 | attempts: {{ pg.macos.dl.retries }}
20 | interval: {{ pg.macos.dl.interval }}
21 | until: True
22 | splay: 10
23 | {% endif %}
24 |
25 | {%- if pg.macos.postgresapp.sum %}
26 | pg-check-archive-hash:
27 | module.run:
28 | - name: file.check_hash
29 | - path: '{{ pg.macos.tmpdir }}/{{ pg.macos.archive }}'
30 | - file_hash: {{ pg.macos.postgresapp.sum }}
31 | - require:
32 | - cmd: pg-download-archive
33 | - require_in:
34 | - archive: pg-package-install
35 | {%- endif %}
36 |
37 | pg-package-install:
38 | macpackage.installed:
39 | - name: '{{ pg.macos.tmpdir }}/{{ pg.macos.archive }}'
40 | - store: True
41 | - dmg: True
42 | - app: True
43 | - force: True
44 | - allow_untrusted: True
45 | - onchanges:
46 | - cmd: pg-download-archive
47 | - require_in:
48 | - file: pg-package-install
49 | file.append:
50 | - name: {{ pg.userhomes }}/{{ pg.user }}/.bash_profile
51 | - text: 'export PATH=$PATH:/Applications/Postgres.app/Contents/Versions/latest/bin'
52 |
53 |
--------------------------------------------------------------------------------
/postgres/macros.jinja:
--------------------------------------------------------------------------------
1 | {%- from "postgres/map.jinja" import postgres with context -%}
2 |
3 | {%- macro format_kwargs(kwarg) -%}
4 |
5 | {%- filter indent(4) %}
6 | {%- for k, v in kwarg|dictsort() %}
7 | - {{ k }}: {{ v|yaml_dquote if v is string else v }}
8 | {%- endfor %}
9 | {%- endfilter %}
10 |
11 | {%- endmacro %}
12 |
13 | {%- macro format_state(name, state, kwarg) %}
14 |
15 | {%- if 'name' not in kwarg %}
16 | {%- do kwarg.update({'name': name}) %}
17 | {%- endif %}
18 | {%- if 'ensure' in kwarg %}
19 | {%- set ensure = kwarg.pop('ensure') %}
20 | {%- endif %}
21 | {%- set user_available = not (state == 'postgres_schema' and grains.saltversioninfo < [2018, 3]) %}
22 | {%- if 'user' not in kwarg and user_available %}
23 | {%- do kwarg.update({'user': postgres.user}) %}
24 | {%- endif -%}
25 |
26 | {{ state }}-{{ name }}:
27 | {{ state }}.{{ ensure|default('present') }}:
28 | {{- format_kwargs(kwarg) }}
29 | - onchanges:
30 | - test: postgres-reload-modules
31 |
32 | {%- endmacro %}
33 |
34 | # vim: ft=sls
35 |
--------------------------------------------------------------------------------
/postgres/manage.sls:
--------------------------------------------------------------------------------
1 | {%- from tpldir + "/map.jinja" import postgres with context -%}
2 | {%- from tpldir + "/macros.jinja" import format_state with context -%}
3 |
4 | {%- if salt['postgres.user_create']|default(none) is not callable %}
5 |
6 | # Salt states for managing PostgreSQL is not available,
7 | # need to provision client binaries first
8 |
9 | include:
10 | - postgres.client
11 | {%- if 'server_bins' in postgres and grains['saltversion'] == '2016.11.0' %}
12 | # FIXME: Salt v2016.11.0 bug https://github.com/saltstack/salt/issues/37935
13 | - postgres.server
14 | {%- endif %}
15 |
16 | {%- endif %}
17 |
18 | # Ensure that Salt is able to use postgres modules
19 |
20 | postgres-reload-modules:
21 | test.succeed_with_changes:
22 | - reload_modules: True
23 |
24 | # User states
25 |
26 | {%- for name, user in postgres.users|dictsort() %}
27 |
28 | {{ format_state(name, 'postgres_user', user) }}
29 |
30 | {%- endfor %}
31 |
32 | # Tablespace states
33 |
34 | {%- for name, tblspace in postgres.tablespaces|dictsort() %}
35 |
36 | {{ format_state(name, 'postgres_tablespace', tblspace) }}
37 | {%- if 'owner' in tblspace %}
38 | - require:
39 | - postgres_user: postgres_user-{{ tblspace.owner }}
40 | {%- endif %}
41 |
42 | {%- endfor %}
43 |
44 | # Database states
45 |
46 | {%- for name, db in postgres.databases|dictsort() %}
47 | {%- if 'extensions' in db %}
48 | {%- for ext_name, extension in db.pop('extensions')|dictsort() %}
49 | {%- do extension.update({'name': ext_name, 'maintenance_db': name}) %}
50 |
51 | {{ format_state( name + '-' + ext_name, 'postgres_extension', extension) }}
52 | - require:
53 | - postgres_database: postgres_database-{{ name }}
54 | {%- if 'schema' in extension and 'schemas' in postgres %}
55 | - postgres_schema: postgres_schema-{{ name }}-{{ extension.schema }}
56 | {%- endif %}
57 |
58 | {%- endfor %}
59 | {%- endif %}
60 | {%- if 'schemas' in db %}
61 | {%- for schema_name, schema in db.pop('schemas')|dictsort() %}
62 | {%- do schema.update({'name': schema_name, 'dbname': name }) %}
63 |
64 | {{ format_state( name + '-' + schema_name, 'postgres_schema', schema) }}
65 | - require:
66 | - postgres_database: postgres_database-{{ name }}
67 |
68 | {%- endfor %}
69 | {%- endif %}
70 |
71 | {{ format_state(name, 'postgres_database', db) }}
72 | {%- if 'owner' in db or 'tablespace' in db %}
73 | - require:
74 | {%- endif %}
75 | {%- if 'owner' in db %}
76 | - postgres_user: postgres_user-{{ db.owner }}
77 | {%- endif %}
78 | {%- if 'tablespace' in db %}
79 | - postgres_tablespace: postgres_tablespace-{{ db.tablespace }}
80 | {%- endif %}
81 |
82 | {%- endfor %}
83 |
84 | # Schema states
85 |
86 | {%- for name, schema in postgres.schemas|dictsort() %}
87 |
88 | {{ format_state(name, 'postgres_schema', schema) }}
89 | - require:
90 | - postgres_database-{{ schema.dbname }}
91 | {%- if 'owner' in schema %}
92 | - postgres_user: postgres_user-{{ schema.owner }}
93 | {%- endif %}
94 |
95 | {%- endfor %}
96 |
97 | # Extension states
98 |
99 | {%- for name, extension in postgres.extensions|dictsort() %}
100 |
101 | {{ format_state(name, 'postgres_extension', extension) }}
102 | {%- if 'maintenance_db' in extension or 'schema' in extension %}
103 | - require:
104 | {%- endif %}
105 | {%- if 'maintenance_db' in extension %}
106 | - postgres_database: postgres_database-{{ extension.maintenance_db }}
107 | {%- endif %}
108 | {%- if 'schema' in extension %}
109 | - postgres_schema: postgres_schema-{{ extension.schema }}
110 | {%- endif %}
111 |
112 | {%- endfor %}
113 |
--------------------------------------------------------------------------------
/postgres/map.jinja:
--------------------------------------------------------------------------------
1 | {% import_yaml "postgres/defaults.yaml" as defaults %}
2 | {% import_yaml "postgres/osfamilymap.yaml" as osfamilymap %}
3 | {% import_yaml "postgres/osmap.yaml" as osmap %}
4 | {% import_yaml "postgres/codenamemap.yaml" as oscodenamemap %}
5 |
6 | {% set postgres = salt['grains.filter_by'](
7 | defaults,
8 | merge=salt['grains.filter_by'](
9 | osfamilymap,
10 | grain='os_family',
11 | merge=salt['grains.filter_by'](
12 | osmap,
13 | grain='os',
14 | merge=salt['grains.filter_by'](
15 | oscodenamemap,
16 | grain='oscodename',
17 | merge=salt['pillar.get']('postgres', {}),
18 | ),
19 | ),
20 | ),
21 | base='postgres',
22 | ) %}
23 |
24 | {# Concatenate the cluster preparation command and then append it to the `postgres` dict #}
25 | {% set pc_cmd = '{0} {1}'.format(postgres.prepare_cluster.pgcommand, postgres.data_dir) %}
26 | {% if postgres.cluster.locale %}
27 | {% set pc_cmd = '{0} --locale={1}'.format(pc_cmd, postgres.cluster.locale) %}
28 | {% endif %}
29 | {% if postgres.cluster.encoding %}
30 | {% set pc_cmd = '{0} --encoding={1}'.format(pc_cmd, postgres.cluster.encoding) %}
31 | {% endif %}
32 | {% do postgres.update({'prepare_cluster_cmd': pc_cmd}) %}
33 |
--------------------------------------------------------------------------------
/postgres/osfamilymap.yaml:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # vim: ft=yaml
3 | ---
4 | {% import_yaml "postgres/repo.yaml" as repo %}
5 |
6 | {% set release = repo.version|replace('.', '') %}
7 |
8 | Arch:
9 | use_upstream_repo: false
10 | conf_dir: /var/lib/postgres/data
11 | data_dir: /var/lib/postgres/data
12 | pkg_client: postgresql-libs
13 | pkg_dev: postgresql
14 |
15 | Debian:
16 | pkgs_deps: ['python3-apt']
17 | pkg_repo:
18 | humanname: PostgreSQL Official Repository
19 | file: /etc/apt/sources.list.d/pgdg.list
20 | pkg_repo_keyring: 'https://download.postgresql.org/pub/repos/apt/pool/main/p/pgdg-keyring/pgdg-keyring_2018.2_all.deb'
21 | pkg_repo_keyid: ACCC4CF8
22 | {% if repo.use_upstream_repo == true %}
23 | pkg_dev: ''
24 | {% else %}
25 | pkg_dev: postgresql-server-dev-all
26 | {% endif %}
27 |
28 | FreeBSD:
29 | {% if repo.version|float >= 9.6 %}
30 | user: &freebsd-user postgres
31 | group: &freebsd-group postgres
32 | conf_dir: {{ '/var/db/postgres/data' ~ release }}
33 | data_dir: {{ '/var/db/postgres/data' ~ release }}
34 | {% else %}
35 | user: &freebsd-user pgsql
36 | group: &freebsd-group pgsql
37 | conf_dir: /usr/local/pgsql/data
38 | data_dir: /usr/local/pgsql/data
39 | {% endif %}
40 | pkg_libpq_dev: null #not in freebsd
41 | pkg_client: postgresql{{ release }}-client
42 | pkg: postgresql{{ release }}-server
43 | prepare_cluster:
44 | user: *freebsd-user
45 | group: *freebsd-group
46 | service:
47 | flags: -w -s -m fast
48 | sysrc: True
49 |
50 | OpenBSD:
51 | conf_dir: /var/postgresql/data
52 | data_dir: /var/postgresql/data
53 | user: _postgresql
54 | service:
55 | flags: -w -s -m fast
56 | sysrc: True
57 |
58 | RedHat:
59 | pkg_repo:
60 | name: pgdg{{ release }}
61 | humanname: PostgreSQL {{ repo.version }} $releasever - $basearch
62 | gpgcheck: 1
63 | gpgkey: 'https://download.postgresql.org/pub/repos/yum/RPM-GPG-KEY-PGDG-{{ release }}'
64 | baseurl: 'https://download.postgresql.org/pub/repos/yum/{{ repo.version }}/redhat/rhel-$releasever-$basearch'
65 |
66 | pkgs_deps:
67 | - libicu
68 | {%- if grains.get('osmajorrelease', 0) == 7 %}
69 | - systemd-sysv
70 | {%- endif %}
71 | pkg_python: python3-psycopg2
72 |
73 | {% if repo.use_upstream_repo == true %}
74 | {% set data_dir = '/var/lib/pgsql/' ~ repo.version ~ '/data' %}
75 |
76 | fromrepo: pgdg{{ release }}
77 | pkg: postgresql{{ release }}-server
78 | pkg_client: postgresql{{ release }}
79 | pkg_libs: postgresql{{ release }}-libs
80 | pkg_dev: postgresql{{ release }}-devel
81 | conf_dir: {{ data_dir }}
82 | data_dir: {{ data_dir }}
83 | service:
84 | name: postgresql-{{ repo.version }}
85 |
86 | # Alternatives system
87 | linux:
88 | altpriority: 30
89 |
90 | # directory containing PostgreSQL client executables
91 | bin_dir: /usr/pgsql-{{ repo.version }}/bin
92 | dev_bins:
93 | - ecg
94 | client_bins:
95 | - clusterdb
96 | - createdb
97 | - createlang
98 | - createuser
99 | - dropdb
100 | - droplang
101 | - dropuser
102 | - pg_archivecleanup
103 | - pg_basebackup
104 | - pg_config
105 | - pg_dump
106 | - pg_dumpall
107 | - pg_isready
108 | - pg_receivexlog
109 | - pg_restore
110 | - pg_rewind
111 | - pg_test_fsync
112 | - pg_test_timing
113 | - pg_upgrade
114 | - pg_xlogdump
115 | - pgbench
116 | - psql
117 | - reindexdb
118 | - vacuumdb
119 | server_bins:
120 | - initdb
121 | - pg_controldata
122 | - pg_ctl
123 | - pg_resetxlog
124 | - postgres
125 | - postgresql{{ release }}-check-db-dir
126 | - postgresql{{ release }}-setup
127 | - postmaster
128 |
129 | {% else %}
130 |
131 | pkg: postgresql-server
132 | pkg_client: postgresql
133 |
134 | {% endif %}
135 | pkg_libpq_dev: libpqxx-devel
136 | pkg_dev_deps:
137 | - perl-Time-HiRes
138 | - libicu-devel
139 | - perl-IPC-Run
140 | - perl-Test-Simple
141 |
142 | Suse:
143 | pkg_repo:
144 | name: pgdg-sles-{{ release }}
145 | humanname: PostgreSQL {{ repo.version }} $releasever - $basearch
146 | # works for postgres 11 onwards
147 | baseurl: 'https://download.postgresql.org/pub/repos/zypp/{{ repo.version }}/suse/sles-$releasever-$basearch'
148 | gpgkey: 'https://download.postgresql.org/pub/repos/zypp/{{ repo.version }}/suse/sles-$releasever-$basearch/repodata/repomd.xml.key'
149 | gpgcheck: 1
150 | gpgautoimport: True
151 |
152 | {% if repo.use_upstream_repo == true %}
153 | {% set data_dir = '/var/lib/pgsql/' ~ repo.version ~ '/data' %}
154 |
155 | fromrepo: pgdg-sles-{{ release }}
156 | pkg: postgresql{{ release }}-server
157 | pkg_client: postgresql{{ release }}
158 | pkg_dev: postgresql{{ release }}-devel
159 | pkg_libs: postgresql{{ release }}-libs
160 | conf_dir: {{ data_dir }}
161 | data_dir: {{ data_dir }}
162 | service:
163 | name: postgresql-{{ repo.version }}
164 |
165 | # Alternatives system
166 | linux:
167 | altpriority: 30
168 |
169 | # directory containing PostgreSQL client executables
170 | bin_dir: /usr/pgsql-{{ repo.version }}/bin
171 | dev_bins:
172 | - ecg
173 | client_bins:
174 | - pg_archivecleanup
175 | - pg_config
176 | - pg_isready
177 | - pg_receivexlog
178 | - pg_rewind
179 | - pg_test_fsync
180 | - pg_test_timing
181 | - pg_upgrade
182 | - pg_xlogdump
183 | - pgbench
184 | server_bins:
185 | - initdb
186 | - pg_controldata
187 | - pg_ctl
188 | - pg_resetxlog
189 | - postgres
190 | - postgresql{{ release }}-check-db-dir
191 | - postgresql{{ release }}-setup
192 | - postmaster
193 |
194 | {% else %}
195 |
196 | pkg: postgresql-server
197 | pkg_client: postgresql
198 |
199 | {% endif %}
200 | pkg_libpq_dev: libpqxx
201 |
202 | {%- if grains.os == 'MacOS' %}
203 | ## jinja check avoids rendering noise/failure on Linux
204 | MacOS:
205 | {%- if repo.use_upstream_repo == 'homebrew' %}
206 | service:
207 | name: homebrew.mxcl.postgresql
208 | {%- elif repo.use_upstream_repo == 'postgresapp' %}
209 | service:
210 | name: com.postgresapp.Postgres2
211 | {%- endif %}
212 | pkg: postgresql
213 | pkg_client:
214 | pkg_libpq_dev:
215 | userhomes: /Users
216 | user: {{ repo.user }}
217 | group: {{ repo.group }}
218 | conf_dir: /Users/{{ repo.user }}/Library/AppSupport/postgres_{{ repo.use_upstream_repo }}
219 | data_dir: /Users/{{ repo.user }}/Library/AppSupport/postgres_{{ repo.use_upstream_repo }}
220 | prepare_cluster:
221 | user: {{ repo.user }}
222 | group: {{ repo.group }}
223 | # macos limits
224 | limits:
225 | soft: 64000
226 | hard: 64000
227 | {%- endif %}
228 |
229 | # vim: ft=sls
230 |
--------------------------------------------------------------------------------
/postgres/osmap.yaml:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # vim: ft=yaml
3 | ---
4 | {% import_yaml "postgres/repo.yaml" as repo %}
5 |
6 | Fedora:
7 | pkg_repo:
8 | # yamllint disable-line rule:line-length
9 | baseurl: 'https://download.postgresql.org/pub/repos/yum/{{ repo.version }}/fedora/fedora-$releasever-$basearch'
10 | remove:
11 | releases: ['9.4', '9.5', '9.6', '10']
12 |
--------------------------------------------------------------------------------
/postgres/python.sls:
--------------------------------------------------------------------------------
1 | {% from tpldir + "/map.jinja" import postgres with context %}
2 |
3 | include:
4 | - postgres.upstream
5 |
6 | postgresql-python:
7 | pkg.installed:
8 | - name: {{ postgres.pkg_python }}
9 | {% if postgres.fromrepo %}
10 | - fromrepo: {{ postgres.fromrepo }}
11 | {% endif %}
12 | {% if 'pkg_repo' in postgres and postgres.use_upstream_repo == true %}
13 | - refresh: True
14 | - require:
15 | - pkgrepo: postgresql-repo
16 | {% endif %}
17 |
--------------------------------------------------------------------------------
/postgres/repo.yaml:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # vim: ft=yaml
3 | ---
4 | # This file allows to get PostgreSQL version and upstream repo settings
5 | # early from Pillar to set correct lookup dictionaty items
6 |
7 | {% import_yaml "postgres/defaults.yaml" as defaults %}
8 |
9 | use_upstream_repo: {{ salt['pillar.get']('postgres:use_upstream_repo', defaults.postgres.use_upstream_repo) }}
10 | version: {{ salt['pillar.get']('postgres:version', defaults.postgres.version) }}
11 | fromrepo: {{ salt['pillar.get']('postgres:fromrepo', defaults.postgres.fromrepo) }}
12 | cluster_name: {{ salt['pillar.get']('postgres:cluster:name', defaults.postgres.cluster.name) }}
13 |
14 | #Early lookup for system user on MacOS
15 | {% if grains.os == 'MacOS' %}
16 | {% set sysuser = salt['pillar.get']('postgres:user', salt['cmd.run']("stat -f '%Su' /dev/console")) %}
17 | {% set sysgroup = salt['pillar.get']('postgres:group', salt['cmd.run']("stat -f '%Sg' /dev/console")) %}
18 | user: {{ sysuser }}
19 | group: {{ sysgroup }}
20 | {% endif %}
21 |
22 | # vim: ft=sls
23 |
--------------------------------------------------------------------------------
/postgres/server/image.sls:
--------------------------------------------------------------------------------
1 | {%- from salt.file.dirname(tpldir) ~ "/map.jinja" import postgres with context -%}
2 |
3 | # This state is used to launch PostgreSQL with ``pg_ctl`` command and enable it
4 | # on "boot" during an image (Docker, Virtual Appliance, AMI) preparation
5 |
6 | {%- if postgres.bake_image %}
7 |
8 | # An attempt to start PostgreSQL with `pg_ctl`
9 | postgresql-running:
10 | cmd.run:
11 | - name: {{ postgres.bake_image_run_cmd }}
12 | - runas: {{ postgres.user }}
13 | - unless:
14 | - ps -p $(head -n 1 {{ postgres.data_dir }}/postmaster.pid) 2>/dev/null
15 | - require:
16 | - file: postgresql-pg_hba
17 |
18 | postgresql-service-reload:
19 | module.run:
20 | - name: test.true
21 | - require:
22 | - cmd: postgresql-running
23 |
24 | # Try to enable PostgreSQL in "manual" way
25 |
26 | postgresql-enable:
27 | cmd.run:
28 | {%- if salt['file.file_exists']('/bin/systemctl') %}
29 | - name: systemctl enable {{ postgres.service.name }}
30 | {%- elif salt['cmd.which']('chkconfig') %}
31 | - name: chkconfig {{ postgres.service.name }} on
32 | {%- elif salt['file.file_exists']('/usr/sbin/update-rc.d') %}
33 | - name: update-rc.d {{ postgres.service.name }} defaults
34 | {%- else %}
35 | # Nothing to do
36 | - name: 'true'
37 | {%- endif %}
38 | - require:
39 | - cmd: postgresql-running
40 |
41 | {%- endif %}
42 |
--------------------------------------------------------------------------------
/postgres/server/init.sls:
--------------------------------------------------------------------------------
1 | {%- from salt.file.dirname(tpldir) ~ "/map.jinja" import postgres with context -%}
2 |
3 | {%- set includes = [] %}
4 | {%- if postgres.bake_image %}
5 | {%- do includes.append('postgres.server.image') %}
6 | {%- endif %}
7 | {%- if postgres.use_upstream_repo == true -%}
8 | {%- do includes.append('postgres.upstream') %}
9 | {%- endif %}
10 |
11 | {%- if includes -%}
12 | include:
13 | {{ includes|yaml(false)|indent(2) }}
14 | {%- endif %}
15 |
16 | {%- set pkgs = [postgres.pkg] + postgres.pkgs_extra %}
17 | # Install, configure and start PostgreSQL server
18 | postgresql-server:
19 | pkg.installed:
20 | - pkgs: {{ pkgs | json }}
21 | {%- if 'pkg_repo' in postgres and postgres.use_upstream_repo == true %}
22 | - refresh: True
23 | - require:
24 | - pkgrepo: postgresql-repo
25 | {%- endif %}
26 | {%- if postgres.fromrepo %}
27 | - fromrepo: {{ postgres.fromrepo }}
28 | {%- endif %}
29 | {%- if grains.os == 'MacOS' %}
30 | #Register as Launchd LaunchAgent for system users
31 | - require_in:
32 | - file: postgresql-server
33 | file.managed:
34 | - name: /Library/LaunchAgents/{{ postgres.service.name }}.plist
35 | - source: /usr/local/opt/postgres/{{ postgres.service.name }}.plist
36 | - group: wheel
37 | - require_in:
38 | - service: postgresql-running
39 |
40 |
41 | # Alternatives system. Make server binaries available in $PATH
42 | {%- elif 'bin_dir' in postgres and postgres.linux.altpriority %}
43 | {%- for bin in postgres.server_bins %}
44 | {%- set path = salt['file.join'](postgres.bin_dir, bin) %}
45 |
46 | postgresql-{{ bin }}-altinstall:
47 | alternatives.install:
48 | - name: {{ bin }}
49 | - link: {{ salt['file.join']('/usr/bin', bin) }}
50 | - path: {{ path }}
51 | - priority: {{ postgres.linux.altpriority }}
52 | - onlyif: test -f {{ path }}
53 | - require:
54 | - pkg: postgresql-server
55 | - require_in:
56 | - cmd: postgresql-cluster-prepared
57 | {%- if grains['saltversioninfo'] < [2018, 11, 0, 0] %}
58 | - retry:
59 | attempts: 2
60 | until: True
61 | {%- endif %}
62 |
63 | {%- endfor %}
64 | {%- endif %}
65 |
66 | postgresql-cluster-prepared:
67 | file.directory:
68 | - name: {{ postgres.data_dir }}
69 | - user: {{ postgres.user }}
70 | - group: {{ postgres.group }}
71 | - makedirs: True
72 | - recurse:
73 | - user
74 | - group
75 | {%- if postgres.prepare_cluster.run %}
76 | cmd.run:
77 | {%- if postgres.prepare_cluster.command is defined %}
78 | {# support for depreciated 'prepare_cluster.command' pillar #}
79 | - name: {{ postgres.prepare_cluster.command }}
80 | - unless: {{ postgres.prepare_cluster.test }}
81 | {%- else %}
82 | - name: {{ postgres.prepare_cluster_cmd }}
83 | - unless: test -f {{ postgres.data_dir }}/{{ postgres.prepare_cluster.pgtestfile }}
84 | {%- endif %}
85 | - cwd: /
86 | - env: {{ postgres.prepare_cluster.env }}
87 | - runas: {{ postgres.prepare_cluster.user }}
88 | - require:
89 | - pkg: postgresql-server
90 | - file: postgresql-cluster-prepared
91 | - watch_in:
92 | - service: postgresql-running
93 | {%- endif %}
94 |
95 | postgresql-config-dir:
96 | file.directory:
97 | - names:
98 | - {{ postgres.data_dir }}
99 | - {{ postgres.conf_dir }}
100 | - user: {{ postgres.user }}
101 | - group: {{ postgres.group }}
102 | - dir_mode: {{ postgres.conf_dir_mode }}
103 | - force: True
104 | - recurse:
105 | - mode
106 | - ignore_files
107 | - makedirs: True
108 | - require:
109 | {%- if postgres.prepare_cluster.run %}
110 | - cmd: postgresql-cluster-prepared
111 | {%- else %}
112 | - file: postgresql-cluster-prepared
113 | {%- endif %}
114 |
115 | {%- set db_port = salt['config.option']('postgres.port') %}
116 | {%- if db_port %}
117 |
118 | postgresql-conf-comment-port:
119 | file.comment:
120 | - name: {{ postgres.conf_dir }}/postgresql.conf
121 | - regex: ^port\s*=.+
122 | - require:
123 | - file: postgresql-config-dir
124 |
125 | {%- endif %}
126 |
127 | {%- if postgres.postgresconf or db_port %}
128 |
129 | postgresql-conf:
130 | file.blockreplace:
131 | - name: {{ postgres.conf_dir }}/postgresql.conf
132 | - marker_start: "# Managed by SaltStack: listen_addresses: please do not edit"
133 | - marker_end: "# Managed by SaltStack: end of salt managed zone --"
134 | - content: |
135 | {%- if postgres.postgresconf %}
136 | {{ postgres.postgresconf|indent(8) }}
137 | {%- endif %}
138 | {%- if db_port %}
139 | port = {{ db_port }}
140 | {%- endif %}
141 | - show_changes: True
142 | - append_if_not_found: True
143 | {#- Detect empty values (none, '') in the config_backup #}
144 | - backup: {{ postgres.config_backup|default(false, true) }}
145 | - require:
146 | - file: postgresql-config-dir
147 | {%- if db_port %}
148 | - file: postgresql-conf-comment-port
149 | {%- endif %}
150 | - watch_in:
151 | - service: postgresql-running
152 |
153 | {%- endif %}
154 |
155 | {%- set pg_hba_path = salt['file.join'](postgres.conf_dir, 'pg_hba.conf') %}
156 |
157 | postgresql-pg_hba:
158 | file.managed:
159 | - name: {{ pg_hba_path }}
160 | - user: {{ postgres.user }}
161 | - group: {{ postgres.group }}
162 | - mode: 600
163 | {%- if postgres.acls %}
164 | - source: {{ postgres['pg_hba.conf'] }}
165 | - template: jinja
166 | - defaults:
167 | acls: {{ postgres.acls|yaml() }}
168 | {%- if postgres.config_backup %}
169 | # Create the empty file before managing to overcome the limitation of check_cmd
170 | - onlyif: test -f {{ pg_hba_path }} || touch {{ pg_hba_path }}
171 | # Make a local backup before the file modification
172 | - check_cmd: >-
173 | salt-call --local file.copy
174 | {{ pg_hba_path }} {{ pg_hba_path ~ postgres.config_backup }} remove_existing=true
175 | {%- endif %}
176 | {%- else %}
177 | - replace: False
178 | {%- endif %}
179 | - require:
180 | - file: postgresql-config-dir
181 | - watch_in:
182 | - service: postgresql-running
183 |
184 | {%- set pg_ident_path = salt['file.join'](postgres.conf_dir, 'pg_ident.conf') %}
185 |
186 | postgresql-pg_ident:
187 | file.managed:
188 | - name: {{ pg_ident_path }}
189 | - user: {{ postgres.user }}
190 | - group: {{ postgres.group }}
191 | - mode: 600
192 | {%- if postgres.identity_map %}
193 | - source: {{ postgres['pg_ident.conf'] }}
194 | - template: jinja
195 | - defaults:
196 | mappings: {{ postgres.identity_map|yaml() }}
197 | {%- if postgres.config_backup %}
198 | # Create the empty file before managing to overcome the limitation of check_cmd
199 | - onlyif: test -f {{ pg_ident_path }} || touch {{ pg_ident_path }}
200 | # Make a local backup before the file modification
201 | - check_cmd: >-
202 | salt-call --local file.copy
203 | {{ pg_ident_path }} {{ pg_ident_path ~ postgres.config_backup }} remove_existing=true
204 | {%- endif %}
205 | {%- else %}
206 | - replace: False
207 | {%- endif %}
208 | - require:
209 | - file: postgresql-config-dir
210 | {%- if postgres.prepare_cluster.run %}
211 | - cmd: postgresql-cluster-prepared
212 | {%- else %}
213 | - file: postgresql-cluster-prepared
214 | {%- endif %}
215 | - watch_in:
216 | {%- if grains.os not in ('MacOS',) %}
217 | - module: postgresql-service-reload
218 | {%- else %}
219 | - service: postgresql-running
220 | {%- endif %}
221 |
222 | {%- for name, tblspace in postgres.tablespaces|dictsort() %}
223 |
224 | postgresql-tablespace-dir-{{ name }}:
225 | file.directory:
226 | - name: {{ tblspace.directory }}
227 | - user: {{ postgres.user }}
228 | - group: {{ postgres.group }}
229 | - mode: 700
230 | - makedirs: True
231 | - recurse:
232 | - user
233 | - group
234 | - require:
235 | - pkg: postgresql-server
236 |
237 | {%- if "selinux" in grains and grains.selinux.enabled %}
238 |
239 | pkg.installed:
240 | - names:
241 | - policycoreutils-python
242 | - selinux-policy-targeted
243 | - refresh: True
244 | selinux.fcontext_policy_present:
245 | - name: '{{ tblspace.directory }}(/.*)?'
246 | - sel_type: postgresql_db_t
247 | - require:
248 | - file: postgresql-tablespace-dir-{{ name }}
249 | - pkg: postgresql-tablespace-dir-{{ name }}
250 |
251 | postgresql-tablespace-dir-{{ name }}-fcontext:
252 | selinux.fcontext_policy_applied:
253 | - name: {{ tblspace.directory }}
254 | - recursive: True
255 | - require:
256 | - selinux: postgresql-tablespace-dir-{{ name }}
257 |
258 | {%- endif %}
259 |
260 | {%- endfor %}
261 |
262 | {%- if not postgres.bake_image %}
263 |
264 | # Workaround for FreeBSD minion undefinitely hanging on service start
265 | # cf. https://github.com/saltstack/salt/issues/44848
266 | {% if postgres.service.sysrc %}
267 | posgresql-rc-flags:
268 | sysrc.managed:
269 | - name: {{ postgres.service.name }}_flags
270 | - value: "{{ postgres.service.flags }} > /dev/null 2>&1"
271 | - watch_in:
272 | - service: postgresql-running
273 | {% endif %}
274 |
275 | # Start PostgreSQL server using OS init
276 | # Note: This is also the target for numerous `watch_in` requisites above, used
277 | # for the necessary service restart after changing the relevant configuration files
278 | postgresql-running:
279 | service.running:
280 | - name: {{ postgres.service.name }}
281 | - enable: True
282 |
283 | # Reload the service for changes made to `pg_ident.conf`, except for `MacOS`
284 | # which is handled by `postgresql-running` above.
285 | {%- if grains.os not in ('MacOS',) %}
286 | postgresql-service-reload:
287 | module.wait:
288 | - name: service.reload
289 | - m_name: {{ postgres.service.name }}
290 | - require:
291 | - service: postgresql-running
292 | {%- endif %}
293 |
294 | {%- endif %}
295 |
--------------------------------------------------------------------------------
/postgres/server/remove.sls:
--------------------------------------------------------------------------------
1 | {%- from salt.file.dirname(tpldir) ~ "/map.jinja" import postgres with context -%}
2 |
3 | postgresql-dead:
4 | service.dead:
5 | - name: {{ postgres.service.name }}
6 | - enable: False
7 |
8 | postgresql-repo-removed:
9 | pkgrepo.absent:
10 | - name: {{ postgres.pkg_repo.name }}
11 | {%- if 'pkg_repo_keyid' in postgres %}
12 | - keyid: {{ postgres.pkg_repo_keyid }}
13 | {%- endif %}
14 |
15 | {% if grains.os_family == 'Debian' %}
16 | postgresql-repo-keyring-removed:
17 | pkg.removed:
18 | - name: pgdg-keyring
19 | {%- endif -%}
20 |
21 | #remove release installed by formula
22 | postgresql-server-removed:
23 | pkg.removed:
24 | - pkgs:
25 | {% if postgres.pkg %}
26 | - {{ postgres.pkg }}
27 | {% endif %}
28 | {% if postgres.pkgs_extra %}
29 | {% for pkg in postgres.pkgs_extra %}
30 | - {{ pkg }}
31 | {% endfor %}
32 | {% endif %}
33 | file.absent:
34 | - names:
35 | - /var/run/postgresql
36 |
37 | {%- if postgres.remove.multiple_releases %}
38 | #search for and cleandown multiple releases
39 |
40 | {% for release in postgres.remove.releases %}
41 | postgresql{{ release }}-server-pkgs-removed:
42 | pkg.purged:
43 | - pkgs:
44 | - {{ postgres.pkg if postgres.pkg else "postgresql" }}
45 | - postgresql-server
46 | - postgresql-libs
47 | - postgresql-contrib
48 | - postgresql-server-{{ release }}
49 | - postgresql-libs-{{ release }}
50 | - postgresql-contrib-{{ release }}
51 | - postgresql{{ release }}-contrib
52 | - postgresql{{ release }}-server
53 | - postgresql{{ release }}-libs
54 | - postgresql{{ release }}-contrib
55 | - postgresql{{ release|replace('.', '') }}-contrib
56 | - postgresql{{ release|replace('.', '') }}-server
57 | - postgresql{{ release|replace('.', '') }}-libs
58 | - postgresql{{ release|replace('.', '') }}-contrib
59 |
60 | {% if 'bin_dir' in postgres %}
61 | {% for bin in postgres.server_bins %}
62 | {% set path = '/usr/pgsql-' + release|string + '/bin/' + bin %}
63 |
64 | postgresql{{ release }}-server-{{ bin }}-alternative-remove:
65 | alternatives.remove:
66 | - name: {{ bin }}
67 | - path: {{ path }}
68 | {% if grains.os in ('Fedora', 'CentOS',) %}
69 | {# bypass bug #}
70 | - onlyif: alternatives --display {{ bin }}
71 | {% else %}
72 | - onlyif: test -f {{ path }}
73 | {% endif %}
74 |
75 | {% endfor %}
76 | {% endif %}
77 |
78 | {%- if postgres.remove.data %}
79 | #allow data loss? default is no
80 | postgresql{{ release }}-dataconf-removed:
81 | file.absent:
82 | - names:
83 | - {{ postgres.conf_dir }}
84 | - {{ postgres.data_dir }}
85 | - /var/lib/postgresql
86 | - /var/lib/pgsql
87 |
88 | {% for name, tblspace in postgres.tablespaces|dictsort() %}
89 | postgresql{{ release }}-tablespace-dir-{{ name }}-removed:
90 | file.absent:
91 | - name: {{ tblspace.directory }}
92 | - require:
93 | - file: postgresql{{ release }}-dataconf-removed
94 | {% endfor %}
95 | {% endif %}
96 |
97 | {% endfor %}
98 | {%- endif %}
99 |
--------------------------------------------------------------------------------
/postgres/templates/limit.maxfiles.plist:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 | Label
7 | limit.maxfiles
8 | ProgramArguments
9 |
10 | /bin/launchctl
11 | limit
12 | maxfiles
13 | {{ soft_limit }}
14 | {{ hard_limit }}
15 |
16 | RunAtLoad
17 |
18 | ServiceIPC
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/postgres/templates/mac_shortcut.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | shortcutName="${1}"
4 | app="postgres.app"
5 | Source="/Applications/$app"
6 | Destination="{{ homes }}/{{ user }}/Desktop/${shortcutName}"
7 | /usr/bin/osascript -e "tell application \"Finder\" to make alias file to POSIX file \"$Source\" at POSIX file \"$Destination\""
8 |
--------------------------------------------------------------------------------
/postgres/templates/pg_hba.conf.j2:
--------------------------------------------------------------------------------
1 | ######################################################################
2 | # ATTENTION! Managed by SaltStack. #
3 | # DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN! #
4 | ######################################################################
5 | #
6 | # PostgreSQL Client Authentication Configuration File
7 | # ===================================================
8 | #
9 | # Refer to the "Client Authentication" section in the PostgreSQL
10 | # documentation for a complete description of this file.
11 |
12 | # DO NOT DISABLE!
13 | # If you change this first entry you will need to make sure that the
14 | # database superuser can access the database using some other method.
15 | # Noninteractive access to all databases is required during automatic
16 | # maintenance (custom daily cronjobs, replication, and similar tasks).
17 |
18 | # Database administrative login by Unix domain socket
19 | local all postgres peer
20 |
21 | # TYPE DATABASE USER ADDRESS METHOD
22 |
23 | {% for acl in acls %}
24 | {%- if acl|first() == 'local' %}
25 |
26 | {%- if acl|length() == 3 %}
27 | {%- do acl.extend(['', 'md5']) %}
28 | {%- elif acl|length() == 4 %}
29 | {%- do acl.insert(3, '') %}
30 | {%- endif %}
31 |
32 | {%- else %}
33 |
34 | {%- if acl|length() == 4 %}
35 | {%- do acl.append('md5') %}
36 | {%- endif %}
37 |
38 | {%- endif %}
39 | {{ '{0:<7} {1:<15} {2:<15} {3:<23} {4}'.format(*acl) }}
40 | {% endfor %}
41 |
--------------------------------------------------------------------------------
/postgres/templates/pg_ident.conf.j2:
--------------------------------------------------------------------------------
1 | ######################################################################
2 | # ATTENTION! Managed by SaltStack. #
3 | # DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN! #
4 | ######################################################################
5 | #
6 | # PostgreSQL User Name Maps
7 | # =========================
8 | #
9 | # Refer to the PostgreSQL documentation, chapter "Client
10 | # Authentication" for a complete description. A short synopsis
11 | # follows.
12 | #
13 | # This file controls PostgreSQL user name mapping. It maps external
14 | # user names to their corresponding PostgreSQL user names. Records
15 | # are of the form:
16 | #
17 | # MAPNAME SYSTEM-USERNAME PG-USERNAME
18 | #
19 | # (The uppercase quantities must be replaced by actual values.)
20 | #
21 | # MAPNAME is the (otherwise freely chosen) map name that was used in
22 | # pg_hba.conf. SYSTEM-USERNAME is the detected user name of the
23 | # client. PG-USERNAME is the requested PostgreSQL user name. The
24 | # existence of a record specifies that SYSTEM-USERNAME may connect as
25 | # PG-USERNAME.
26 | #
27 | # If SYSTEM-USERNAME starts with a slash (/), it will be treated as a
28 | # regular expression. Optionally this can contain a capture (a
29 | # parenthesized subexpression). The substring matching the capture
30 | # will be substituted for \1 (backslash-one) if present in
31 | # PG-USERNAME.
32 | #
33 | # Multiple maps may be specified in this file and used by pg_hba.conf.
34 | #
35 | # No map names are defined in the default configuration. If all
36 | # system user names and PostgreSQL user names are the same, you don't
37 | # need anything in this file.
38 | #
39 | # This file is read on server startup and when the postmaster receives
40 | # a SIGHUP signal. If you edit the file on a running system, you have
41 | # to SIGHUP the postmaster for the changes to take effect. You can
42 | # use "pg_ctl reload" to do that.
43 |
44 | # Put your actual configuration here
45 | # ----------------------------------
46 |
47 | # MAPNAME SYSTEM-USERNAME PG-USERNAME
48 |
49 | {%- for mapping in mappings %}
50 | {{ '{0:<15} {1:<22} {2}'.format(*mapping) -}}
51 | {% endfor %}
52 |
--------------------------------------------------------------------------------
/postgres/templates/postgres.sh.j2:
--------------------------------------------------------------------------------
1 | ######################################################################
2 | # ATTENTION! Managed by SaltStack. #
3 | # DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN! #
4 | ######################################################################
5 |
6 | if ! echo $PATH | grep -q {{ bin_dir }} ; then
7 | export PATH=$PATH:{{ bin_dir }}
8 | fi
9 |
--------------------------------------------------------------------------------
/postgres/upstream.sls:
--------------------------------------------------------------------------------
1 | {%- from tpldir + "/map.jinja" import postgres with context -%}
2 | {%- from tpldir + "/macros.jinja" import format_kwargs with context -%}
3 |
4 | {%- if 'pkg_repo' in postgres -%}
5 | {% set pg_common_version = salt['pkg.version']('postgresql-common') %}
6 |
7 | {%- if postgres.use_upstream_repo == true -%}
8 |
9 | {%- if postgres.add_profile -%}
10 | postgresql-profile:
11 | file.managed:
12 | - name: /etc/profile.d/postgres.sh
13 | - user: root
14 | - group: root
15 | - mode: 644
16 | - template: jinja
17 | - source: salt://postgres/templates/postgres.sh.j2
18 | - defaults:
19 | bin_dir: {{ postgres.bin_dir }}
20 | {%- endif %}
21 |
22 | postgresql-pkg-deps:
23 | pkg.installed:
24 | - pkgs: {{ postgres.pkgs_deps | json }}
25 |
26 | # Add upstream repository for your distro
27 | {% if grains.os_family == 'Debian' %}
28 | {% if salt['pkg.version_cmp'](pg_common_version, '246') <= 0 %}
29 | postgresql-repo-keyring:
30 | pkg.installed:
31 | - sources:
32 | - pgdg-keyring: {{ postgres.pkg_repo_keyring }}
33 | - require_in:
34 | - pkgrepo: postgresql-repo
35 | {%- endif %}
36 | {%- endif %}
37 |
38 | postgresql-repo:
39 | pkgrepo.managed:
40 | {{- format_kwargs(postgres.pkg_repo) }}
41 | - require:
42 | - pkg: postgresql-pkg-deps
43 |
44 | {%- else -%}
45 |
46 | # Remove the repo configuration (and GnuPG key) as requested
47 | postgresql-repo:
48 | pkgrepo.absent:
49 | - name: {{ postgres.pkg_repo.name }}
50 | {%- if 'pkg_repo_keyid' in postgres %}
51 | - keyid: {{ postgres.pkg_repo_keyid }}
52 | {%- endif %}
53 |
54 | {% if grains.os_family == 'Debian' %}
55 | postgresql-repo-keyring:
56 | pkg.removed:
57 | - name: pgdg-keyring
58 | {%- endif -%}
59 |
60 | {%- endif -%}
61 |
62 | {%- elif grains.os not in ('Windows', 'MacOS',) %}
63 |
64 | postgresql-repo:
65 | test.show_notification:
66 | - text: |
67 | PostgreSQL does not provide package repository for {{ salt['grains.get']('osfinger', grains.os) }}
68 |
69 | {%- endif %}
70 |
--------------------------------------------------------------------------------
/pre-commit_semantic-release.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | ###############################################################################
4 | # (A) Update `FORMULA` with `${nextRelease.version}`
5 | ###############################################################################
6 | sed -i -e "s_^\(version:\).*_\1 ${1}_" FORMULA
7 |
8 |
9 | ###############################################################################
10 | # (B) Use `m2r2` to convert automatically produced `.md` docs to `.rst`
11 | ###############################################################################
12 |
13 | # Install `m2r2`
14 | pip3 install m2r2
15 |
16 | # Copy and then convert the `.md` docs
17 | cp ./*.md docs/
18 | cd docs/ || exit
19 | m2r2 --overwrite ./*.md
20 |
21 | # Change excess `H1` headings to `H2` in converted `CHANGELOG.rst`
22 | sed -i -e '/^=.*$/s/=/-/g' CHANGELOG.rst
23 | sed -i -e '1,4s/-/=/g' CHANGELOG.rst
24 |
25 | # Use for debugging output, when required
26 | # cat AUTHORS.rst
27 | # cat CHANGELOG.rst
28 |
29 | # Return back to the main directory
30 | cd ..
31 |
--------------------------------------------------------------------------------
/release-rules.js:
--------------------------------------------------------------------------------
1 | // No release is triggered for the types commented out below.
2 | // Commits using these types will be incorporated into the next release.
3 | //
4 | // NOTE: Any changes here must be reflected in `CONTRIBUTING.md`.
5 | module.exports = [
6 | {breaking: true, release: 'major'},
7 | // {type: 'build', release: 'patch'},
8 | // {type: 'chore', release: 'patch'},
9 | // {type: 'ci', release: 'patch'},
10 | {type: 'docs', release: 'patch'},
11 | {type: 'feat', release: 'minor'},
12 | {type: 'fix', release: 'patch'},
13 | {type: 'perf', release: 'patch'},
14 | {type: 'refactor', release: 'patch'},
15 | {type: 'revert', release: 'patch'},
16 | {type: 'style', release: 'patch'},
17 | {type: 'test', release: 'patch'},
18 | ];
19 |
--------------------------------------------------------------------------------
/release.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | branch: 'master',
3 | repositoryUrl: 'https://github.com/saltstack-formulas/postgres-formula',
4 | plugins: [
5 | ['@semantic-release/commit-analyzer', {
6 | preset: 'angular',
7 | releaseRules: './release-rules.js',
8 | }],
9 | '@semantic-release/release-notes-generator',
10 | ['@semantic-release/changelog', {
11 | changelogFile: 'CHANGELOG.md',
12 | changelogTitle: '# Changelog',
13 | }],
14 | ['@semantic-release/exec', {
15 | prepareCmd: 'sh ./pre-commit_semantic-release.sh ${nextRelease.version}',
16 | }],
17 | ['@semantic-release/git', {
18 | assets: ['*.md', 'docs/*.rst', 'FORMULA'],
19 | }],
20 | '@semantic-release/github',
21 | ],
22 | generateNotes: {
23 | preset: 'angular',
24 | writerOpts: {
25 | // Required due to upstream bug preventing all types being displayed.
26 | // Bug: https://github.com/conventional-changelog/conventional-changelog/issues/317
27 | // Fix: https://github.com/conventional-changelog/conventional-changelog/pull/410
28 | transform: (commit, context) => {
29 | const issues = []
30 |
31 | commit.notes.forEach(note => {
32 | note.title = `BREAKING CHANGES`
33 | })
34 |
35 | // NOTE: Any changes here must be reflected in `CONTRIBUTING.md`.
36 | if (commit.type === `feat`) {
37 | commit.type = `Features`
38 | } else if (commit.type === `fix`) {
39 | commit.type = `Bug Fixes`
40 | } else if (commit.type === `perf`) {
41 | commit.type = `Performance Improvements`
42 | } else if (commit.type === `revert`) {
43 | commit.type = `Reverts`
44 | } else if (commit.type === `docs`) {
45 | commit.type = `Documentation`
46 | } else if (commit.type === `style`) {
47 | commit.type = `Styles`
48 | } else if (commit.type === `refactor`) {
49 | commit.type = `Code Refactoring`
50 | } else if (commit.type === `test`) {
51 | commit.type = `Tests`
52 | } else if (commit.type === `build`) {
53 | commit.type = `Build System`
54 | // } else if (commit.type === `chore`) {
55 | // commit.type = `Maintenance`
56 | } else if (commit.type === `ci`) {
57 | commit.type = `Continuous Integration`
58 | } else {
59 | return
60 | }
61 |
62 | if (commit.scope === `*`) {
63 | commit.scope = ``
64 | }
65 |
66 | if (typeof commit.hash === `string`) {
67 | commit.shortHash = commit.hash.substring(0, 7)
68 | }
69 |
70 | if (typeof commit.subject === `string`) {
71 | let url = context.repository
72 | ? `${context.host}/${context.owner}/${context.repository}`
73 | : context.repoUrl
74 | if (url) {
75 | url = `${url}/issues/`
76 | // Issue URLs.
77 | commit.subject = commit.subject.replace(/#([0-9]+)/g, (_, issue) => {
78 | issues.push(issue)
79 | return `[#${issue}](${url}${issue})`
80 | })
81 | }
82 | if (context.host) {
83 | // User URLs.
84 | commit.subject = commit.subject.replace(/\B@([a-z0-9](?:-?[a-z0-9/]){0,38})/g, (_, username) => {
85 | if (username.includes('/')) {
86 | return `@${username}`
87 | }
88 |
89 | return `[@${username}](${context.host}/${username})`
90 | })
91 | }
92 | }
93 |
94 | // remove references that already appear in the subject
95 | commit.references = commit.references.filter(reference => {
96 | if (issues.indexOf(reference.issue) === -1) {
97 | return true
98 | }
99 |
100 | return false
101 | })
102 |
103 | return commit
104 | },
105 | },
106 | },
107 | };
108 |
--------------------------------------------------------------------------------
/test/integration/default/README.md:
--------------------------------------------------------------------------------
1 | # InSpec Profile: `default`
2 |
3 | This shows the implementation of the `default` InSpec [profile](https://github.com/inspec/inspec/blob/master/docs/profiles.md).
4 |
5 | ## Verify a profile
6 |
7 | InSpec ships with built-in features to verify a profile structure.
8 |
9 | ```bash
10 | $ inspec check default
11 | Summary
12 | -------
13 | Location: default
14 | Profile: profile
15 | Controls: 4
16 | Timestamp: 2019-06-24T23:09:01+00:00
17 | Valid: true
18 |
19 | Errors
20 | ------
21 |
22 | Warnings
23 | --------
24 | ```
25 |
26 | ## Execute a profile
27 |
28 | To run all **supported** controls on a local machine use `inspec exec /path/to/profile`.
29 |
30 | ```bash
31 | $ inspec exec default
32 | ..
33 |
34 | Finished in 0.0025 seconds (files took 0.12449 seconds to load)
35 | 8 examples, 0 failures
36 | ```
37 |
38 | ## Execute a specific control from a profile
39 |
40 | To run one control from the profile use `inspec exec /path/to/profile --controls name`.
41 |
42 | ```bash
43 | $ inspec exec default --controls package
44 | .
45 |
46 | Finished in 0.0025 seconds (files took 0.12449 seconds to load)
47 | 1 examples, 0 failures
48 | ```
49 |
50 | See an [example control here](https://github.com/inspec/inspec/blob/master/examples/profile/controls/example.rb).
51 |
--------------------------------------------------------------------------------
/test/integration/default/controls/services.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | service_name = 'postgresql'
4 |
5 | pg_port =
6 | case platform[:family]
7 | when 'debian', 'suse'
8 | 5433
9 | else
10 | 5432
11 | end
12 |
13 | control 'Postgres service' do
14 | impact 0.5
15 | title 'should be installed, enabled and running'
16 |
17 | describe service(service_name) do
18 | it { should be_installed }
19 | it { should be_enabled }
20 | it { should be_running }
21 | end
22 |
23 | describe port(pg_port) do
24 | it { should be_listening }
25 | end
26 | end
27 |
--------------------------------------------------------------------------------
/test/integration/default/controls/share.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # https://docs.chef.io/inspec/profiles/#including-all-controls-from-a-profile
4 | # Could use `include_controls` in this scenario
5 | # include_controls 'share'
6 |
7 | # https://docs.chef.io/inspec/profiles/#selectively-including-controls-from-a-profile
8 | # However, using `require_controls` for more clarity
9 | require_controls 'share' do
10 | control 'Postgres command'
11 | control 'Postgres configuration'
12 | # control 'Postgres service'
13 | end
14 |
--------------------------------------------------------------------------------
/test/integration/default/inspec.yml:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # vim: ft=yaml
3 | ---
4 | name: default
5 | title: postgres formula
6 | maintainer: SaltStack Formulas
7 | license: Apache-2.0
8 | summary: Verify that the postgres formula is setup and configured correctly
9 | depends:
10 | - name: share
11 | path: test/integration/share
12 | supports:
13 | - platform-name: debian
14 | - platform-name: ubuntu
15 | - platform-name: centos
16 | - platform-name: fedora
17 | - platform-name: opensuse
18 | - platform-name: suse
19 | - platform-name: freebsd
20 | - platform-name: openbsd
21 | - platform-name: amazon
22 | - platform-name: oracle
23 | - platform-name: arch
24 | - platform-name: gentoo
25 | - platform-name: almalinux
26 | - platform-name: rocky
27 | - platform-name: mac_os_x
28 | - platform: windows
29 |
--------------------------------------------------------------------------------
/test/integration/repo/README.md:
--------------------------------------------------------------------------------
1 | # InSpec Profile: `repo`
2 |
3 | This shows the implementation of the `repo` InSpec [profile](https://github.com/inspec/inspec/blob/master/docs/profiles.md).
4 |
5 | ## Verify a profile
6 |
7 | InSpec ships with built-in features to verify a profile structure.
8 |
9 | ```bash
10 | $ inspec check repo
11 | Summary
12 | -------
13 | Location: repo
14 | Profile: profile
15 | Controls: 4
16 | Timestamp: 2019-06-24T23:09:01+00:00
17 | Valid: true
18 |
19 | Errors
20 | ------
21 |
22 | Warnings
23 | --------
24 | ```
25 |
26 | ## Execute a profile
27 |
28 | To run all **supported** controls on a local machine use `inspec exec /path/to/profile`.
29 |
30 | ```bash
31 | $ inspec exec repo
32 | ..
33 |
34 | Finished in 0.0025 seconds (files took 0.12449 seconds to load)
35 | 8 examples, 0 failures
36 | ```
37 |
38 | ## Execute a specific control from a profile
39 |
40 | To run one control from the profile use `inspec exec /path/to/profile --controls name`.
41 |
42 | ```bash
43 | $ inspec exec repo --controls package
44 | .
45 |
46 | Finished in 0.0025 seconds (files took 0.12449 seconds to load)
47 | 1 examples, 0 failures
48 | ```
49 |
50 | See an [example control here](https://github.com/inspec/inspec/blob/master/examples/profile/controls/example.rb).
51 |
--------------------------------------------------------------------------------
/test/integration/repo/controls/repository.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | case platform.family
4 | when 'redhat', 'fedora', 'suse'
5 | os_name_repo_file = {
6 | 'opensuse' => '/etc/zypp/repos.d/pgdg-sles-13.repo'
7 | }
8 | os_name_repo_file.default = '/etc/yum.repos.d/pgdg13.repo'
9 |
10 | os_name_repo_url = {
11 | 'amazon' => 'https://download.postgresql.org/pub/repos/yum/13/redhat/rhel-7-$basearch',
12 | 'fedora' => 'https://download.postgresql.org/pub/repos/yum/13/fedora/fedora-$releasever-$basearch',
13 | 'opensuse' => 'https://download.postgresql.org/pub/repos/zypp/13/suse/sles-$releasever-$basearch'
14 | }
15 | os_name_repo_url.default = 'https://download.postgresql.org/pub/repos/yum/13/redhat/rhel-$releasever-$basearch'
16 |
17 | repo_url = os_name_repo_url[platform.name]
18 | repo_file = os_name_repo_file[platform.name]
19 |
20 | when 'debian'
21 | repo_keyring = '/usr/share/postgresql-common/pgdg/apt.postgresql.org.gpg'
22 | repo_file = '/etc/apt/sources.list.d/pgdg.list'
23 | # rubocop:disable Layout/LineLength
24 | repo_url = "deb [signed-by=#{repo_keyring}] http://apt.postgresql.org/pub/repos/apt #{system.platform[:codename]}-pgdg main"
25 | # rubocop:enable Layout/LineLength
26 | end
27 |
28 | control 'Postgresql repository keyring' do
29 | title 'should be installed'
30 |
31 | only_if('Requirement for Debian family') do
32 | os.debian?
33 | end
34 |
35 | describe package('pgdg-keyring') do
36 | it { should be_installed }
37 | end
38 |
39 | describe file(repo_keyring) do
40 | it { should exist }
41 | it { should be_owned_by 'root' }
42 | it { should be_grouped_into 'root' }
43 | its('mode') { should cmp '0644' }
44 | end
45 | end
46 |
47 | control 'Postgresql repository' do
48 | impact 1
49 | title 'should be configured'
50 | describe file(repo_file) do
51 | its('content') { should include repo_url }
52 | end
53 | end
54 |
--------------------------------------------------------------------------------
/test/integration/repo/controls/services.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | service_name =
4 | case platform[:family]
5 | when 'redhat', 'fedora', 'suse'
6 | case system.platform[:release]
7 | when 'tumbleweed'
8 | 'postgresql'
9 | else
10 | 'postgresql-13'
11 | end
12 | else
13 | 'postgresql'
14 | end
15 |
16 | pg_port =
17 | case platform[:family]
18 | when 'debian', 'suse'
19 | 5433
20 | else
21 | 5432
22 | end
23 |
24 | control 'Postgres service' do
25 | impact 0.5
26 | title 'should be installed, enabled and running'
27 |
28 | describe service(service_name) do
29 | it { should be_installed }
30 | it { should be_enabled }
31 | it { should be_running }
32 | end
33 |
34 | describe port(pg_port) do
35 | it { should be_listening }
36 | end
37 | end
38 |
--------------------------------------------------------------------------------
/test/integration/repo/controls/share.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # https://docs.chef.io/inspec/profiles/#including-all-controls-from-a-profile
4 | # Could use `include_controls` in this scenario
5 | # include_controls 'share'
6 |
7 | # https://docs.chef.io/inspec/profiles/#selectively-including-controls-from-a-profile
8 | # However, using `require_controls` for more clarity
9 | require_controls 'share' do
10 | control 'Postgres command'
11 | control 'Postgres configuration'
12 | # control 'Postgres service'
13 | end
14 |
--------------------------------------------------------------------------------
/test/integration/repo/inspec.yml:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # vim: ft=yaml
3 | ---
4 | name: repo
5 | title: postgres formula
6 | maintainer: SaltStack Formulas
7 | license: Apache-2.0
8 | # yamllint disable-line rule:line-length
9 | summary: Verify that the postgres formula is setup and configured correctly (when installing from the upstream repo)
10 | depends:
11 | - name: share
12 | path: test/integration/share
13 | supports:
14 | - platform-name: debian
15 | - platform-name: ubuntu
16 | - platform-name: centos
17 | - platform-name: fedora
18 | - platform-name: opensuse
19 | - platform-name: suse
20 | - platform-name: freebsd
21 | - platform-name: openbsd
22 | - platform-name: amazon
23 | - platform-name: oracle
24 | - platform-name: arch
25 | - platform-name: gentoo
26 | - platform-name: almalinux
27 | - platform-name: rocky
28 | - platform-name: mac_os_x
29 | - platform: windows
30 |
--------------------------------------------------------------------------------
/test/integration/share/README.md:
--------------------------------------------------------------------------------
1 | # InSpec Profile: `share`
2 |
3 | This shows the implementation of the `share` InSpec [profile](https://github.com/inspec/inspec/blob/master/docs/profiles.md).
4 |
5 | Its goal is to share the libraries between all profiles.
6 |
7 | ## Libraries
8 |
9 | ### `system`
10 |
11 | The `system` library provides easy access to system dependent information:
12 |
13 | - `system.platform`: based on `inspec.platform`, modify to values that are more consistent from a SaltStack perspective
14 | - `system.platform[:family]` provide a family name for Arch and Gentoo
15 | - `system.platform[:name]` append `linux` to both `amazon` and `oracle`; ensure Windows platforms are resolved as simply `windows`
16 | - `system.platform[:release]` tweak Arch, Amazon Linux, Gentoo, openSUSE and Windows:
17 | - `Arch` is always `base-latest`
18 | - `Amazon Linux` release `2018` is resolved as `1`
19 | - `Gentoo` release is trimmed to its major version number and then the init system is appended (i.e. `sysv` or `sysd`)
20 | - `openSUSE` is resolved as `tumbleweed` if the `platform[:release]` is in date format
21 | - `Windows` uses the widely-used release number (e.g. `8.1` or `2019-server`) in place of the actual system release version
22 | - `system.platform[:finger]` is the concatenation of the name and the major release number (except for Ubuntu, which gives `ubuntu-20.04` for example)
23 |
--------------------------------------------------------------------------------
/test/integration/share/controls/command.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Overide by Platform
4 | pg_port = '5432'
5 | pg_port = '5433' if (platform[:family] == 'debian') || (platform[:family] == 'suse')
6 |
7 | control 'Postgres command' do
8 | title 'should match desired lines'
9 |
10 | # Can't use `%Q` here due to the `\`
11 | describe command("su - postgres -c 'psql -p#{pg_port} -qtc \"\\l+ db2\"'") do
12 | its(:stdout) do
13 | should match(
14 | /db2.*remoteUser.*UTF8.*en_US.UTF-8.*en_US.UTF-8.*my_space/
15 | )
16 | end
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/test/integration/share/controls/config.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | control 'Postgres configuration' do
4 | title 'should include the directory'
5 |
6 | describe file('/srv/my_tablespace') do
7 | it { should be_directory }
8 | it { should be_owned_by 'postgres' }
9 | it { should be_grouped_into 'postgres' }
10 | its('mode') { should cmp '0700' }
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/test/integration/share/inspec.yml:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # vim: ft=yaml
3 | ---
4 | name: share
5 | title: InSpec shared resources
6 | maintainer: SaltStack Formulas
7 | license: Apache-2.0
8 | summary: shared resources
9 | supports:
10 | - platform-name: debian
11 | - platform-name: ubuntu
12 | - platform-name: centos
13 | - platform-name: fedora
14 | - platform-name: opensuse
15 | - platform-name: suse
16 | - platform-name: freebsd
17 | - platform-name: openbsd
18 | - platform-name: amazon
19 | - platform-name: oracle
20 | - platform-name: arch
21 | - platform-name: gentoo
22 | - platform-name: almalinux
23 | - platform-name: rocky
24 | - platform-name: mac_os_x
25 | - platform: windows
26 |
--------------------------------------------------------------------------------
/test/integration/share/libraries/system.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # system.rb -- InSpec resources for system values
4 | # Author: Daniel Dehennin
5 | # Copyright (C) 2020 Daniel Dehennin
6 |
7 | # rubocop:disable Metrics/ClassLength
8 | class SystemResource < Inspec.resource(1)
9 | name 'system'
10 |
11 | attr_reader :platform
12 |
13 | def initialize
14 | super
15 | @platform = build_platform
16 | end
17 |
18 | private
19 |
20 | def build_platform
21 | {
22 | family: build_platform_family,
23 | name: build_platform_name,
24 | release: build_platform_release,
25 | finger: build_platform_finger,
26 | codename: build_platform_codename
27 | }
28 | end
29 |
30 | def build_platform_family
31 | case inspec.platform[:name]
32 | when 'arch', 'gentoo'
33 | inspec.platform[:name]
34 | else
35 | inspec.platform[:family]
36 | end
37 | end
38 |
39 | def build_platform_name
40 | case inspec.platform[:name]
41 | when 'amazon', 'oracle', 'rocky'
42 | "#{inspec.platform[:name]}linux"
43 | when /^windows_/
44 | inspec.platform[:family]
45 | else
46 | inspec.platform[:name]
47 | end
48 | end
49 |
50 | # rubocop:disable Metrics/MethodLength,Metrics/AbcSize,Metrics/CyclomaticComplexity
51 | def build_platform_release
52 | case inspec.platform[:name]
53 | when 'amazon'
54 | # `2018` relase is named `1` in `kitchen.yml`
55 | inspec.platform[:release].gsub(/2018.*/, '1')
56 | when 'arch'
57 | 'base-latest'
58 | when 'gentoo'
59 | "#{inspec.platform[:release].split('.')[0]}-#{derive_gentoo_init_system}"
60 | when 'mac_os_x'
61 | inspec.command('sw_vers -productVersion').stdout.to_s
62 | when 'opensuse'
63 | # rubocop:disable Style/NumericLiterals,Layout/LineLength
64 | inspec.platform[:release].to_i > 20210101 ? 'tumbleweed' : inspec.platform[:release]
65 | # rubocop:enable Style/NumericLiterals,Layout/LineLength
66 | when 'windows_8.1_pro'
67 | '8.1'
68 | when 'windows_server_2022_datacenter'
69 | '2022-server'
70 | when 'windows_server_2019_datacenter'
71 | '2019-server'
72 | when 'windows_server_2016_datacenter'
73 | '2016-server'
74 | else
75 | inspec.platform[:release]
76 | end
77 | end
78 | # rubocop:enable Metrics/MethodLength,Metrics/AbcSize,Metrics/CyclomaticComplexity
79 |
80 | def derive_gentoo_init_system
81 | inspec.command('systemctl').exist? ? 'sysd' : 'sysv'
82 | end
83 |
84 | def build_platform_finger
85 | "#{build_platform_name}-#{build_finger_release}"
86 | end
87 |
88 | def build_finger_release
89 | case inspec.platform[:name]
90 | when 'ubuntu'
91 | build_platform_release.split('.').slice(0, 2).join('.')
92 | else
93 | build_platform_release.split('.')[0]
94 | end
95 | end
96 |
97 | # rubocop:disable Metrics/MethodLength,Metrics/CyclomaticComplexity
98 | def build_platform_codename
99 | case build_platform_finger
100 | when 'ubuntu-22.04'
101 | 'jammy'
102 | when 'ubuntu-20.04'
103 | 'focal'
104 | when 'ubuntu-18.04'
105 | 'bionic'
106 | when 'debian-11'
107 | 'bullseye'
108 | when 'debian-10'
109 | 'buster'
110 | when 'debian-9'
111 | 'stretch'
112 | when 'almalinux-8'
113 | "AlmaLinux #{build_platform_release} (Arctic Sphynx)"
114 | when 'amazonlinux-2'
115 | 'Amazon Linux 2'
116 | when 'arch-base-latest'
117 | 'Arch Linux'
118 | when 'centos-7'
119 | 'CentOS Linux 7 (Core)'
120 | when 'centos-8'
121 | 'CentOS Stream 8'
122 | when 'opensuse-tumbleweed'
123 | 'openSUSE Tumbleweed'
124 | when 'opensuse-15'
125 | "openSUSE Leap #{build_platform_release}"
126 | when 'oraclelinux-8', 'oraclelinux-7'
127 | "Oracle Linux Server #{build_platform_release}"
128 | when 'gentoo-2-sysd', 'gentoo-2-sysv'
129 | 'Gentoo/Linux'
130 | when 'rockylinux-8'
131 | "Rocky Linux #{build_platform_release} (Green Obsidian)"
132 | else
133 | ''
134 | end
135 | end
136 | # rubocop:enable Metrics/MethodLength,Metrics/CyclomaticComplexity
137 | end
138 | # rubocop:enable Metrics/ClassLength
139 |
--------------------------------------------------------------------------------
/test/salt/pillar/postgres.sls:
--------------------------------------------------------------------------------
1 | # Port to use for the cluster -- can be used to provide a non-standard port
2 | # NOTE: If already set in the minion config, that value takes priority
3 |
4 | {%- if grains.os_family not in ['Debian', 'Suse'] %}
5 | postgres.port: '5432'
6 | {%- else %}
7 | postgres.port: '5433'
8 | {%- endif %}
9 |
10 | postgres:
11 | use_upstream_repo: false
12 |
13 | # ### MACOS
14 | # # Set to 'postgresapp' OR 'homebrew' for MacOS
15 | # # use_upstream_repo: 'postgresapp'
16 | # # use_upstream_repo: 'homebrew'
17 |
18 | # # PACKAGE
19 | # # These pillars are typically never required.
20 | # # pkg: 'postgresql'
21 | # # pkg_client: 'postgresql-client'
22 | # # service: postgresql
23 | # pkgs_extra:
24 | # - postgresql-contrib
25 | # - postgresql-plpython
26 |
27 | # CLUSTER
28 | # The default `encoding` is derived from the `locale` so not recommended
29 | # to provide a value for it unless necessary
30 | cluster:
31 | locale: en_US.UTF-8
32 | # encoding: UTF8
33 |
34 | # #'Alternatives system' priority incremental. 0 disables feature.
35 | # linux:
36 | # altpriority: 30
37 | #
38 | # # macos limits
39 | # limits:
40 | # soft: 64000
41 | # hard: 128000
42 |
43 | # POSTGRES
44 | # Append the lines under this item to your postgresql.conf file.
45 | # Pay attention to indent exactly with 4 spaces for all lines.
46 | postgresconf: |-
47 | listen_addresses = '*' # listen on all interfaces
48 |
49 | # Path to the `pg_hba.conf` file Jinja template on Salt Fileserver
50 | pg_hba.conf: salt://postgres/templates/pg_hba.conf.j2
51 |
52 | # This section covers ACL management in the ``pg_hba.conf`` file.
53 | # acls list controls: which hosts are allowed to connect, how clients
54 | # are authenticated, which PostgreSQL user names they can use, which
55 | # databases they can access. Records take one of these forms:
56 | #
57 | # acls:
58 | # - ['local', 'DATABASE', 'USER', 'METHOD']
59 | # - ['host', 'DATABASE', 'USER', 'ADDRESS', 'METHOD']
60 | # - ['hostssl', 'DATABASE', 'USER', 'ADDRESS', 'METHOD']
61 | # - ['hostnossl', 'DATABASE', 'USER', 'ADDRESS', 'METHOD']
62 | #
63 | # The uppercase items must be replaced by actual values.
64 | # METHOD could be omitted, 'md5' will be appended by default.
65 | #
66 | # If ``acls`` item value is empty ('', [], null), then the contents of
67 | # ``pg_hba.conf`` file will not be touched at all.
68 | acls:
69 | - ['local', 'db0', 'connuser', 'peer map=users_as_appuser']
70 | - ['local', 'db1', 'localUser']
71 | - ['host', 'db2', 'remoteUser', '192.168.33.0/24']
72 |
73 | identity_map:
74 | - ['users_as_appuser', 'jdoe', 'connuser']
75 | - ['users_as_appuser', 'jsmith', 'connuser']
76 |
77 | # Backup extension for configuration files, defaults to ``.bak``.
78 | # Set ``False`` to stop creation of backups when config files change.
79 | {%- if salt['status.time']|default(none) is callable %}
80 | config_backup: ".backup@{{ salt['status.time']('%y-%m-%d_%H:%M:%S') }}"
81 | {%- endif %}
82 |
83 | {# {%- if grains['init'] == 'unknown' %} #}
84 | {# #}
85 | {# # If Salt is unable to detect init system running in the scope of state run, #}
86 | {# # probably we are trying to bake a container/VM image with PostgreSQL. #}
87 | {# # Use ``bake_image`` setting to control how PostgreSQL will be started: if set #}
88 | {# # to ``True`` the raw ``pg_ctl`` will be utilized instead of packaged init #}
89 | {# # script, job or unit run with Salt ``service`` state. #}
90 | {# bake_image: True #}
91 | {# #}
92 | {# {%- endif %} #}
93 |
94 | # Create/remove users, tablespaces, databases, schema and extensions.
95 | # Each of these dictionaries contains PostgreSQL entities which
96 | # mapped to the ``postgres_*`` Salt states with arguments. See the Salt
97 | # documentation to get all supported argument for a particular state.
98 | #
99 | # Format is the following:
100 | #
101 | #:
102 | # NAME:
103 | # ensure: # 'present' is the default
104 | # ARGUMENT: VALUE
105 | # ...
106 | #
107 | # where 'NAME' is the state name, 'ARGUMENT' is the kwarg name, and
108 | # 'VALUE' is kwarg value.
109 | #
110 | # For example, the Pillar:
111 | #
112 | # users:
113 | # testUser:
114 | # password: test
115 | #
116 | # will render such state:
117 | #
118 | # postgres_user-testUser:
119 | # postgres_user.present:
120 | # - name: testUser
121 | # - password: test
122 | users:
123 | localUser:
124 | ensure: present
125 | password: '98ruj923h4rf'
126 | createdb: False
127 | createroles: False
128 | inherit: True
129 | replication: False
130 |
131 | remoteUser:
132 | ensure: present
133 | password: '98ruj923h4rf'
134 | createdb: False
135 | createroles: False
136 | inherit: True
137 | replication: False
138 |
139 | absentUser:
140 | ensure: absent
141 |
142 | # tablespaces to be created
143 | tablespaces:
144 | my_space:
145 | directory: /srv/my_tablespace
146 | owner: localUser
147 |
148 | # databases to be created
149 | databases:
150 | db1:
151 | owner: localUser
152 | template: template0
153 | lc_ctype: en_US.UTF-8
154 | lc_collate: en_US.UTF-8
155 | db2:
156 | owner: remoteUser
157 | template: template0
158 | lc_ctype: en_US.UTF-8
159 | lc_collate: en_US.UTF-8
160 | tablespace: my_space
161 | # set custom schema
162 | schemas:
163 | public:
164 | owner: localUser
165 | # enable per-db extension
166 | {#- TODO: Find a way to only disable this for the `default` suite, since it works with the `repo` suite #}
167 | {%- if grains.os_family == 'Debian' and salt['grains.get']('osfinger') != 'Debian-9' %}
168 | extensions:
169 | uuid-ossp:
170 | schema: 'public'
171 | {%- endif %}
172 |
173 | # optional schemas to enable on database
174 | schemas:
175 | uuid-ossp:
176 | dbname: db1
177 | owner: localUser
178 |
179 | # optional extensions to install in schema
180 | {#- TODO: Find a way to only disable this for the `default` suite, since it works with the `repo` suite #}
181 | {%- if grains.os_family == 'Debian' and salt['grains.get']('osfinger') != 'Debian-9' %}
182 | extensions:
183 | uuid-ossp:
184 | schema: uuid-ossp
185 | maintenance_db: db1
186 | # postgis: {}
187 | {%- endif %}
188 |
189 | # remove:
190 | # data: True
191 | # multiple_releases: True
192 | # releases: ['9.6', '10',]
193 |
194 | # vim: ft=yaml ts=2 sts=2 sw=2 et
195 |
--------------------------------------------------------------------------------
/test/salt/pillar/repo.sls:
--------------------------------------------------------------------------------
1 | ---
2 | postgres:
3 | use_upstream_repo: true
4 | version: '13'
5 |
--------------------------------------------------------------------------------