├── .github
└── workflows
│ ├── commitlint.yml
│ ├── kitchen.vagrant.yml
│ └── kitchen.windows.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
└── map.jinja.rst
├── kitchen.vagrant.yml
├── kitchen.windows.yml
├── kitchen.yml
├── openvpn
├── _mapdata
│ ├── _mapdata.jinja
│ └── init.sls
├── adapters.sls
├── config.sls
├── dhparams.sls
├── files
│ ├── client.jinja
│ ├── common_opts.jinja
│ ├── ifconfig_pool_persist.jinja
│ ├── openvpn-1.cer
│ ├── openvpn-2.cer
│ ├── peer.jinja
│ ├── server.jinja
│ └── tap-adapter.ps1
├── general_config.sls
├── gui.sls
├── hardening.sls
├── ifconfig_pool_persist.sls
├── init.sls
├── install.sls
├── libmapstack.jinja
├── libmatchers.jinja
├── libsaltcli.jinja
├── macros.jinja
├── map.jinja
├── network_manager_networks
│ ├── files
│ │ └── connection.jinja
│ └── init.sls
├── parameters
│ ├── defaults.yaml
│ ├── defaults.yaml.jinja
│ ├── map_jinja.yaml
│ ├── os
│ │ ├── Debian.yaml
│ │ ├── Fedora.yaml
│ │ └── Ubuntu.yaml
│ ├── os_family
│ │ ├── Arch.yaml
│ │ ├── Debian.yaml
│ │ ├── FreeBSD.yaml
│ │ ├── RedHat.yaml
│ │ └── Windows.yaml
│ ├── oscodename
│ │ └── openSUSE Tumbleweed.yaml
│ └── osfinger
│ │ └── CentOS-6.yaml
├── repo.sls
└── service.sls
├── pillar.example
├── pre-commit_semantic-release.sh
├── release-rules.js
├── release.config.js
└── test
├── integration
├── default
│ ├── README.md
│ ├── controls
│ │ ├── _mapdata.rb
│ │ ├── config_spec.rb
│ │ ├── packages_spec.rb
│ │ └── services_spec.rb
│ ├── files
│ │ └── _mapdata
│ │ │ ├── amazonlinux-1.yaml
│ │ │ ├── amazonlinux-2.yaml
│ │ │ ├── arch-base-latest.yaml
│ │ │ ├── centos-6.yaml
│ │ │ ├── centos-7.yaml
│ │ │ ├── centos-8.yaml
│ │ │ ├── debian-10.yaml
│ │ │ ├── debian-11.yaml
│ │ │ ├── debian-9.yaml
│ │ │ ├── fedora-31.yaml
│ │ │ ├── fedora-32.yaml
│ │ │ ├── fedora-33.yaml
│ │ │ ├── gentoo-2-sysd.yaml
│ │ │ ├── gentoo-2-sysv.yaml
│ │ │ ├── opensuse-15.yaml
│ │ │ ├── opensuse-tumbleweed.yaml
│ │ │ ├── oraclelinux-7.yaml
│ │ │ ├── oraclelinux-8.yaml
│ │ │ ├── ubuntu-16.yaml
│ │ │ ├── ubuntu-18.yaml
│ │ │ ├── ubuntu-20.yaml
│ │ │ ├── ubuntu-22.yaml
│ │ │ ├── windows-10.yaml
│ │ │ ├── windows-2016-server.yaml
│ │ │ ├── windows-2019-server.yaml
│ │ │ ├── windows-2022-server.yaml
│ │ │ └── windows-8.yaml
│ └── inspec.yml
└── share
│ ├── README.md
│ ├── inspec.yml
│ └── libraries
│ └── system.rb
└── salt
└── pillar
└── default.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 (Windows)'
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-windows-10-latest-py3
18 | - default-windows-81-latest-py3
19 | steps:
20 | - name: 'Check out code'
21 | uses: 'actions/checkout@v2'
22 | - name: 'Set up Bundler cache'
23 | uses: 'actions/cache@v1'
24 | with:
25 | path: 'vendor/bundle'
26 | key: "${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}"
27 | restore-keys: "${{ runner.os }}-gems-"
28 | - name: 'Run Bundler'
29 | run: |
30 | ruby --version
31 | bundle config path vendor/bundle
32 | bundle install --jobs 4 --retry 3
33 | - name: 'Run Test Kitchen'
34 | run: 'bundle exec kitchen verify ${{ matrix.instance }}'
35 |
--------------------------------------------------------------------------------
/.github/workflows/kitchen.windows.yml:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # vim: ft=yaml
3 | ---
4 | name: 'Kitchen (Windows)'
5 | 'on': ['push', 'pull_request']
6 |
7 | env:
8 | machine_user: kitchen
9 | machine_pass: Pass@word1
10 | machine_port: 5985
11 | KITCHEN_LOCAL_YAML: 'kitchen.windows.yml'
12 |
13 | jobs:
14 | test-2022:
15 | runs-on: 'windows-2022'
16 | strategy:
17 | fail-fast: false
18 | matrix:
19 | instance:
20 | - default-windows-2022-latest-py3
21 | steps:
22 | - name: 'Check out code'
23 | uses: 'actions/checkout@v2'
24 | - name: 'Install Chef'
25 | uses: 'actionshub/chef-install@1.1.0'
26 | with:
27 | project: 'chef'
28 | version: '16.10.8'
29 | - name: 'Add Chef bindir to PATH'
30 | uses: 'myci-actions/export-env-var-powershell@1'
31 | with:
32 | name: 'PATH'
33 | value: "C:\\opscode\\chef\\bin;\
34 | C:\\opscode\\chef\\embedded\\bin;$env:PATH"
35 | - name: 'Set up Bundler cache'
36 | uses: 'actions/cache@v1'
37 | with:
38 | path: 'vendor/bundle'
39 | key: "${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}"
40 | restore-keys: "${{ runner.os }}-gems-"
41 | - name: 'Set up test user'
42 | run: |
43 | $password = ConvertTo-SecureString $env:machine_pass -AsPlainText -Force
44 | New-LocalUser $env:machine_user -Password $password
45 | Add-LocalGroupMember -Group "Administrators" -Member $env:machine_user
46 | - name: 'Set up WinRM'
47 | run: |
48 | Set-WSManQuickConfig -Force
49 | - name: 'Run Bundler'
50 | run: |
51 | ruby --version
52 | bundle config path vendor/bundle
53 | bundle install --jobs 4 --retry 3
54 | - name: 'Run Test Kitchen'
55 | run: 'bundle exec kitchen verify ${{ matrix.instance }}'
56 | test-2019:
57 | runs-on: 'windows-2019'
58 | strategy:
59 | fail-fast: false
60 | matrix:
61 | instance:
62 | - default-windows-2019-latest-py3
63 | steps:
64 | - name: 'Check out code'
65 | uses: 'actions/checkout@v2'
66 | - name: 'Install Chef'
67 | uses: 'actionshub/chef-install@1.1.0'
68 | with:
69 | project: 'chef'
70 | version: '16.10.8'
71 | - name: 'Add Chef bindir to PATH'
72 | uses: 'myci-actions/export-env-var-powershell@1'
73 | with:
74 | name: 'PATH'
75 | value: "C:\\opscode\\chef\\bin;\
76 | C:\\opscode\\chef\\embedded\\bin;$env:PATH"
77 | - name: 'Set up Bundler cache'
78 | uses: 'actions/cache@v1'
79 | with:
80 | path: 'vendor/bundle'
81 | key: "${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}"
82 | restore-keys: "${{ runner.os }}-gems-"
83 | - name: 'Set up test user'
84 | run: |
85 | $password = ConvertTo-SecureString $env:machine_pass -AsPlainText -Force
86 | New-LocalUser $env:machine_user -Password $password
87 | Add-LocalGroupMember -Group "Administrators" -Member $env:machine_user
88 | - name: 'Set up WinRM'
89 | run: |
90 | Set-WSManQuickConfig -Force
91 | - name: 'Run Bundler'
92 | run: |
93 | ruby --version
94 | bundle config path vendor/bundle
95 | bundle install --jobs 4 --retry 3
96 | - name: 'Run Test Kitchen'
97 | run: 'bundle exec kitchen verify ${{ matrix.instance }}'
98 |
--------------------------------------------------------------------------------
/.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/openvpn-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/openvpn-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 | default-debian-10-master-py3: {extends: '.test_instance'}
149 | default-debian-9-master-py3: {extends: '.test_instance'}
150 | default-ubuntu-2204-master-py3: {extends: '.test_instance_failure_permitted'}
151 | default-ubuntu-2004-master-py3: {extends: '.test_instance'}
152 | default-ubuntu-1804-master-py3: {extends: '.test_instance'}
153 | # default-centos-stream8-master-py3: {extends: '.test_instance_failure_permitted'}
154 | default-centos-7-master-py3: {extends: '.test_instance'}
155 | # default-fedora-36-master-py3: {extends: '.test_instance_failure_permitted'}
156 | # default-fedora-35-master-py3: {extends: '.test_instance'}
157 | default-opensuse-leap-153-master-py3: {extends: '.test_instance'}
158 | default-opensuse-tmbl-latest-master-py3: {extends: '.test_instance_failure_permitted'}
159 | default-amazonlinux-2-master-py3: {extends: '.test_instance'}
160 | # default-oraclelinux-8-master-py3: {extends: '.test_instance'}
161 | default-oraclelinux-7-master-py3: {extends: '.test_instance'}
162 | # default-arch-base-latest-master-py3: {extends: '.test_instance'}
163 | # default-gentoo-stage3-latest-master-py3: {extends: '.test_instance'}
164 | # default-gentoo-stage3-systemd-master-py3: {extends: '.test_instance'}
165 | # default-almalinux-8-master-py3: {extends: '.test_instance'}
166 | # default-rockylinux-8-master-py3: {extends: '.test_instance'}
167 | # default-debian-11-3004-1-py3: {extends: '.test_instance'}
168 | # default-debian-10-3004-1-py3: {extends: '.test_instance'}
169 | # default-debian-9-3004-1-py3: {extends: '.test_instance'}
170 | # default-ubuntu-2204-3004-1-py3: {extends: '.test_instance_failure_permitted'}
171 | # default-ubuntu-2004-3004-1-py3: {extends: '.test_instance'}
172 | # default-ubuntu-1804-3004-1-py3: {extends: '.test_instance'}
173 | # default-centos-stream8-3004-1-py3: {extends: '.test_instance_failure_permitted'}
174 | # default-centos-7-3004-1-py3: {extends: '.test_instance'}
175 | # default-fedora-36-3004-1-py3: {extends: '.test_instance_failure_permitted'}
176 | # default-fedora-35-3004-1-py3: {extends: '.test_instance'}
177 | # default-amazonlinux-2-3004-1-py3: {extends: '.test_instance'}
178 | # default-oraclelinux-8-3004-1-py3: {extends: '.test_instance'}
179 | # default-oraclelinux-7-3004-1-py3: {extends: '.test_instance'}
180 | # default-arch-base-latest-3004-1-py3: {extends: '.test_instance'}
181 | # default-gentoo-stage3-latest-3004-1-py3: {extends: '.test_instance'}
182 | # default-gentoo-stage3-systemd-3004-1-py3: {extends: '.test_instance'}
183 | # default-almalinux-8-3004-1-py3: {extends: '.test_instance'}
184 | # default-rockylinux-8-3004-1-py3: {extends: '.test_instance'}
185 | # default-opensuse-leap-153-3004-0-py3: {extends: '.test_instance'}
186 | # default-opensuse-tmbl-latest-3004-0-py3: {extends: '.test_instance_failure_permitted'}
187 | # default-debian-10-3003-4-py3: {extends: '.test_instance'}
188 | # default-debian-9-3003-4-py3: {extends: '.test_instance'}
189 | # default-ubuntu-2004-3003-4-py3: {extends: '.test_instance'}
190 | # default-ubuntu-1804-3003-4-py3: {extends: '.test_instance'}
191 | # default-centos-stream8-3003-4-py3: {extends: '.test_instance_failure_permitted'}
192 | # default-centos-7-3003-4-py3: {extends: '.test_instance'}
193 | # default-amazonlinux-2-3003-4-py3: {extends: '.test_instance'}
194 | # default-oraclelinux-8-3003-4-py3: {extends: '.test_instance'}
195 | # default-oraclelinux-7-3003-4-py3: {extends: '.test_instance'}
196 | # default-almalinux-8-3003-4-py3: {extends: '.test_instance'}
197 | # yamllint enable rule:line-length
198 |
199 | ###############################################################################
200 | # `release` stage: `semantic-release`
201 | ###############################################################################
202 | semantic-release:
203 | only: *only_branch_master_parent_repo
204 | stage: *stage_release
205 | image: *image_semanticrelease
206 | variables:
207 | MAINTAINER_TOKEN: '${GH_TOKEN}'
208 | script:
209 | # Update `AUTHORS.md`
210 | - '${HOME}/go/bin/maintainer contributor'
211 | # Run `semantic-release`
212 | - 'semantic-release'
213 |
--------------------------------------------------------------------------------
/.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=default-debian-10-master-py3
101 | - env: INSTANCE=default-debian-9-master-py3
102 | - env: INSTANCE=default-ubuntu-2204-master-py3
103 | - env: INSTANCE=default-ubuntu-2004-master-py3
104 | - env: INSTANCE=default-ubuntu-1804-master-py3
105 | # - env: INSTANCE=default-centos-stream8-master-py3
106 | - env: INSTANCE=default-centos-7-master-py3
107 | # - env: INSTANCE=default-fedora-36-master-py3
108 | # - env: INSTANCE=default-fedora-35-master-py3
109 | - env: INSTANCE=default-opensuse-leap-153-master-py3
110 | - env: INSTANCE=default-opensuse-tmbl-latest-master-py3
111 | - env: INSTANCE=default-amazonlinux-2-master-py3
112 | # - env: INSTANCE=default-oraclelinux-8-master-py3
113 | - env: INSTANCE=default-oraclelinux-7-master-py3
114 | # - env: INSTANCE=default-arch-base-latest-master-py3
115 | # - env: INSTANCE=default-gentoo-stage3-latest-master-py3
116 | # - env: INSTANCE=default-gentoo-stage3-systemd-master-py3
117 | # - env: INSTANCE=default-almalinux-8-master-py3
118 | # - env: INSTANCE=default-rockylinux-8-master-py3
119 | # - env: INSTANCE=default-debian-11-3004-1-py3
120 | # - env: INSTANCE=default-debian-10-3004-1-py3
121 | # - env: INSTANCE=default-debian-9-3004-1-py3
122 | # - env: INSTANCE=default-ubuntu-2204-3004-1-py3
123 | # - env: INSTANCE=default-ubuntu-2004-3004-1-py3
124 | # - env: INSTANCE=default-ubuntu-1804-3004-1-py3
125 | # - env: INSTANCE=default-centos-stream8-3004-1-py3
126 | # - env: INSTANCE=default-centos-7-3004-1-py3
127 | # - env: INSTANCE=default-fedora-36-3004-1-py3
128 | # - env: INSTANCE=default-fedora-35-3004-1-py3
129 | # - env: INSTANCE=default-amazonlinux-2-3004-1-py3
130 | # - env: INSTANCE=default-oraclelinux-8-3004-1-py3
131 | # - env: INSTANCE=default-oraclelinux-7-3004-1-py3
132 | # - env: INSTANCE=default-arch-base-latest-3004-1-py3
133 | # - env: INSTANCE=default-gentoo-stage3-latest-3004-1-py3
134 | # - env: INSTANCE=default-gentoo-stage3-systemd-3004-1-py3
135 | # - env: INSTANCE=default-almalinux-8-3004-1-py3
136 | # - env: INSTANCE=default-rockylinux-8-3004-1-py3
137 | # - env: INSTANCE=default-opensuse-leap-153-3004-0-py3
138 | # - env: INSTANCE=default-opensuse-tmbl-latest-3004-0-py3
139 | # - env: INSTANCE=default-debian-10-3003-4-py3
140 | # - env: INSTANCE=default-debian-9-3003-4-py3
141 | # - env: INSTANCE=default-ubuntu-2004-3003-4-py3
142 | # - env: INSTANCE=default-ubuntu-1804-3003-4-py3
143 | # - env: INSTANCE=default-centos-stream8-3003-4-py3
144 | # - env: INSTANCE=default-centos-7-3003-4-py3
145 | # - env: INSTANCE=default-amazonlinux-2-3003-4-py3
146 | # - env: INSTANCE=default-oraclelinux-8-3003-4-py3
147 | # - env: INSTANCE=default-oraclelinux-7-3003-4-py3
148 | # - env: INSTANCE=default-almalinux-8-3003-4-py3
149 |
150 | ## Define the release stage that runs `semantic-release`
151 | - stage: 'release'
152 | language: 'node_js'
153 | node_js: 'lts/*'
154 | env: 'Release'
155 | name: 'Run semantic-release inc. file updates to AUTHORS, CHANGELOG & FORMULA'
156 | before_install: 'skip'
157 | script:
158 | # Update `AUTHORS.md`
159 | - export MAINTAINER_TOKEN=${GH_TOKEN}
160 | - go get github.com/myii/maintainer
161 | - maintainer contributor
162 |
163 | # Install all dependencies required for `semantic-release`
164 | - npm i -D @semantic-release/changelog@3
165 | @semantic-release/exec@3
166 | @semantic-release/git@7
167 | deploy:
168 | provider: 'script'
169 | # Opt-in to `dpl v2` to complete the Travis build config validation (beta)
170 | # * https://docs.travis-ci.com/user/build-config-validation
171 | # Deprecated `skip_cleanup` can now be avoided, `cleanup: false` is by default
172 | edge: true
173 | # Run `semantic-release`
174 | script: 'npx semantic-release@15.14'
175 |
176 | # Notification options: `always`, `never` or `change`
177 | notifications:
178 | webhooks:
179 | if: 'repo = saltstack-formulas/openvpn-formula'
180 | urls:
181 | - https://saltstack-formulas.zulipchat.com/api/v1/external/travis?api_key=HsIq3o5QmLxdnVCKF9is0FUIpkpAY79P&stream=CI&topic=saltstack-formulas%2Fopenvpn-formula&ignore_pull_requests=true
182 | on_success: always # default: always
183 | on_failure: always # default: always
184 | on_start: always # default: never
185 | on_cancel: always # default: always
186 | on_error: always # default: always
187 |
--------------------------------------------------------------------------------
/.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 | ignore: |
16 | .bundle/
17 | .cache/
18 | .git/
19 | node_modules/
20 | test/**/states/**/*.sls
21 | .kitchen/
22 | kitchen.vagrant.yml
23 | test/salt/pillar/default.sls
24 |
25 | yaml-files:
26 | # Default settings
27 | - '*.yaml'
28 | - '*.yml'
29 | - .salt-lint
30 | - .yamllint
31 | # SaltStack Formulas additional settings
32 | - '*.example'
33 | - test/**/*.sls
34 |
35 | rules:
36 | empty-values:
37 | forbid-in-block-mappings: true
38 | forbid-in-flow-mappings: true
39 | line-length:
40 | # Increase from default of `80`
41 | # Based on https://github.com/PyCQA/flake8-bugbear#opinionated-warnings (`B950`)
42 | max: 88
43 | octal-values:
44 | forbid-implicit-octal: true
45 | forbid-explicit-octal: true
46 |
--------------------------------------------------------------------------------
/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)|177
8 |
|[@alxwr](https://github.com/alxwr)|96
9 |
|[@dafyddj](https://github.com/dafyddj)|61
10 |
|[@TimJones](https://github.com/TimJones)|21
11 |
|[@aboe76](https://github.com/aboe76)|19
12 |
|[@puneetk](https://github.com/puneetk)|12
13 |
|[@daschatten](https://github.com/daschatten)|11
14 |
|[@marconett](https://github.com/marconett)|9
15 |
|[@sc250024](https://github.com/sc250024)|6
16 |
|[@baby-gnu](https://github.com/baby-gnu)|6
17 |
|[@wolodjawentland](https://github.com/wolodjawentland)|5
18 |
|[@diegofd](https://github.com/diegofd)|4
19 |
|[@javierbertoli](https://github.com/javierbertoli)|4
20 |
|[@landergate](https://github.com/landergate)|4
21 |
|[@aviau](https://github.com/aviau)|3
22 |
|[@nmadhok](https://github.com/nmadhok)|3
23 |
|[@viper233](https://github.com/viper233)|3
24 |
|[@timwhite](https://github.com/timwhite)|3
25 |
|[@daks](https://github.com/daks)|3
26 |
|[@alexhayes](https://github.com/alexhayes)|2
27 |
|[@iggy](https://github.com/iggy)|2
28 |
|[@dimitry-unified-streaming](https://github.com/dimitry-unified-streaming)|2
29 |
|[@t0fik](https://github.com/t0fik)|2
30 |
|[@anderbubble](https://github.com/anderbubble)|2
31 |
|[@kevinschmidt](https://github.com/kevinschmidt)|2
32 |
|[@Wenzel](https://github.com/Wenzel)|2
33 |
|[@stasjok](https://github.com/stasjok)|2
34 |
|[@genuss](https://github.com/genuss)|2
35 |
|[@cmclaughlin](https://github.com/cmclaughlin)|2
36 |
|[@noelmcloughlin](https://github.com/noelmcloughlin)|2
37 |
|[@aldovillagra](https://github.com/aldovillagra)|1
38 |
|[@blbradley](https://github.com/blbradley)|1
39 |
|[@vielmetti](https://github.com/vielmetti)|1
40 |
|[@gboddin](https://github.com/gboddin)|1
41 |
|[@icflournoy](https://github.com/icflournoy)|1
42 |
|[@mthibaut](https://github.com/mthibaut)|1
43 |
|[@marek-knappe](https://github.com/marek-knappe)|1
44 |
|[@oselivanov](https://github.com/oselivanov)|1
45 |
|[@kevit](https://github.com/kevit)|1
46 |
|[@tobio](https://github.com/tobio)|1
47 |
48 | ---
49 |
50 | Auto-generated by a [forked version](https://github.com/myii/maintainer) of [gaocegege/maintainer](https://github.com/gaocegege/maintainer) on 2022-08-16.
51 |
--------------------------------------------------------------------------------
/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 | * @dafyddj
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 | /*/libmapstack.jinja @saltstack-formulas/ssf
20 | /*/libmatchers.jinja @saltstack-formulas/ssf
21 | /*/libsaltcli.jinja @saltstack-formulas/ssf
22 | /*/libtofs.jinja @saltstack-formulas/ssf
23 | /*/map.jinja @saltstack-formulas/ssf
24 | /test/integration/**/_mapdata.rb @saltstack-formulas/ssf
25 | /test/integration/**/libraries/system.rb @saltstack-formulas/ssf
26 | /test/integration/**/inspec.yml @saltstack-formulas/ssf
27 | /test/integration/**/README.md @saltstack-formulas/ssf
28 | /test/salt/pillar/top.sls @saltstack-formulas/ssf
29 | /.gitignore @saltstack-formulas/ssf
30 | /.cirrus.yml @saltstack-formulas/ssf
31 | /.gitlab-ci.yml @saltstack-formulas/ssf
32 | /.pre-commit-config.yaml @saltstack-formulas/ssf
33 | /.rstcheck.cfg @saltstack-formulas/ssf
34 | /.rubocop.yml @saltstack-formulas/ssf
35 | /.salt-lint @saltstack-formulas/ssf
36 | /.travis.yml @saltstack-formulas/ssf
37 | /.yamllint @saltstack-formulas/ssf
38 | /AUTHORS.md @saltstack-formulas/ssf
39 | /CHANGELOG.md @saltstack-formulas/ssf
40 | /CODEOWNERS @saltstack-formulas/ssf
41 | /commitlint.config.js @saltstack-formulas/ssf
42 | /FORMULA @saltstack-formulas/ssf
43 | /Gemfile @saltstack-formulas/ssf
44 | /Gemfile.lock @saltstack-formulas/ssf
45 | /kitchen.yml @saltstack-formulas/ssf
46 | /kitchen.vagrant.yml @saltstack-formulas/ssf
47 | /kitchen.windows.yml @saltstack-formulas/ssf
48 | /pre-commit_semantic-release.sh @saltstack-formulas/ssf
49 | /release-rules.js @saltstack-formulas/ssf
50 | /release.config.js @saltstack-formulas/ssf
51 |
52 | # SECTION: Owner(s) for specific files
53 | # FILE PATTERN OWNER(S)
54 |
--------------------------------------------------------------------------------
/FORMULA:
--------------------------------------------------------------------------------
1 | name: template
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: 1.0.5
5 | release: 1
6 | minimum_version: 2018.3
7 | summary: OpenVPN formula
8 | description: Formula to use manage OpenVPN
9 | top_level_dir: openvpn
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 | gem 'rspec-retry'
21 |
22 | group :vagrant do
23 | gem 'kitchen-vagrant'
24 | end
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2015-2017 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 | - 177
19 | * - :raw-html-m2r:`
`
20 | - `@alxwr `_
21 | - 96
22 | * - :raw-html-m2r:`
`
23 | - `@dafyddj `_
24 | - 61
25 | * - :raw-html-m2r:`
`
26 | - `@TimJones `_
27 | - 21
28 | * - :raw-html-m2r:`
`
29 | - `@aboe76 `_
30 | - 19
31 | * - :raw-html-m2r:`
`
32 | - `@puneetk `_
33 | - 12
34 | * - :raw-html-m2r:`
`
35 | - `@daschatten `_
36 | - 11
37 | * - :raw-html-m2r:`
`
38 | - `@marconett `_
39 | - 9
40 | * - :raw-html-m2r:`
`
41 | - `@sc250024 `_
42 | - 6
43 | * - :raw-html-m2r:`
`
44 | - `@baby-gnu `_
45 | - 6
46 | * - :raw-html-m2r:`
`
47 | - `@wolodjawentland `_
48 | - 5
49 | * - :raw-html-m2r:`
`
50 | - `@diegofd `_
51 | - 4
52 | * - :raw-html-m2r:`
`
53 | - `@javierbertoli `_
54 | - 4
55 | * - :raw-html-m2r:`
`
56 | - `@landergate `_
57 | - 4
58 | * - :raw-html-m2r:`
`
59 | - `@aviau `_
60 | - 3
61 | * - :raw-html-m2r:`
`
62 | - `@nmadhok `_
63 | - 3
64 | * - :raw-html-m2r:`
`
65 | - `@viper233 `_
66 | - 3
67 | * - :raw-html-m2r:`
`
68 | - `@timwhite `_
69 | - 3
70 | * - :raw-html-m2r:`
`
71 | - `@daks `_
72 | - 3
73 | * - :raw-html-m2r:`
`
74 | - `@alexhayes `_
75 | - 2
76 | * - :raw-html-m2r:`
`
77 | - `@iggy `_
78 | - 2
79 | * - :raw-html-m2r:`
`
80 | - `@dimitry-unified-streaming `_
81 | - 2
82 | * - :raw-html-m2r:`
`
83 | - `@t0fik `_
84 | - 2
85 | * - :raw-html-m2r:`
`
86 | - `@anderbubble `_
87 | - 2
88 | * - :raw-html-m2r:`
`
89 | - `@kevinschmidt `_
90 | - 2
91 | * - :raw-html-m2r:`
`
92 | - `@Wenzel `_
93 | - 2
94 | * - :raw-html-m2r:`
`
95 | - `@stasjok `_
96 | - 2
97 | * - :raw-html-m2r:`
`
98 | - `@genuss `_
99 | - 2
100 | * - :raw-html-m2r:`
`
101 | - `@cmclaughlin `_
102 | - 2
103 | * - :raw-html-m2r:`
`
104 | - `@noelmcloughlin `_
105 | - 2
106 | * - :raw-html-m2r:`
`
107 | - `@aldovillagra `_
108 | - 1
109 | * - :raw-html-m2r:`
`
110 | - `@blbradley `_
111 | - 1
112 | * - :raw-html-m2r:`
`
113 | - `@vielmetti `_
114 | - 1
115 | * - :raw-html-m2r:`
`
116 | - `@gboddin `_
117 | - 1
118 | * - :raw-html-m2r:`
`
119 | - `@icflournoy `_
120 | - 1
121 | * - :raw-html-m2r:`
`
122 | - `@mthibaut `_
123 | - 1
124 | * - :raw-html-m2r:`
`
125 | - `@marek-knappe `_
126 | - 1
127 | * - :raw-html-m2r:`
`
128 | - `@oselivanov `_
129 | - 1
130 | * - :raw-html-m2r:`
`
131 | - `@kevit `_
132 | - 1
133 | * - :raw-html-m2r:`
`
134 | - `@tobio `_
135 | - 1
136 |
137 |
138 | ----
139 |
140 | Auto-generated by a `forked version `_ of `gaocegege/maintainer `_ on 2022-08-16.
141 |
--------------------------------------------------------------------------------
/docs/README.rst:
--------------------------------------------------------------------------------
1 | openvpn-formula
2 | ===============
3 |
4 |
5 | |img_travis| |img_sr|
6 |
7 | .. |img_travis| image:: https://travis-ci.com/saltstack-formulas/openvpn-formula.svg?branch=master
8 | :alt: Travis CI Build Status
9 | :scale: 100%
10 | :target: https://travis-ci.com/saltstack-formulas/openvpn-formula
11 | .. |img_sr| image:: https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg
12 | :alt: Semantic Release
13 | :scale: 100%
14 | :target: https://github.com/semantic-release/semantic-release
15 |
16 | Formula to install and configure openvpn server and client.
17 |
18 | .. contents:: **Table of Contents**
19 |
20 | General notes
21 | -------------
22 |
23 | See the full `SaltStack Formulas installation and usage instructions
24 | `_.
25 |
26 | If you are interested in writing or contributing to formulas, please pay attention to the `Writing Formula Section
27 | `_.
28 |
29 | If you want to use this formula, please pay attention to the ``FORMULA`` file and/or ``git tag``,
30 | which contains the currently released version. This formula is versioned according to `Semantic Versioning `_.
31 |
32 | See `Formula Versioning Section `_ for more details.
33 |
34 | If you need (non-default) configuration, please refer to:
35 |
36 | - `how to configure the formula with map.jinja `_
37 | - the ``pillar.example`` file
38 |
39 |
40 | Contributing to this repo
41 | -------------------------
42 |
43 | **Commit message formatting is significant!!**
44 |
45 | Please see `How to contribute `_ for more details.
46 |
47 |
48 | Available states
49 | ----------------
50 |
51 | .. contents::
52 | :local:
53 |
54 | ``openvpn``
55 | ^^^^^^^^^^^
56 |
57 | Installs OpenVPN.
58 |
59 | ``openvpn.config``
60 | ^^^^^^^^^^^^^^^^^^
61 |
62 | Configures OpenVPN client and server. Multiple clients and servers are possible.
63 |
64 | ``openvpn.gui``
65 | ^^^^^^^^^^^^^^^
66 |
67 | Configures OpenVPN GUI (Windows only). Sets global registry settings as described `here `_.
68 |
69 | ``openvpn.adapters``
70 | ^^^^^^^^^^^^^^^^^^^^
71 |
72 | Manages TAP-Windows device adapters (Windows only). Ensures that any devices specified with ``dev_node`` in pillar exist.
73 |
74 | ``openvpn.ifconfig_pool_persist``
75 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
76 |
77 | Installs and configures an ifconfig_pool_persist file. Used to assign host IPs.
78 |
79 | ``openvpn.network_manager_networks``
80 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
81 |
82 | Don't setup a OpenVPN client service, but add ready-to-use NetworkManager configurations.
83 |
84 | Examples
85 | --------
86 |
87 | See *openvpn/pillar.example*.
88 |
89 | Notes
90 | -----
91 |
92 | This formula does can optionally deploy certificates and keys, but does not generate them. This must be done manually or with another formula.
93 |
94 | Testing
95 | -------
96 |
97 | Linux testing is done with ``kitchen-salt``.
98 |
99 | Requirements
100 | ^^^^^^^^^^^^
101 |
102 | * Ruby
103 | * Docker
104 |
105 | .. code-block:: bash
106 |
107 | $ gem install bundler
108 | $ bundle install
109 | $ bin/kitchen test [platform]
110 |
111 | Where ``[platform]`` is the platform name defined in ``kitchen.yml``,
112 | e.g. ``debian-9-2019-2-py3``.
113 |
114 | ``bin/kitchen converge``
115 | ^^^^^^^^^^^^^^^^^^^^^^^^
116 |
117 | Creates the docker instance and runs the ``openvpn`` main state, ready for testing.
118 |
119 | ``bin/kitchen verify``
120 | ^^^^^^^^^^^^^^^^^^^^^^
121 |
122 | Runs the ``inspec`` tests on the actual instance.
123 |
124 | ``bin/kitchen destroy``
125 | ^^^^^^^^^^^^^^^^^^^^^^^
126 |
127 | Removes the docker instance.
128 |
129 | ``bin/kitchen test``
130 | ^^^^^^^^^^^^^^^^^^^^
131 |
132 | Runs all of the stages above in one go: i.e. ``destroy`` + ``converge`` + ``verify`` + ``destroy``.
133 |
134 | ``bin/kitchen login``
135 | ^^^^^^^^^^^^^^^^^^^^^
136 |
137 | Gives you SSH access to the instance for manual testing.
138 |
139 | Testing with Vagrant
140 | --------------------
141 |
142 | Windows/FreeBSD/OpenBSD testing is done with ``kitchen-salt``.
143 |
144 | Requirements
145 | ^^^^^^^^^^^^
146 |
147 | * Ruby
148 | * Virtualbox
149 | * Vagrant
150 |
151 | Setup
152 | ^^^^^
153 |
154 | .. code-block:: bash
155 |
156 | $ gem install bundler
157 | $ bundle install --with=vagrant
158 | $ bin/kitchen test [platform]
159 |
160 | Where ``[platform]`` is the platform name defined in ``kitchen.vagrant.yml``,
161 | e.g. ``windows-81-latest-py3``.
162 |
163 | Note
164 | ^^^^
165 |
166 | When testing using Vagrant you must set the environment variable ``KITCHEN_LOCAL_YAML`` to ``kitchen.vagrant.yml``. For example:
167 |
168 | .. code-block:: bash
169 |
170 | $ KITCHEN_LOCAL_YAML=kitchen.vagrant.yml bin/kitchen test # Alternatively,
171 | $ export KITCHEN_LOCAL_YAML=kitchen.vagrant.yml
172 | $ bin/kitchen test
173 |
174 | Then run the following commands as needed.
175 |
176 | ``bin/kitchen converge``
177 | ^^^^^^^^^^^^^^^^^^^^^^^^
178 |
179 | Creates the Vagrant instance and runs the ``openvpn`` main state, ready for testing.
180 |
181 | ``bin/kitchen verify``
182 | ^^^^^^^^^^^^^^^^^^^^^^
183 |
184 | Runs the ``inspec`` tests on the actual instance.
185 |
186 | ``bin/kitchen destroy``
187 | ^^^^^^^^^^^^^^^^^^^^^^^
188 |
189 | Removes the Vagrant instance.
190 |
191 | ``bin/kitchen test``
192 | ^^^^^^^^^^^^^^^^^^^^
193 |
194 | Runs all of the stages above in one go: i.e. ``destroy`` + ``converge`` + ``verify`` + ``destroy``.
195 |
196 | ``bin/kitchen login``
197 | ^^^^^^^^^^^^^^^^^^^^^
198 |
199 | Gives you RDP/SSH access to the instance for manual testing.
200 |
--------------------------------------------------------------------------------
/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: windows-10-latest-py3
22 | driver:
23 | box: techneg/win10x64-pro-salt
24 | cache_directory: "/omnibus/cache"
25 | customize: {}
26 | ssh: {}
27 | provisioner:
28 | # yamllint disable rule:line-length
29 | init_environment: |
30 | # Workaround to allow `kitchen converge` to be used multiple times
31 | # without having to `kitchen destroy` first: remove state files cached by
32 | # Salt during the previous `converge` (if present)
33 | rm -recurse `
34 | C:\Users\vagrant\AppData\Local\Temp\kitchen\var\cache\salt\minion\files\base `
35 | -ErrorAction SilentlyContinue
36 | salt-call --local state.single file.managed `
37 | C:\Users\vagrant\AppData\Local\Temp\kitchen\srv\salt\win\repo-ng\openvpn.sls `
38 | source=https://github.com/saltstack/salt-winrepo-ng/raw/master/openvpn.sls `
39 | skip_verify=True makedirs=True
40 | exit 0
41 | # yamllint enable rule:line-length
42 | - name: windows-81-latest-py3
43 | driver:
44 | box: techneg/win81x64-pro-salt
45 | cache_directory: "/omnibus/cache"
46 | customize: {}
47 | ssh: {}
48 | provisioner:
49 | # yamllint disable rule:line-length
50 | init_environment: |
51 | # Workaround to allow `kitchen converge` to be used multiple times
52 | # without having to `kitchen destroy` first: remove state files cached by
53 | # Salt during the previous `converge` (if present)
54 | rm -recurse `
55 | C:\Users\vagrant\AppData\Local\Temp\kitchen\var\cache\salt\minion\files\base `
56 | -ErrorAction SilentlyContinue
57 | salt-call --local state.single file.managed `
58 | C:\Users\vagrant\AppData\Local\Temp\kitchen\srv\salt\win\repo-ng\openvpn.sls `
59 | source=https://github.com/saltstack/salt-winrepo-ng/raw/master/openvpn.sls `
60 | skip_verify=True makedirs=True
61 | exit 0
62 | # yamllint enable rule:line-length
63 |
--------------------------------------------------------------------------------
/kitchen.windows.yml:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # vim: ft=yaml
3 | ---
4 | driver:
5 | name: proxy
6 | host: localhost
7 | reset_command: "exit 0"
8 | port: 5985
9 | username: kitchen
10 | password: Pass@word1
11 |
12 | provisioner:
13 | salt_install: bootstrap
14 | salt_bootstrap_options: -pythonVersion 3
15 | # yamllint disable rule:line-length
16 | init_environment: |
17 | salt-call --local state.single file.managed `
18 | C:\Users\kitchen\AppData\Local\Temp\kitchen\srv\salt\win\repo-ng\openvpn.sls `
19 | source=https://github.com/saltstack/salt-winrepo-ng/raw/master/openvpn.sls `
20 | skip_verify=True makedirs=True
21 | # yamllint enable rule:line-length
22 |
23 | platforms:
24 | - name: windows-2022-latest-py3
25 | - name: windows-2019-latest-py3
26 |
--------------------------------------------------------------------------------
/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: openvpn
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 | # This formula has InSpec controls which involve retrying tests, to allow time,
269 | # for example, for services to start up fully. These retries will not pick
270 | # up these changes if the backend cache is in use, so it's set to `false` here.
271 | backend_cache: false
272 |
273 | suites:
274 | - name: default
275 | provisioner:
276 | state_top:
277 | base:
278 | '*':
279 | - openvpn._mapdata
280 | - openvpn.config
281 | pillars:
282 | top.sls:
283 | base:
284 | '*':
285 | - openvpn
286 | pillars_from_files:
287 | openvpn.sls: test/salt/pillar/default.sls
288 | verifier:
289 | inspec_tests:
290 | - path: test/integration/default
291 |
--------------------------------------------------------------------------------
/openvpn/_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 |
--------------------------------------------------------------------------------
/openvpn/_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 mapdata with context %}
7 |
8 | {%- set _mapdata = {
9 | "values": mapdata,
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 |
--------------------------------------------------------------------------------
/openvpn/adapters.sls:
--------------------------------------------------------------------------------
1 | {% if salt['grains.get']('os_family') == 'Windows' %}
2 | include:
3 | - openvpn
4 |
5 | {% for type, names in salt['pillar.get']('openvpn', {}).items() %}
6 | {% if type in ['client', 'server', 'peer'] %}
7 | {% for name, config in names.items() %}
8 | {% if config.dev_node is defined %}
9 | openvpn_tap_adapter_{{ config.dev_node }}:
10 | cmd.script:
11 | - source: salt://openvpn/files/tap-adapter.ps1
12 | - args: -New {{ config.dev_node }}
13 | - shell: powershell
14 | - stateful: True
15 | - require:
16 | - pkg: openvpn_pkgs
17 | {% endif %}
18 | {% endfor %}
19 | {% endif %}
20 | {% endfor %}
21 |
22 | {% endif %}
23 |
--------------------------------------------------------------------------------
/openvpn/config.sls:
--------------------------------------------------------------------------------
1 | {%- from "openvpn/map.jinja" import mapdata as map with context %}
2 | {% from "openvpn/macros.jinja" import multipart_param with context %}
3 |
4 | include:
5 | - openvpn
6 | - openvpn.general_config
7 |
8 | {% for type, names in salt['pillar.get']('openvpn', {}).items() %}
9 | {% if type in ['client', 'server', 'peer'] %}
10 | {% for name, config in names.items() %}
11 |
12 | {% macro _permissions(mode=644, user=None, group=None) %}
13 | {%- if not grains['os_family'] == 'Windows' -%}
14 | - mode: {{ mode }}
15 | - user: {% if not user is none %}{{ user }}{% elif config.user is defined %}{{ config.user }}{% else %}{{ map.user }}{% endif %}
16 | - group: {% if not group is none %}{{ group }}{% elif config.group is defined %}{{ config.group }}{% else %}{{ map.group }}{% endif %}
17 | {%- endif -%}
18 | {% endmacro %}
19 |
20 | {% set service_id = "openvpn_{0}_service".format(name) if map.multi_services else "openvpn_service" %}
21 |
22 | {%- if config.conf_dir is defined %}
23 | {#- Use the explicit config from Pillar, if it is present. #}
24 | {%- set config_dir = config.conf_dir %}
25 | {%- else %}
26 | {#- Some distributions use /etc/openvpn/{client,server} as their working directory #}
27 | {%- set config_dir = map.get(type, {}).get("conf_dir", map.conf_dir) %}
28 | {%- endif %}
29 |
30 | {%- set config_file = "{0}/openvpn_{1}.conf".format(
31 | config_dir,
32 | name,
33 | ) if map.multi_services and grains['os_family'] == 'FreeBSD' else "{0}/{1}.{2}".format(
34 | config_dir,
35 | name,
36 | map.conf_ext,
37 | ) %}
38 |
39 | # Deploy {{ type }} {{ name }} config files
40 | openvpn_config_{{ type }}_{{ name }}:
41 | file.managed:
42 | - name: {{ config_file }}
43 | {{ _permissions(640, 'root') }}
44 | - source:
45 | - salt://openvpn/files/{{ type }}.jinja
46 | - salt://openvpn/files/common_opts.jinja # make available to salt-ssh
47 | # see https://github.com/saltstack/salt/issues/21370#issuecomment-226868952
48 | - template: jinja
49 | - context:
50 | name: {{ name }}
51 | type: {{ type }}
52 | user: {{ map.user }}
53 | group: {{ map.group }}
54 | config: {{ config | json }}
55 | - watch_in:
56 | - service: {{ service_id }}
57 |
58 | {% if config.ca is defined and config.ca_content is defined %}
59 | # Deploy {{ type }} {{ name }} CA file
60 | openvpn_config_{{ type }}_{{ name }}_ca_file:
61 | file.managed:
62 | - name: {{ config.ca }}
63 | {{ _permissions(640, 'root') }}
64 | - contents_pillar: openvpn:{{ type }}:{{ name }}:ca_content
65 | - makedirs: True
66 | - watch_in:
67 | - service: {{ service_id }}
68 | {% endif %}
69 |
70 | {% if config.cert is defined and config.cert_content is defined %}
71 | # Deploy {{ type }} {{ name }} certificate file
72 | openvpn_config_{{ type }}_{{ name }}_cert_file:
73 | file.managed:
74 | - name: {{ config.cert }}
75 | {{ _permissions(640, 'root') }}
76 | - contents_pillar: openvpn:{{ type }}:{{ name }}:cert_content
77 | - makedirs: True
78 | - watch_in:
79 | - service: {{ service_id }}
80 | {% endif %}
81 |
82 | {% if config.key is defined and config.key_content is defined %}
83 | # Deploy {{ type }} {{ name }} private key file
84 | openvpn_config_{{ type }}_{{ name }}_key_file:
85 | file.managed:
86 | - name: {{ config.key }}
87 | {{ _permissions(600, 'root') }}
88 | - contents_pillar: openvpn:{{ type }}:{{ name }}:key_content
89 | - makedirs: True
90 | - watch_in:
91 | - service: {{ service_id }}
92 | {% endif %}
93 |
94 | {% if config.crl_verify is defined and config.crl_verify_content is defined %}
95 | # Deploy {{ type }} {{ name }} crl file
96 | openvpn_config_{{ type }}_{{ name }}_crl_verify_file:
97 | file.managed:
98 | - name: {{ config.crl_verify }}
99 | {{ _permissions(640, 'root') }}
100 | - contents_pillar: openvpn:{{ type }}:{{ name }}:crl_verify_content
101 | - makedirs: True
102 | - watch_in:
103 | - service: {{ service_id }}
104 | {% endif %}
105 |
106 | {% if config.askpass is defined and config.askpass_content is defined %}
107 | # Deploy {{ type }} {{ name }} private key password file
108 | openvpn_config_{{ type }}_{{ name }}_passwd_file:
109 | file.managed:
110 | - name: {{ config.askpass }}
111 | {{ _permissions(600, 'root') }}
112 | - contents_pillar: openvpn:{{ type }}:{{ name }}:askpass_content
113 | - makedirs: True
114 | - watch_in:
115 | - service: {{ service_id }}
116 | {% endif %}
117 |
118 | {% if config.ta_content is defined and config.tls_crypt is defined %}
119 | # Deploy {{ type }} {{ name }} TLS key file
120 | openvpn_config_{{ type }}_{{ name }}_tls_crypt_file:
121 | file.managed:
122 | - name: {{ config.tls_crypt }}
123 | {{ _permissions(600, 'root') }}
124 | - contents_pillar: openvpn:{{ type }}:{{ name }}:ta_content
125 | - makedirs: True
126 | - watch_in:
127 | - service: {{ service_id }}
128 | {% elif config.ta_content is defined and config.tls_auth is defined %}
129 | # Deploy {{ type }} {{ name }} TLS key file
130 | openvpn_config_{{ type }}_{{ name }}_tls_auth_file:
131 | file.managed:
132 | - name: {{ multipart_param(config.tls_auth, 0) }}
133 | {{ _permissions(600, 'root') }}
134 | - contents_pillar: openvpn:{{ type }}:{{ name }}:ta_content
135 | - makedirs: True
136 | - watch_in:
137 | - service: {{ service_id }}
138 | {% endif %}
139 |
140 | {% if config.secret is defined and config.secret_content is defined %}
141 | # Deploy {{ type }} {{ name }} shared secret key file
142 | openvpn_config_{{ type }}_{{ name }}_secret_file:
143 | file.managed:
144 | - name: {{ multipart_param(config.secret, 0) }}
145 | {{ _permissions(600, 'root') }}
146 | - contents_pillar: openvpn:{{ type }}:{{ name }}:secret_content
147 | - makedirs: True
148 | - watch_in:
149 | - service: {{ service_id }}
150 | {% endif %}
151 |
152 | {% if config.auth_user_pass is defined and config.auth_user_pass_content is defined %}
153 | # Deploy {{ type }} {{ name }} auth_user_pass file
154 | openvpn_config_{{ type }}_{{ name }}_auth_user_pass_file:
155 | file.managed:
156 | - name: {{ config.auth_user_pass }}
157 | {{ _permissions(600, 'root') }}
158 | - contents_pillar: openvpn:{{ type }}:{{ name }}:auth_user_pass_content
159 | - makedirs: True
160 | - watch_in:
161 | - service: {{ service_id }}
162 | {% endif %}
163 |
164 | {% if config.status is defined %}
165 | # Ensure status file exists and is writeable
166 | openvpn_{{ type }}_{{ name }}_status_file:
167 | file.managed:
168 | - name: {{ config.status }}
169 | - makedirs: True
170 | {{ _permissions(600, 'root', 0) }} # different group names on FreeBSD and Debian/Ubuntu
171 | - watch_in:
172 | {%- if map.multi_services %}
173 | - service: openvpn_{{ name }}_service
174 | {%- else %}
175 | - service: openvpn_service
176 | {%- endif %}
177 | {% endif %}
178 |
179 | {% if config.log is defined %}
180 | # Ensure log file exists and is writeable
181 | openvpn_{{ type }}_{{ name }}_log_file:
182 | file.managed:
183 | - name: {{ config.log }}
184 | - makedirs: True
185 | - replace: False
186 | {{ _permissions(640, map.log_user) }}
187 | - require_in:
188 | {%- if map.multi_services %}
189 | - service: openvpn_{{ name }}_service
190 | {%- else %}
191 | - service: openvpn_service
192 | {%- endif %}
193 | {% endif %}
194 |
195 | {% if config.log_append is defined %}
196 | # Ensure log file exists and is writeable
197 | openvpn_{{ type }}_{{ name }}_log_file_append:
198 | file.managed:
199 | - name: {{ config.log_append }}
200 | - makedirs: True
201 | - replace: False
202 | {{ _permissions(640, map.log_user) }}
203 | - require_in:
204 | {%- if map.multi_services %}
205 | - service: openvpn_{{ name }}_service
206 | {%- else %}
207 | - service: openvpn_service
208 | {%- endif %}
209 | {% endif %}
210 |
211 | {% if config.client_config_dir is defined %}
212 | # Ensure client config dir exists
213 | openvpn_config_{{ type }}_{{ name }}_client_config_dir:
214 | file.directory:
215 | - name: {{ config_dir }}/{{ config.client_config_dir }}
216 | {{ _permissions(750, 'root') }}
217 | - makedirs: True
218 | - watch_in:
219 | {%- if map.multi_services %}
220 | - service: openvpn_{{ name }}_service
221 | {%- else %}
222 | - service: openvpn_service
223 | {%- endif %}
224 |
225 | {% for client, client_config in salt['pillar.get']('openvpn:'+type+':'+name+':client_config', {}).items() %}
226 | # Client config for {{ client }}
227 | openvpn_config_{{ type }}_{{ name }}_{{ client }}_client_config:
228 | file.managed:
229 | - name: {{ config_dir }}/{{ config.client_config_dir }}/{{ client }}
230 | {{ _permissions(640, 'root') }}
231 | - contents_pillar: openvpn:{{ type }}:{{ name }}:client_config:{{ client }}
232 | - makedirs: True
233 | - watch_in:
234 | - service: {{ service_id }}
235 | {% endfor %}
236 | {% endif %}
237 |
238 | {% endfor %}
239 | {% endif %}
240 | {% endfor %}
241 |
--------------------------------------------------------------------------------
/openvpn/dhparams.sls:
--------------------------------------------------------------------------------
1 | {%- from "openvpn/map.jinja" import mapdata as map with context %}
2 |
3 | # Generate diffie hellman files
4 | {% if salt['pillar.get']('openvpn:server', False) %}
5 | {#- Some distributions use /etc/openvpn/{client,server} as their working directory #}
6 | {%- set config_dir = map.get("server", {}).get("conf_dir", map.conf_dir) %}
7 | {%- for dh in map.dh_files %}
8 | {%- set dh_file = config_dir ~ "/dh" ~ dh ~ ".pem" %}
9 | openvpn_create_dh_{{ dh }}:
10 | cmd.run:
11 | - name: '"{{ map.bin_dir | default('', true) }}openssl" dhparam {% if map.dsaparam %}-dsaparam {% endif %}-out "{{ dh_file }}" {{ dh }}'
12 | - creates: {{ dh_file }}
13 | - require:
14 | - pkg: openvpn_pkgs
15 | {%- endfor %}
16 | {% endif %}
17 |
--------------------------------------------------------------------------------
/openvpn/files/client.jinja:
--------------------------------------------------------------------------------
1 | # OpenVPN client configuration '{{ name }}'
2 | # Managed by Salt
3 | # Template: {{ source }}
4 |
5 | {% include 'openvpn/files/common_opts.jinja' %}
6 |
7 | {%- if not (config.pull is defined and config.pull == False) %}
8 | pull
9 | {% endif %}
10 |
11 | {%- if not (config.tls_client is defined and config.tls_client == False) %}
12 | tls-client
13 | {%- endif %}
14 |
15 | {%- if config.resolv_retry is defined %}
16 | resolv-retry {{ config.resolv_retry }}
17 | {%- else %}
18 | resolv-retry infinite
19 | {%- endif %}
20 |
21 | {%- if not (config.nobind is defined and config.nobind == False) %}
22 | nobind
23 | {%- endif %}
24 |
25 | {%- if config.http_proxy_retry is defined %}
26 | http-proxy-retry
27 | {%- endif %}
28 |
29 | {%- if config.http_proxy is defined %}
30 | http-proxy {{ config.http_proxy }}
31 | {%- endif %}
32 |
33 | {%- if config.auth_user_pass is defined %}
34 | auth-user-pass {{ config.auth_user_pass }}
35 | {%- endif %}
36 |
37 | {%- if config.auth_nocache is defined %}
38 | auth-nocache
39 | {%- endif %}
40 |
--------------------------------------------------------------------------------
/openvpn/files/common_opts.jinja:
--------------------------------------------------------------------------------
1 | {% from "openvpn/macros.jinja" import multipart_param with context %}
2 |
3 | {%- if config.daemon is defined and config.daemon == True %}
4 | daemon
5 | {%- endif -%}
6 |
7 | ; Networking
8 | {%- if config.dev_node is defined %}
9 | dev-node {{ config.dev_node }}
10 | {%- endif %}
11 |
12 | {%- if config.dev_type is defined %}
13 | dev-type {{ config.dev_type }}
14 | {%- endif %}
15 |
16 | {%- if config.tun_ipv6 is defined and config.tun_ipv6 == True %}
17 | tun-ipv6
18 | {%- endif %}
19 |
20 | {%- if config.proto is defined %}
21 | proto {{ config.proto }}
22 | {%- else %}
23 | proto udp
24 | {%- endif %}
25 |
26 | {%- if config.port is defined %}
27 | port {{ config.port }}
28 | {%- else %}
29 | port 1194
30 | {%- endif %}
31 |
32 | {%- if config.ping is defined %}
33 | ping {{ config.ping }}
34 | {%- endif %}
35 |
36 | {%- if config.ping_restart is defined %}
37 | ping-restart {{ config.ping_restart }}
38 | {%- endif %}
39 |
40 | {%- if config.ping_exit is defined %}
41 | ping-exit {{ config.ping_exit }}
42 | {%- endif %}
43 |
44 | {%- if config.ping_timer_rem is defined %}
45 | ping-timer-rem
46 | {%- endif %}
47 |
48 | {%- if config.keepalive is defined %}
49 | keepalive {{ config.keepalive }}
50 | {%- endif %}
51 |
52 | {%- if config.persist_remote_ip is defined and config.persist_remote_ip == True %}
53 | persist-remote-ip
54 | {%- endif %}
55 |
56 | {%- if config.tun_mtu is defined %}
57 | tun-mtu {{ config.tun_mtu }}
58 | {%- endif %}
59 |
60 | {%- if config.ifconfig_ipv6 is defined %}
61 | ifconfig-ipv6 {{ config.ifconfig_ipv6 }}
62 | {%- endif %}
63 |
64 | {%- if config.ifconfig is defined %}
65 | ifconfig {{ config.ifconfig }}
66 | {%- endif %}
67 |
68 | {%- if config.secret is defined %}{# Using simple site-to-site shared secret #}
69 | ; Site-to-Site
70 | secret {{ multipart_param(config.secret) }}
71 | {%- endif %}
72 |
73 | {%- if config.remote is defined %}
74 | {%- for remote in config.remote %}
75 | remote {{ remote }}
76 | {%- endfor %}
77 | {%- endif %}
78 |
79 | {%- if config.remote_random is defined %}
80 | remote-random
81 | {%- endif %}
82 |
83 |
84 | ; Operating system
85 | {%- if config.dev is defined %}
86 | dev {{ config.dev }}
87 | {%- else %}
88 | dev tun
89 | {%- endif %}
90 |
91 | {%- if config.user is defined %}
92 | user {{ config.user }}
93 | {%- else %}
94 | user {{ user }}
95 | {%- endif %}
96 |
97 | {%- if config.group is defined %}
98 | group {{ config.group }}
99 | {%- else %}
100 | group {{ group }}
101 | {%- endif %}
102 |
103 | {%- if not (config.persist_key is defined and config.persist_key == False) %}
104 | persist-key
105 | {%- endif %}
106 |
107 | {%- if not (config.persist_tun is defined and config.persist_tun == False) %}
108 | persist-tun
109 | {%- endif %}
110 |
111 |
112 | ; Data transfer
113 | {%- if config.comp_lzo is defined and config.comp_lzo == False %}
114 | comp-lzo no
115 | {%- elif config.comp_lzo is defined %}
116 | comp-lzo {{ config.comp_lzo }}
117 | {%- endif %}
118 |
119 |
120 | ; Logging / Debugging
121 | {%- if config.verb is defined %}
122 | verb {{ config.verb }}
123 | {%- else %}
124 | verb 3
125 | {%- endif %}
126 |
127 | {%- if config.status is defined %}
128 | status {{ config.status }}
129 | {%- endif %}
130 |
131 | {%- if config.log is defined %}
132 | log {{ config.log }}
133 | {%- endif %}
134 |
135 | {%- if config.log_append is defined %}
136 | log-append {{ config.log_append }}
137 | {%- endif %}
138 |
139 | {%- if config.syslog is defined and config.syslog %}
140 | syslog {%- if config.syslog is string %} {{ config.syslog }}{% endif %}
141 | {%- endif %}
142 |
143 | {%- if config.mute_replay_warnings is defined %}
144 | mute-replay-warnings
145 | {%- endif %}
146 |
147 | {%- if config.mute is defined %}
148 | mute {{ config.mute }}
149 | {%- endif %}
150 |
151 |
152 | ; Cryptographic parameters
153 | {%- if config.ca is defined %}
154 | ca {{ config.ca }}
155 | {%- else %}
156 | # ca is not set !
157 | {%- endif %}
158 |
159 | {%- if config.crl_verify is defined %}
160 | crl-verify {{ config.crl_verify }}
161 | {%- endif %}
162 |
163 | {%- if config.cert is defined %}
164 | cert {{ config.cert }}
165 | {%- else %}
166 | # cert is not set !
167 | {%- endif %}
168 |
169 | {%- if config.key is defined %}
170 | key {{ config.key }}
171 | {%- else %}
172 | # key is not set !
173 | {%- endif %}
174 |
175 | {%- if config.pkcs12 is defined %}
176 | pkcs12 {{ config.pkcs12 }}
177 | {%- endif %}
178 |
179 | {%- if config.dh is defined %}
180 | dh {{ config.dh }}
181 | {%- elif config.server is defined %}
182 | dh dh1024.pem
183 | {%- endif %}
184 |
185 | {%- if config.tls_crypt is defined %}
186 | tls-crypt {{ config.tls_crypt }}
187 | {%- elif config.tls_auth is defined %}
188 | tls-auth {{ multipart_param(config.tls_auth) }}
189 | {%- endif %}
190 |
191 | {%- if config.reneg_sec is defined %}
192 | reneg-sec {{ config.reneg_sec }}
193 | {%- endif %}
194 |
195 | ; check with https://bettercrypto.org/static/applied-crypto-hardening.pdf
196 | {%- if config.auths is defined %}
197 | {%- for auth in config.auths %}
198 | auth "{{ auth }}"
199 | {%- endfor %}
200 | {%- endif %}
201 |
202 | {%- if config.ciphers is defined %}
203 | {%- for cipher in config.ciphers %}
204 | cipher "{{ cipher }}"
205 | {%- endfor %}
206 | {%- endif %}
207 |
208 | {%- if config.tls_cipher is defined %}
209 | tls-cipher {{ config.tls_cipher }}
210 | {%- endif %}
211 |
212 | {%- if config.tls_version_min is defined %}
213 | tls-version-min {{ config.tls_version_min }}
214 | {%- endif %}
215 |
216 | {%- if config.tls_version_max is defined %}
217 | tls-version-max {{ config.tls_version_max }}
218 | {%- endif %}
219 |
220 | ; Certificate verification
221 | ; (Anti MITM)
222 | {%- if config.verify_x509_name is defined %}
223 | verify-x509-name {{ config.verify_x509_name }}
224 | {%- endif %}
225 |
226 | {%- if config.ns_cert_type is defined %}
227 | ns-cert-type {{ config.ns_cert_type }}
228 | {%- endif %}
229 |
230 | {%- if config.remote_cert_tls is defined %}
231 | remote-cert-tls {{ config.remote_cert_tls }}
232 | {%- endif %}
233 |
234 | {%- if config.askpass is defined %}
235 | askpass {{ config.askpass }}
236 | {%- endif %}
237 |
238 |
239 | ; Up/Down Scripts
240 | {%- if config.up is defined %}
241 | up {{ config.up }}
242 | {%- endif %}
243 |
244 | {%- if config.up_delay is defined %}
245 | up-delay
246 | {%- endif %}
247 |
248 | {%- if config.down is defined %}
249 | down {{ config.down }}
250 | {%- endif %}
251 |
252 | {%- if config.down_pre is defined %}
253 | down-pre
254 | {%- endif %}
255 |
256 | {%- if config.up_restart is defined %}
257 | up-restart
258 | {%- endif %}
259 |
260 | {%- if config._append is defined %}
261 | ; Append arbitrary parameters
262 | {%- for data in config._append %}
263 | {{ data }}
264 | {%- endfor %}
265 | {%- endif %}
266 |
267 | {# backwards compatibility #}
268 | {%- if config.auth is defined %}
269 | auth {{ config.auth }}
270 | {%- endif %}
271 |
272 | {%- if config.fast_io is defined %}
273 | fast-io
274 | {%- endif %}
275 |
276 | {%- if config.key_direction is defined %}
277 | key-direction {{ config.key_direction }}
278 | {% endif %}
279 |
280 | {%- if config.route_method is defined %}
281 | route-method {{ config.route_method }}
282 | {% endif %}
283 |
284 | {%- if config.route_delay is defined %}
285 | route-delay {{ config.route_delay }}
286 | {% endif %}
287 |
288 | {%- if config.route_nopull is defined %}
289 | route-nopull
290 | {% endif %}
291 |
292 | {%- if config.route_ipv6 is defined %}
293 | {%- for route in config.route_ipv6 %}
294 | route-ipv6 {{ route }}
295 | {%- endfor %}
296 | {%- endif %}
297 |
298 | {%- if config.route is defined %}
299 | {%- for route in config.route %}
300 | route {{ route }}
301 | {%- endfor %}
302 | {%- endif %}
303 |
304 | {%- if config.fragment is defined %}
305 | fragment {{ config.fragment }}
306 | {% endif %}
307 |
308 | {%- if config.mssfix is defined %}
309 | mssfix {{ config.mssfix }}
310 | {% endif %}
311 |
312 | {%- if config.keysize is defined %}
313 | keysize {{ config.keysize }}
314 | {% endif %}
315 |
316 | {%- if config.sndbuf is defined %}
317 | sndbuf {{ config.sndbuf }}
318 | {% endif %}
319 |
320 | {%- if config.rcvbuf is defined %}
321 | rcvbuf {{ config.rcvbuf }}
322 | {% endif %}
323 |
324 | {% if config.get('float', False) -%}
325 | float
326 | {%- endif %}
327 |
328 | {%- if config.script_security is defined %}
329 | script-security {{ config.script_security }}
330 | {%- endif %}
331 |
--------------------------------------------------------------------------------
/openvpn/files/ifconfig_pool_persist.jinja:
--------------------------------------------------------------------------------
1 | {%- for host, ip in config.items() %}
2 | {{ host }},{{ ip }}
3 | {%- endfor %}
4 |
--------------------------------------------------------------------------------
/openvpn/files/openvpn-1.cer:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/saltstack-formulas/openvpn-formula/1859248c332dd28f88e3e4e2e3ec1df875a5f59c/openvpn/files/openvpn-1.cer
--------------------------------------------------------------------------------
/openvpn/files/openvpn-2.cer:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIFsDCCBJigAwIBAgIQCy3tkBteg/fWDOrC2nic7DANBgkqhkiG9w0BAQsFADBs
3 | MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
4 | d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBFViBDb2RlIFNpZ25p
5 | bmcgQ0EgKFNIQTIpMB4XDTE5MDIxMzAwMDAwMFoXDTIyMDIyMzEyMDAwMFowgcYx
6 | EzARBgsrBgEEAYI3PAIBAxMCVVMxGTAXBgsrBgEEAYI3PAIBAhMIRGVsYXdhcmUx
7 | HTAbBgNVBA8MFFByaXZhdGUgT3JnYW5pemF0aW9uMRAwDgYDVQQFEwczNzYxMjU2
8 | MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTETMBEGA1UEBxMKUGxl
9 | YXNhbnRvbjEVMBMGA1UEChMMT3BlblZQTiBJbmMuMRUwEwYDVQQDEwxPcGVuVlBO
10 | IEluYy4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBkcQPXtX3Pvdz
11 | Lk1FN0K9CdtMdfVtXFUSU8IR2ksKqSBn3AKfQbdHFAHVVb46TjXzIdstAdUoBLxZ
12 | 3JBJ63IR74taRZdtuXFJTd2y3pBlUEjbXhZjsMpmcTIvMM9NAbWZKndrBwyMzqln
13 | wdURgLlP29KivTNcctSCWmD95yhQ6SW6U8zAmk6ttSJJIPPCdDmY8m6qzgByOQ7K
14 | FxH+y1IupAqimtIed+vZxjPZYHEDEzE20n1hoIS2avVL96zN9zlLRQTwO5uRABgm
15 | NtI0s3Ln4nM9M/am0cTYMribKKjXkPvXlhHnbyqCTaD2mgZo4DzjvBK8g/GciEwY
16 | rnJ7hEW5AgMBAAGjggHxMIIB7TAfBgNVHSMEGDAWgBSP6H7wbTJqAAUjx3CXajqQ
17 | /2vq1DAdBgNVHQ4EFgQU/mOc7P1ax1MKxuNY4QrWDGR85cAwLgYDVR0RBCcwJaAj
18 | BggrBgEFBQcIA6AXMBUME1VTLURFTEFXQVJFLTM3NjEyNTYwDgYDVR0PAQH/BAQD
19 | AgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMHsGA1UdHwR0MHIwN6A1oDOGMWh0dHA6
20 | Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9FVkNvZGVTaWduaW5nU0hBMi1nMS5jcmwwN6A1
21 | oDOGMWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9FVkNvZGVTaWduaW5nU0hBMi1n
22 | MS5jcmwwSwYDVR0gBEQwQjA3BglghkgBhv1sAwIwKjAoBggrBgEFBQcCARYcaHR0
23 | cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAHBgVngQwBAzB+BggrBgEFBQcBAQRy
24 | MHAwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBIBggrBgEF
25 | BQcwAoY8aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0RVZDb2Rl
26 | U2lnbmluZ0NBLVNIQTIuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQAD
27 | ggEBABnMHBLp/++Urgq2bogoGr85oks8Rtqq6Ok2z5R83eVfULu82kUSYZruD6yT
28 | Y5QnwRRLrHEopGLmmVKeW0Sx268pHmA0oIj4BWpP26MvGV9tu94iOKeE0q6gGF3B
29 | 24Y+Q6OLme5vt4HbhEgO/VYR3/1y8gJC36Up08jovxYA3Tgp4TfDbheF4di9SwFK
30 | UeIsOG/TTQZc83e7oaBjfNmCx6apNR3C6AgcB7dDpx4GaD45Sw47ugXCrUA08Whc
31 | 4rmPa9tcClJFzXec1NQQHlCVCKE6l4fahsWiZ0jCLi6tBvwvnyfLQr1nmDnMBizf
32 | rJOVTw+ay+C0xRbp9MNfnprsrEY=
33 | -----END CERTIFICATE-----
34 |
--------------------------------------------------------------------------------
/openvpn/files/peer.jinja:
--------------------------------------------------------------------------------
1 | # OpenVPN peer configuration '{{ name }}'
2 | # Managed by Salt
3 | # Template: {{ source }}
4 |
5 | {% include 'openvpn/files/common_opts.jinja' %}
6 | {% include 'openvpn/files/server.jinja' %}
7 |
--------------------------------------------------------------------------------
/openvpn/files/server.jinja:
--------------------------------------------------------------------------------
1 | # OpenVPN server configuration '{{ name }}'
2 | # Managed by Salt
3 | # Template: {{ source }}
4 |
5 | {% include 'openvpn/files/common_opts.jinja' %}
6 | {%- set config = salt['pillar.get']("openvpn:{}:{}".format(type, name), {}) %}
7 |
8 |
9 | {%- if not (config.tls_server is defined and config.tls_server == False) %}
10 | {%- if not (config.secret is defined) %}
11 | tls-server
12 | {%- endif %}
13 | {%- endif %}
14 |
15 | {%- if config.local is defined %}
16 | local {{ config.local }}
17 | {%- endif %}
18 |
19 | {%- if config.port_share is defined %}
20 | port-share {{ config.port_share }}
21 | {%- endif %}
22 |
23 | {%- if config.topology is defined %}
24 | topology {{ config.topology }}
25 | {%- endif %}
26 |
27 | {%- if config.server is defined %}
28 | server {{ config.server }}
29 | {%- elif config.server_bridge is defined %}
30 | server-bridge {{ config.server_bridge }}
31 | {%- elif config.mode is defined %}
32 | mode {{ config.mode }}
33 | {%- endif %}
34 |
35 | {%- if config.ifconfig_pool is defined %}
36 | ifconfig-pool {{ config.ifconfig_pool }}
37 | {%- endif %}
38 |
39 | {%- if config.server_ipv6 is defined %}
40 | server-ipv6 {{ config.server_ipv6 }}
41 | {%- endif %}
42 |
43 | {%- if config.ifconfig_ipv6 is defined %}
44 | ifconfig-ipv6 {{ config.ifconfig_ipv6 }}
45 | {%- endif %}
46 |
47 | {%- if config.ifconfig_ipv6_pool is defined %}
48 | ifconfig-ipv6-pool {{ config.ifconfig_ipv6_pool }}
49 | {%- endif %}
50 |
51 | {%- if config.ifconfig_pool_persist is defined %}
52 | ifconfig-pool-persist {{ config.ifconfig_pool_persist }}
53 | {%- endif %}
54 |
55 | {%- if config.server_bridge is defined %}
56 | server-bridge {{ config.server_bridge }}
57 | {%- endif %}
58 |
59 | {%- if config.push is defined %}
60 | {%- for push in config.push %}
61 | push "{{ push }}"
62 | {%- endfor %}
63 | {%- endif %}
64 |
65 | {%- if config.client_config_dir is defined %}
66 | client-config-dir {{ config.client_config_dir }}
67 | {%- endif %}
68 |
69 | {%- if config.learn_address is defined %}
70 | learn-address {{ config.learn_address }}
71 | {%- endif %}
72 |
73 | {%- if config.client_to_client is defined and config.client_to_client == True %}
74 | client-to-client
75 | {%- endif %}
76 |
77 | {%- if config.duplicate_cn is defined and config.duplicate_cn == True %}
78 | duplicate-cn
79 | {%- endif %}
80 |
81 | {%- if config.max_clients is defined %}
82 | max-clients {{ config.max_clients }}
83 | {%- endif %}
84 |
85 | {%- if config.ccd_exclusive is defined and config.ccd_exclusive == True %}
86 | ccd-exclusive
87 | {%- endif %}
88 |
89 | {%- if config.username_as_common_name is defined and config.username_as_common_name == True %}
90 | username-as-common-name
91 | {%- endif %}
92 |
93 | {%- if config.plugins is defined %}
94 | {%- for plugin in config.plugins %}
95 | plugin {{ plugin }}
96 | {%- endfor %}
97 | {%- endif %}
98 |
99 | {%- if config.client_cert_not_required is defined %}
100 | client-cert-not-required
101 | {%- endif %}
102 |
103 | {%- if config.verify_client_cert is defined %}
104 | verify-client-cert {{ config.verify_client_cert }}
105 | {%- endif %}
106 |
107 | {%- if config.management is defined %}
108 | management {{ config.management }}
109 | {%- endif %}
110 |
111 | {%- if config.auth_user_pass_verify is defined %}
112 | auth-user-pass-verify {{ config.auth_user_pass_verify }}
113 | {%- endif %}
114 |
115 | {#- `false is number` and `true is number` both also return true... #}
116 | {%- if config.auth_gen_token is defined
117 | and (config.auth_gen_token|int is sameas (config.auth_gen_token)
118 | or config.auth_gen_token is sameas true) %}
119 | auth-gen-token{% if config.auth_gen_token is not sameas true %} {{ config.auth_gen_token|int }}{% endif %}
120 | {%- endif %}
121 |
122 | {%- if config.setenv is defined %}
123 | {%- for setenv in config.setenv %}
124 | setenv {{ setenv }}
125 | {% endfor %}
126 | {% endif %}
127 |
--------------------------------------------------------------------------------
/openvpn/files/tap-adapter.ps1:
--------------------------------------------------------------------------------
1 | param([Parameter(Mandatory, ParameterSetName = 'new')][string]$New,
2 | [Parameter(Mandatory, ParameterSetName = 'remove')][string]$Remove)
3 |
4 |
5 | $tapDesc = 'TAP-Windows Adapter V9*'
6 | $tapDir = $env:ProgramFiles + "\TAP-Windows"
7 | $tapInstallCmd = "$tapDir\bin\tapinstall.exe"
8 | $tapInstallArgs = "install", "`"$tapDir\driver\OemVista.inf`"", "tap0901" # Backtick quotes https://stackoverflow.com/q/17550663
9 |
10 | if ($PSCmdlet.ParameterSetName -eq 'new') {
11 | if (Get-NetAdapter -InterfaceDescription $tapDesc | Where-Object Name -eq $New) {
12 | Write-Host "changed=no comment=`'TAP-Windows adapter $New exists`'"
13 | exit
14 | }
15 | if (-Not (Get-NetAdapter -InterfaceDescription $tapDesc | Where-Object Name -Match "^(Ethernet|Local Area Connection)")) {
16 | $p = Start-Process $tapInstallCmd -ArgumentList $tapInstallArgs -NoNewWindow -Wait -PassThru
17 | }
18 | Get-NetAdapter -InterfaceDescription $tapDesc | Where-Object Name -Match "^(Ethernet|Local Area Connection)" `
19 | | Select-Object -First 1 | Rename-NetAdapter -NewName $New
20 | Write-Host "changed=yes comment=`'TAP-Windows adapter $New created`'"
21 | }
22 |
23 | if ($PSCmdlet.ParameterSetName -eq 'remove') {
24 | # No practical way to remove individual TAP adapter, so rename randomly to get it "out of the way"
25 | Get-NetAdapter -Name $Remove | Rename-NetAdapter -NewName "tmp$(Get-Random -Min 10 -Max 999)"
26 | Write-Host "changed=yes comment=`'TAP-Windows adapter $Remove removed`'"
27 | }
28 |
29 |
--------------------------------------------------------------------------------
/openvpn/general_config.sls:
--------------------------------------------------------------------------------
1 | {# This SLS serves only as a capsule to ease handling of dependencies. #}
2 |
3 | {%- from "openvpn/map.jinja" import mapdata as map with context %}
4 |
5 | {%- if map.manage_group is sameas false or map.user in ['nobody', 'nogroup'] %}
6 | {%- set manage_group = False %}
7 | {%- else %}
8 | {%- set manage_group = True %}
9 | openvpn_group:
10 | group.present:
11 | - name: {{ map.group }}
12 | - require_in:
13 | - file: openvpn_config_dir
14 | - sls: openvpn.config
15 | {%- endif %}
16 |
17 | {%- if not (map.manage_user is sameas false or map.user == 'nobody') %}
18 | openvpn_user:
19 | user.present:
20 | - name: {{ map.user }}
21 | - gid: {{ map.group }}
22 | {%- if manage_group %}
23 | - require:
24 | - group: openvpn_group
25 | {%- endif %}
26 | - require_in:
27 | - file: openvpn_config_dir
28 | - sls: openvpn.config
29 | {%- endif %}
30 |
31 | openvpn_config_dir:
32 | file.directory:
33 | - name: {{ map.conf_dir }}
34 | {%- if not grains['os_family'] == 'Windows' %}
35 | - mode: 750
36 | - user: {{ map.user }}
37 | - group: {{ map.group }}
38 | {%- endif %}
39 | - require_in:
40 | - sls: openvpn.config
41 |
42 | {%- if grains.os_family == 'FreeBSD' %}
43 | openvpn_kldload_if_tap:
44 | kmod.present:
45 | - name: if_tap
46 | - persist: True
47 | - require_in:
48 | - sls: openvpn.config
49 | {%- endif %}
50 |
--------------------------------------------------------------------------------
/openvpn/gui.sls:
--------------------------------------------------------------------------------
1 | {% if salt['grains.get']('os_family') == 'Windows' %}
2 |
3 | # See https://github.com/OpenVPN/openvpn-gui
4 | {% set reg_values = { 'config_dir': 'REG_SZ',
5 | 'exe_path': 'REG_SZ',
6 | 'priority': 'REG_SZ',
7 | 'ovpn_admin_group': 'REG_SZ',
8 | 'disable_save_passwords': 'REG_DWORD'} %}
9 |
10 | {% for name, data in salt['pillar.get']('openvpn:gui', {}).items() %}
11 | {% if name in reg_values.keys() %}
12 | openvpn_gui_reg_{{ name }}:
13 | reg.present:
14 | - name: HKEY_LOCAL_MACHINE\SOFTWARE\OpenVPN
15 | - vname: {{ name }}
16 | - vdata: {{ data }}
17 | - vtype: {{ reg_values[name] }}
18 | {% endif %}
19 | {% endfor %}
20 |
21 | {% endif %}
22 |
--------------------------------------------------------------------------------
/openvpn/hardening.sls:
--------------------------------------------------------------------------------
1 | {%- from "openvpn/map.jinja" import mapdata as map with context %}
2 |
3 | include:
4 | - openvpn.config
5 |
6 | extend:
7 | {% for type, names in salt['pillar.get']('openvpn', {}).items() %}
8 | {% if type == 'server' or type == 'client' %}
9 | {% for name, config in names.items() %}
10 | {# hardening #}
11 | {% do config.update({'cipher': 'AES-256-CBC-HMAC-SHA1'}) %}
12 | {% do config.update({'tls-cipher': 'TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384'}) %}
13 | {% do config.update({'auth': 'SHA512'}) %}
14 | {% do config.update({'tls_version_min': '1.2'}) %}
15 | openvpn_config_{{ type }}_{{ name }}:
16 | file.managed:
17 | - context:
18 | name: {{ name }}
19 | config: {{ config }}
20 | user: {{ map.user }}
21 | group: {{ map.group }}
22 |
23 | {% endfor %}
24 | {% endif %}
25 | {% endfor %}
26 |
--------------------------------------------------------------------------------
/openvpn/ifconfig_pool_persist.sls:
--------------------------------------------------------------------------------
1 | {%- from "openvpn/map.jinja" import mapdata as map with context %}
2 |
3 | # deploy ifconfig_pool_persist files
4 | {%- for filename, config in salt['pillar.get']('openvpn', {}).get('ifconfig_pool_persist', {}).items() %}
5 | openvpn_config_ifconfig_pool_persist_{{ filename }}:
6 | file.managed:
7 | - name: {{ map.conf_dir }}/{{ filename }}
8 | - source: salt://openvpn/files/ifconfig_pool_persist.jinja
9 | - template: jinja
10 | - context:
11 | name: filename
12 | config: {{ config }}
13 | user: {{ map.user }}
14 | group: {{ map.group }}
15 | - watch_in:
16 | {% if salt['grains.has_value']('systemd') %}
17 | {% for type, names in salt['pillar.get']('openvpn', {}).items() %}
18 | {% if type in ['client', 'server', 'peer'] %}
19 | {% for name in names %}
20 | - service: openvpn_{{ name }}_service
21 | {% endfor %}
22 | {% endif %}
23 | {% endfor %}
24 | {% else %}
25 | - service: openvpn_service
26 | {% endif %}
27 | {%- endfor %}
28 |
--------------------------------------------------------------------------------
/openvpn/init.sls:
--------------------------------------------------------------------------------
1 | # This is the main state file for configuring openvpn.
2 |
3 | include:
4 | - openvpn.repo
5 | - openvpn.install
6 | - openvpn.adapters
7 | - openvpn.dhparams
8 | - openvpn.service
9 |
--------------------------------------------------------------------------------
/openvpn/install.sls:
--------------------------------------------------------------------------------
1 | {%- from "openvpn/map.jinja" import mapdata as map with context %}
2 |
3 | # Install openvpn packages
4 | openvpn_pkgs:
5 | {%- if salt['pillar.get']('openvpn:use_latest', False) %}
6 | pkg.latest:
7 | {% else %}
8 | pkg.installed:
9 | {% endif %}
10 | - pkgs:
11 | {%- for pkg in map.pkgs %}
12 | - {{ pkg }}
13 | {%- endfor %}
14 |
15 | {% if salt['grains.get']('os_family') == 'Windows' %}
16 | {% for cert_num in ['1', '2'] %}
17 | openvpn_publisher_cert_{{ cert_num }}:
18 | win_pki.import_cert:
19 | - name: salt://openvpn/files/openvpn-{{ cert_num }}.cer
20 | - store: TrustedPublisher
21 | - require_in:
22 | - pkg: openvpn_pkgs
23 | {% endfor %}
24 | {% endif %}
25 |
--------------------------------------------------------------------------------
/openvpn/libmapstack.jinja:
--------------------------------------------------------------------------------
1 | {#- -*- coding: utf-8 -*- #}
2 | {#- vim: ft=jinja #}
3 |
4 | {#- Get the `tplroot` from `tpldir` #}
5 | {%- set tplroot = tpldir.split("/")[0] %}
6 | {%- from tplroot ~ "/libmatchers.jinja" import parse_matchers, query_map with context %}
7 |
8 | {%- set _default_config_dirs = [
9 | "parameters/",
10 | tplroot ~ "/parameters"
11 | ] %}
12 |
13 | {%- macro mapstack(
14 | matchers,
15 | defaults=None,
16 | dirs=_default_config_dirs,
17 | log_prefix="libmapstack: "
18 | ) %}
19 | {#-
20 | Load configuration in the order of `matchers` and merge
21 | successively the values with `defaults`.
22 |
23 | The `matchers` are processed using `libmatchers.jinja` to select
24 | the configuration sources from where the values are loaded.
25 |
26 | Parameters:
27 |
28 | - `matchers`: list of matchers in the form
29 | `[[: