├── .gitignore ├── .kitchen.dokken.yml ├── .kitchen.yml ├── .rubocop.yml ├── Berksfile ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── Rakefile ├── TESTING.md ├── attributes ├── apt_repos.rb ├── cron_d.rb ├── groups.rb ├── init_d.rb ├── iptables_d.rb ├── sudoers_d.rb ├── users.rb └── yum_repos.rb ├── chefignore ├── libraries ├── crontab.rb ├── default.rb ├── directory.rb ├── groups.rb └── users.rb ├── metadata.rb ├── recipes ├── apt_repos.rb ├── cron_d.rb ├── init_d.rb ├── iptables_d.rb ├── sudoers_d.rb └── yum_repos.rb └── test ├── fixtures └── cookbooks │ └── test │ ├── attributes │ └── default.rb │ ├── files │ ├── cron │ └── file.txt │ ├── metadata.rb │ ├── recipes │ ├── apt_repos.rb │ ├── cron.rb │ ├── cron_d.rb │ ├── directory.rb │ ├── force.rb │ ├── groups.rb │ ├── init_d.rb │ ├── iptables_d.rb │ ├── notifies.rb │ ├── sudoers_d.rb │ ├── users.rb │ └── yum_repos.rb │ └── templates │ └── source.erb └── integration ├── apt_repos └── default.rb ├── cron └── default.rb ├── cron_d └── default.rb ├── directory └── default.rb ├── groups └── default.rb ├── init_d └── default.rb ├── iptables_d └── default.rb ├── notified └── default.rb ├── sudoers_d └── default.rb ├── unnotified └── default.rb ├── users └── default.rb └── yum_repos └── default.rb /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | .bundle 4 | .config 5 | .kitchen 6 | coverage 7 | vendor/ 8 | InstalledFiles 9 | lib/bundler/man 10 | pkg 11 | rdoc 12 | spec/reports 13 | test/tmp 14 | test/version_tmp 15 | tmp 16 | 17 | # YARD artifacts 18 | .yardoc 19 | _yardoc 20 | doc/ 21 | 22 | Berksfile.lock 23 | Gemfile.lock 24 | *~ 25 | 26 | bin/ 27 | -------------------------------------------------------------------------------- /.kitchen.dokken.yml: -------------------------------------------------------------------------------- 1 | driver: 2 | name: dokken 3 | privileged: true # because Docker and SystemD/Upstart 4 | chef_version: <%= ENV['CHEF_VERSION'] || 'current' %> 5 | 6 | transport: 7 | name: dokken 8 | 9 | provisioner: 10 | name: dokken 11 | deprecations_as_errors: false 12 | 13 | verifier: 14 | name: inspec 15 | 16 | platforms: 17 | - name: amazonlinux-2 18 | driver: 19 | image: dokken/amazonlinux-2 20 | pid_one_command: /usr/lib/systemd/systemd 21 | 22 | - name: debian-9 23 | driver: 24 | image: dokken/debian-9 25 | pid_one_command: /bin/systemd 26 | intermediate_instructions: 27 | - RUN /usr/bin/apt-get update 28 | 29 | - name: debian-10 30 | driver: 31 | image: dokken/debian-10 32 | pid_one_command: /bin/systemd 33 | intermediate_instructions: 34 | - RUN /usr/bin/apt-get update 35 | 36 | - name: centos-6 37 | driver: 38 | image: dokken/centos-6 39 | pid_one_command: /sbin/init 40 | 41 | - name: centos-7 42 | driver: 43 | image: dokken/centos-7 44 | pid_one_command: /usr/lib/systemd/systemd 45 | 46 | - name: centos-8 47 | driver: 48 | image: dokken/centos-8 49 | pid_one_command: /usr/lib/systemd/systemd 50 | 51 | - name: fedora-latest 52 | driver: 53 | image: dokken/fedora-latest 54 | pid_one_command: /usr/lib/systemd/systemd 55 | 56 | - name: ubuntu-16.04 57 | driver: 58 | image: dokken/ubuntu-16.04 59 | pid_one_command: /bin/systemd 60 | intermediate_instructions: 61 | - RUN /usr/bin/apt-get update 62 | 63 | - name: ubuntu-18.04 64 | driver: 65 | image: dokken/ubuntu-18.04 66 | pid_one_command: /bin/systemd 67 | intermediate_instructions: 68 | - RUN /usr/bin/apt-get update 69 | -------------------------------------------------------------------------------- /.kitchen.yml: -------------------------------------------------------------------------------- 1 | --- 2 | driver: 3 | name: vagrant 4 | 5 | provisioner: 6 | name: chef_zero 7 | deprecations_as_errors: false 8 | chef_license: accept-no-persist 9 | product_name: chef 10 | product_version: <%= ENV['CHEF_VERSION'] || 'latest' %> 11 | 12 | verifier: 13 | name: inspec 14 | 15 | platforms: 16 | - name: amazonlinux 17 | driver_config: 18 | box: mvbcoding/awslinux 19 | - name: amazonlinux-2 20 | - name: centos-6 21 | - name: centos-7 22 | - name: centos-8 23 | - name: debian-9 24 | - name: debian-10 25 | - name: fedora-latest 26 | - name: ubuntu-16.04 27 | - name: ubuntu-18.04 28 | 29 | suites: 30 | - name: apt_repos 31 | includes: 32 | - debian-9 33 | - debian-10 34 | - ubuntu-16.04 35 | - ubuntu-18.04 36 | run_list: 37 | - recipe[test::apt_repos] 38 | 39 | - name: cron 40 | run_list: 41 | - recipe[test::cron] 42 | 43 | - name: cron_d 44 | run_list: 45 | - recipe[test::cron_d] 46 | 47 | - name: directory 48 | run_list: 49 | - recipe[test::directory] 50 | 51 | - name: groups 52 | run_list: 53 | - recipe[test::groups] 54 | 55 | - name: users 56 | run_list: 57 | - recipe[test::users] 58 | 59 | - name: yum_repos 60 | includes: 61 | - amazonlinux 62 | - centos-6 63 | - centos-7 64 | run_list: 65 | - recipe[test::yum_repos] 66 | 67 | - name: iptables_d 68 | includes: 69 | - centos-6 70 | - centos-7 71 | run_list: 72 | - recipe[test::iptables_d] 73 | 74 | - name: sudoers_d 75 | run_list: 76 | - recipe[test::sudoers_d] 77 | 78 | - name: init_d 79 | includes: 80 | - amazonlinux 81 | - centos-6 82 | run_list: 83 | - recipe[test::init_d] 84 | 85 | - name: notified 86 | attributes: 87 | obsolete: true 88 | run_list: 89 | - recipe[test::notifies] 90 | 91 | - name: unnotified 92 | attributes: 93 | obsolete: false 94 | run_list: 95 | - recipe[test::notifies] 96 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | AllCops: 2 | NewCops: enable 3 | 4 | Layout/LeadingCommentSpace: 5 | Enabled: false 6 | 7 | Metrics/AbcSize: 8 | Enabled: false 9 | 10 | Metrics/MethodLength: 11 | Enabled: false 12 | 13 | Style/ConditionalAssignment: 14 | Enabled: false 15 | 16 | Style/IfUnlessModifier: 17 | Enabled: false 18 | 19 | Style/Lambda: 20 | EnforcedStyle: lambda 21 | 22 | Style/PercentLiteralDelimiters: 23 | PreferredDelimiters: 24 | "%w": "()" 25 | -------------------------------------------------------------------------------- /Berksfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source 'https://supermarket.chef.io' 4 | 5 | metadata 6 | 7 | group :integration do 8 | cookbook 'test', path: 'test/fixtures/cookbooks/test' 9 | end 10 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | zap Cookbook CHANGELOG 2 | ====================== 3 | This file is used to list changes made in each version of the zap cookbook. 4 | 5 | v2.3.0 6 | - Fix bug in sudoers file name 7 | 8 | v2.2.0 9 | - Support *whyrun* 10 | 11 | v2.1.3 12 | - Fix false-negative in cron tests 13 | 14 | v2.1.2 15 | ### Bugfix 16 | - Fix scoping issue in Chef::Provider::Zap#purge 17 | 18 | v2.1.1 19 | ### Bugfix 20 | - Silence foodcritic warning 21 | 22 | v2.1.0 23 | ### Minor 24 | - Add *notifies* support 25 | 26 | v2.0.1 27 | ### Bugfix 28 | - Fix bug in zap_directory.purge 29 | 30 | v2.0.0 31 | ### Major 32 | - Complete overhaul of code 33 | 34 | v1.2.0 35 | ### Minor 36 | - Add *filter* support to `zap_directory` 37 | 38 | v1.1.0 39 | ### Minor 40 | - Add *immediately* support to `zap::apt_repos` and `zap::yum_repos` 41 | 42 | v1.0.2 43 | ### Enhancement 44 | - Add `zap::init_d` to disable sysv-init services on centos-6 45 | 46 | v1.0.1 47 | ### Enhancement 48 | - Add `zap::sudoers_d` to prune `sudo` resources from /etc/sudoers.d 49 | 50 | v1.0.0 51 | ### Breaking change 52 | - Rewrote to support custom resources 53 | - Remove `zap_firewall` as v2.6.2 of the firewall cookbook manages the ruleset as a whole 54 | - Remove `zap_apt_repos` in favor of the `zap::apt_repos` recipe 55 | - Remove `zap_yum_repos` in favor of the `zap::yum_repos` recipe 56 | 57 | v0.15.1 58 | ### Bugfix 59 | - Fix bug with filter property lamba expression 60 | 61 | v0.15.0 62 | ### Enhancement 63 | - Add `force` to force running of `zap` when there is an override_runlist 64 | Addresses https://github.com/nvwls/zap/issues/36 65 | 66 | v0.14.0 67 | ### Bugfix 68 | - Fix issues with zap_crontab and non-root cron 69 | 70 | v0.13.1 71 | ### Improvement 72 | - added unit tests for `zap_groups` 73 | 74 | v0.13.0 75 | ### Bugfix 76 | - Fix rubocop and foodcritic lint 77 | 78 | v0.12.0 79 | ### Improvement 80 | - added unit tests for zap_users and zap_yum_repos 81 | - adapt logic to make it compatible with versions 12.14 and higher 82 | 83 | v0.11.4 84 | ------- 85 | ### Enhancement 86 | Bump version for tag 87 | 88 | v0.11.3 89 | ------- 90 | ### Enhancement 91 | Using stove for upload 92 | 93 | v0.11.2 94 | ------- 95 | ### Enhancement 96 | - Display a warning if a filter is given but the provider does not support it. 97 | 98 | v0.11.1 99 | ------- 100 | ### Bugfix 101 | - Apply @pattern before entering `converge_by` 102 | 103 | v0.11.0 104 | ------- 105 | ### Enhancement 106 | - Reworked to use `converge_by` 107 | 108 | v0.10.0 109 | ------- 110 | ### Enhancement 111 | - Allow klass to be passed into zap() 112 | - zap_directory will now remove symlinks 113 | 114 | v0.9.1 115 | ------ 116 | ### Bugfix 117 | - Internally @klass should be an array 118 | 119 | v0.9.0 120 | ------ 121 | ### Improvement 122 | - Reworked klass to convert string into class 123 | - Added recipe [zap::cron_d] to remove /etc/cron.d entries 124 | 125 | v0.8.7 126 | ------ 127 | ### Improvement 128 | - Added recipe [zap::firewall_windows] adds Windows Firewall support to zap firewall recipe 129 | 130 | v0.8.6 131 | ------ 132 | ### Enhancement 133 | - Support using a descriptive resource name; added path var to zap_directory 134 | 135 | v0.8.5 136 | ------ 137 | ### Bugfix 138 | - Using the shovel operator in chef 12 results in the resource being 139 | added directly after the current resource, rather than at the end 140 | of the resource list. [joyofhex] 141 | 142 | v0.8.4 143 | ------ 144 | ### Bugfix 145 | - Support globbed directories, e.g. `/home/*/.ssh` 146 | 147 | v0.8.3 148 | ------ 149 | ### Improvement 150 | - Added recipe [zap::firewall] for support for the firewall cookbook (main caller) 151 | - Added recipe [zap::firewall_iptables] adds iptables support to zap firewall recipe 152 | - Added recipe [zap::firewall_firewalld] adds firewalld support to zap firewall recipe 153 | 154 | v0.8.2 155 | ------ 156 | ### Improvement 157 | - Eliminate warnings on newer versions of ChefSpec 158 | 159 | v0.8.1 160 | ------ 161 | ### Bugfix 162 | - Added ZapDirectory#select to return `path` instead of the default of `name`. 163 | 164 | The following will now be properly recognized: 165 | 166 | ```ruby 167 | file 'arbitrary name' do 168 | path '/the/real/path' 169 | end 170 | ``` 171 | 172 | v0.8.0 173 | ------ 174 | ### Improvement 175 | - Added recursive option to zap_directory to remove all files under the 176 | specified directory 177 | 178 | v0.5.2 179 | ------ 180 | ### Improvement 181 | - Refactored recipe[zap::yum_repos_d] into the zap_yum_repos resource provider 182 | - Added an option to call zap immediately at a certain point in your Chef run 183 | 184 | v0.5.1 185 | ------ 186 | ### Improvement 187 | - Added recipe[zap::yum_repos_d] 188 | 189 | v0.5.0 190 | ------ 191 | ### Improvement 192 | - Added collect and select to the resource 193 | 194 | v0.4.3 195 | ------ 196 | ### Improvement 197 | - Moved @filter.call back 198 | 199 | v0.4.2 200 | ------ 201 | ### Improvement 202 | - Moved @filter.call into iterate 203 | 204 | v0.4.1 205 | ------ 206 | ### Improvement 207 | - Fixed rubocop warning 208 | 209 | v0.4.0 210 | ------ 211 | ### Improvement 212 | - Added klass keyword to DSL which can take a class, 213 | i.e. Chef::Resource::File, or string, 214 | i.e. 'Chef::Resource::YumRepository', or an array of classes or 215 | strings. 216 | 217 | v0.3.0 218 | ------ 219 | ### Improvement 220 | - Added zap_users and zap_groups 221 | 222 | v0.2.0 223 | ------ 224 | ### Improvement 225 | - Added filter for more complex, codified filtering 226 | 227 | v0.1.1 228 | ------ 229 | ### Improvement 230 | - Log at info 231 | 232 | v0.1.0 233 | ------ 234 | ### Minor 235 | - Refactored into an HWRP to allow better code reuse 236 | 237 | v0.0.6 238 | ------ 239 | ### Improvement 240 | - Cleaned up Rubocop warnings 241 | 242 | v0.0.5 243 | ------ 244 | ### Improvement 245 | - Added zap_crontab to zap the specified user's crontab 246 | 247 | v0.0.4 248 | ------ 249 | ### Improvement 250 | - Use ::File.join instead of hardcoding slashes 251 | 252 | v0.0.3 253 | ------ 254 | ### Improvement 255 | - Split zap_directory into two phases, :delay to move it to the end of 256 | the resource list, and :run to do the actual work. 257 | 258 | v0.0.2 259 | ------ 260 | ### Improvement 261 | - Move zap_directory to the end of the resource list. 262 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Please refer to 4 | [https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | zap 2 | === 3 | 4 | Library cookbook for garbage collecting chef controlled resource sets. 5 | 6 | One of the common pitfalls in chef land is the pattern of one deleting a 7 | resource definition from a recipe and the user wondering why the resource still 8 | exists on the system. 9 | 10 | For example, on Monday a cronjob is added: 11 | 12 | ```ruby 13 | cron 'collect stats' do 14 | action :create 15 | minute 0 16 | command '/usr/local/bin/collect-stats | mailto ops@nvwls.com' 17 | end 18 | ``` 19 | 20 | After a few days, the issue is figured out and that cron resource is removed 21 | from the recipe. After uploading the new cookbook, they wonder why they are 22 | still receiving email. 23 | 24 | The issue that chef is great for describing actions. I mean, *action* is part 25 | of the DSL. 26 | 27 | At the 2013 Opscode Communit Summit, Matt Ray and I had a discussion regarding 28 | this issue. The name *authoritative cookbook* was coined. If chef is deploying 29 | files to a .d directory, if there are files in that directory not converged by a 30 | resource, those files should be removed. 31 | 32 | This pattern has been added to https://github.com/Youscribe/sysctl-cookbook 33 | 34 | I presented the zap pattern at ChefConf 2014. You can check out the 35 | video 36 | http://www.youtube.com/watch?v=4-So4AJlBI4&list=PL11cZfNdwNyMmx0msapJfuGsLV43C7XsA&feature=share&index=53 37 | and the slides 38 | https://speakerdeck.com/nvwls/building-authoritative-resource-sets 39 | 40 | Thanks 41 | ====== 42 | 43 | Users and groups support was provided by Sander Botman . 44 | Yum_repository support was provided by Sander van Harmelen 45 | Apt_repository support was provided by Helgi Þormar Þorbjörnsson 46 | 47 | Resource/Provider 48 | ================= 49 | 50 | zap_directory 51 | ------------- 52 | 53 | ## Actions 54 | 55 | - **:delete** - Delete files and symlinks in a directory 56 | 57 | ## Attribute Parameters 58 | 59 | - **pattern** - Pattern of files to match, i.e. `*.conf`, defaults to `*` 60 | - **recursive** - Recurse into subdirectories, defaults to `false` 61 | 62 | ### Examples 63 | 64 | ```ruby 65 | zap_directory '/etc/sysctl.d' do 66 | pattern '*.conf' 67 | end 68 | ``` 69 | 70 | zap_crontab 71 | ----------- 72 | 73 | ## Actions 74 | 75 | - **:delete** - Delete jobs from a user's crontab 76 | 77 | ## Attribute Parameters 78 | 79 | - **pattern** - Pattern of job names match, i.e. `test \#*`, defaults to `*` 80 | 81 | ### Examples 82 | 83 | ```ruby 84 | zap_crontab 'root' do 85 | pattern 'test \#*' 86 | end 87 | ``` 88 | 89 | zap_users 90 | --------- 91 | 92 | Delete users from `/etc/passwd` style files. 93 | `node['zap']['users']['keep']` contains an array of user names to 94 | keep, i.e. `root`. 95 | 96 | ## Actions 97 | 98 | - **:remove** 99 | 100 | ## Example 101 | 102 | ```ruby 103 | zap_users '/etc/passwd' do 104 | # only zap users whose uid is greater than 500 105 | filter { |u| u.uid > 500 } 106 | end 107 | ``` 108 | 109 | zap_groups 110 | ---------- 111 | 112 | Delete groups from `/etc/group` style files. 113 | `node['zap']['groups']['keep']` contains an array of group names to 114 | keep, i.e. `wheel`. 115 | 116 | ## Actions 117 | 118 | - **:remove** 119 | 120 | ## Example 121 | 122 | ```ruby 123 | zap_groups '/etc/group' do 124 | # only zap groups whose gid is greater than 500 125 | filter { |g| g.gid > 500 && g.name != 'nrpe' } 126 | end 127 | ``` 128 | 129 | zap 130 | --- 131 | 132 | This the base HWRP. 133 | 134 | ## Example 135 | 136 | ```ruby 137 | zap '/etc/sysctl.d' do 138 | register :file, :template 139 | collect { Dir.glob("#{base}/*") } 140 | end 141 | ``` 142 | 143 | Recipes 144 | ======= 145 | 146 | zap::apt_repos 147 | -------------- 148 | 149 | Remove extraneous repos from `/etc/apt/sources.list.d` 150 | * `node['zap']['apt_repos']['pattern']` is a glob expression used to restrict the name space, defaults to `'*'` 151 | * `node['zap']['apt_repos']['immediately']` controls whether the zap is run immediately, defaults to `true` 152 | 153 | zap::cron_d 154 | ----------- 155 | 156 | Remove extraneous `/etc/cron.d` entries 157 | * `node['zap']['cron_d']['pattern']` is a glob expression used to restrict the name space, defaults to `'*'` 158 | 159 | zap::init_d 160 | ----------- 161 | 162 | Disable sysv-init services on centos-6 163 | * `node['zap']['init_d']['pattern']` is a glob expression used to restrict the name space, defaults to `'*'` 164 | 165 | zap::iptables_d 166 | --------------- 167 | 168 | Remove `/etc/iptables.d` entries created by the iptables cookbook 169 | * `node['zap']['iptables_d']['pattern']` is a glob expression used to restrict the name space, defaults to `'*'` 170 | 171 | zap::sudoers_d 172 | -------------- 173 | 174 | Remove extraneous `/etc/sudoers.d` entries 175 | * `node['zap']['sudoers_d']['pattern']` is a glob expression used to restrict the name space, defaults to `'*'` 176 | 177 | zap::yum_repos 178 | -------------- 179 | 180 | Remove extraneous repos from `/etc/yum.repos.d` 181 | * `node['zap']['yum_repos']['pattern']` is a glob expression used to restrict the name space, defaults to `'*'` 182 | * `node['zap']['yum_repos']['immediately']` controls whether the zap is run immediately, defaults to `true` 183 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'stove/rake_task' 4 | Stove::RakeTask.new 5 | -------------------------------------------------------------------------------- /TESTING.md: -------------------------------------------------------------------------------- 1 | # Testing 2 | 3 | Please refer to [the community cookbook documentation on testing](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/TESTING.MD). 4 | -------------------------------------------------------------------------------- /attributes/apt_repos.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # 4 | # Cookbook:: zap 5 | # Attributes:: apt_repos 6 | # 7 | # Author:: Joseph J. Nuspl Jr. 8 | # 9 | # Copyright:: 2014-2021, Joseph J. Nuspl Jr. 10 | # 11 | # Licensed under the Apache License, Version 2.0 (the "License"); 12 | # you may not use this file except in compliance with the License. 13 | # You may obtain a copy of the License at 14 | # 15 | # http://www.apache.org/licenses/LICENSE-2.0 16 | # 17 | # Unless required by applicable law or agreed to in writing, software 18 | # distributed under the License is distributed on an "AS IS" BASIS, 19 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | # See the License for the specific language governing permissions and 21 | # limitations under the License. 22 | # 23 | 24 | default['zap']['apt_repos']['pattern'] = '*' 25 | default['zap']['apt_repos']['immediately'] = true 26 | -------------------------------------------------------------------------------- /attributes/cron_d.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # 4 | # Cookbook:: zap 5 | # Attributes:: cron_d 6 | # 7 | # Author:: Joseph J. Nuspl Jr. 8 | # 9 | # Copyright:: 2014-2021, Joseph J. Nuspl Jr. 10 | # 11 | # Licensed under the Apache License, Version 2.0 (the "License"); 12 | # you may not use this file except in compliance with the License. 13 | # You may obtain a copy of the License at 14 | # 15 | # http://www.apache.org/licenses/LICENSE-2.0 16 | # 17 | # Unless required by applicable law or agreed to in writing, software 18 | # distributed under the License is distributed on an "AS IS" BASIS, 19 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | # See the License for the specific language governing permissions and 21 | # limitations under the License. 22 | # 23 | 24 | default['zap']['cron_d']['pattern'] = '*' 25 | -------------------------------------------------------------------------------- /attributes/groups.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # 4 | # Cookbook:: zap 5 | # Attributes:: groups 6 | # 7 | # Author:: Sander Botman. 8 | # 9 | # Copyright:: 2014, Sander Botman. 10 | # Copyright:: 2014-2021, Joseph J. Nuspl Jr. 11 | # 12 | # Licensed under the Apache License, Version 2.0 (the "License"); 13 | # you may not use this file except in compliance with the License. 14 | # You may obtain a copy of the License at 15 | # 16 | # http://www.apache.org/licenses/LICENSE-2.0 17 | # 18 | # Unless required by applicable law or agreed to in writing, software 19 | # distributed under the License is distributed on an "AS IS" BASIS, 20 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | # See the License for the specific language governing permissions and 22 | # limitations under the License. 23 | # 24 | 25 | case node['platform_family'] 26 | when 'debian' 27 | default['zap']['groups']['keep'] = %w( 28 | root 29 | daemon 30 | bin 31 | sys 32 | adm 33 | tty 34 | disk 35 | lp 36 | mail 37 | news 38 | uucp 39 | man 40 | proxy 41 | kmem 42 | dialout 43 | fax 44 | voice 45 | cdrom 46 | floppy 47 | tape 48 | sudo 49 | audio 50 | dip 51 | www-data 52 | backup 53 | operator 54 | list 55 | irc 56 | src 57 | gnats 58 | shadow 59 | utmp 60 | video 61 | sasl 62 | plugdev 63 | staff 64 | games 65 | users 66 | nogroup 67 | libuuid 68 | crontab 69 | vboxsf 70 | fuse 71 | avahi-autoipd 72 | scanner 73 | messagebus 74 | colord 75 | lpadmin 76 | ssl-cert 77 | bluetooth 78 | utempter 79 | netdev 80 | Debian-exim 81 | mlocate 82 | ssh 83 | avahi 84 | pulse 85 | pulse-access 86 | rtkit 87 | saned 88 | Debian-gdm 89 | systemd-coredump 90 | systemd-timesync 91 | ) 92 | 93 | when 'rhel', 'fedora' 94 | default['zap']['groups']['keep'] = %w( 95 | root 96 | bin 97 | daemon 98 | sys 99 | adm 100 | tty 101 | disk 102 | lp 103 | mem 104 | kmem 105 | wheel 106 | mail 107 | uucp 108 | man 109 | games 110 | gopher 111 | video 112 | dip 113 | ftp 114 | lock 115 | audio 116 | nobody 117 | users 118 | utmp 119 | utempter 120 | floppy 121 | vcsa 122 | rpc 123 | cdrom 124 | tape 125 | dialout 126 | ntp 127 | saslauth 128 | postdrop 129 | postfix 130 | rpcuser 131 | nfsnobody 132 | sshd 133 | slocate 134 | haldaemon 135 | dbus 136 | render 137 | systemd-coredump 138 | systemd-timesync 139 | ) 140 | 141 | when 'freebsd' 142 | default['zap']['groups']['keep'] = %w( 143 | root 144 | ) 145 | 146 | else 147 | default['zap']['groups']['keep'] = %w( 148 | root 149 | ) 150 | end 151 | -------------------------------------------------------------------------------- /attributes/init_d.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # 4 | # Cookbook:: zap 5 | # Attributes:: init_d 6 | # 7 | # Author:: Joseph J. Nuspl Jr. 8 | # 9 | # Copyright:: 2014-2021, Joseph J. Nuspl Jr. 10 | # 11 | # Licensed under the Apache License, Version 2.0 (the "License"); 12 | # you may not use this file except in compliance with the License. 13 | # You may obtain a copy of the License at 14 | # 15 | # http://www.apache.org/licenses/LICENSE-2.0 16 | # 17 | # Unless required by applicable law or agreed to in writing, software 18 | # distributed under the License is distributed on an "AS IS" BASIS, 19 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | # See the License for the specific language governing permissions and 21 | # limitations under the License. 22 | # 23 | 24 | default['zap']['init_d']['pattern'] = '*' 25 | -------------------------------------------------------------------------------- /attributes/iptables_d.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # 4 | # Cookbook:: zap 5 | # Attributes:: iptables_d 6 | # 7 | # Author:: Joseph J. Nuspl Jr. 8 | # 9 | # Copyright:: 2014-2021, Joseph J. Nuspl Jr. 10 | # 11 | # Licensed under the Apache License, Version 2.0 (the "License"); 12 | # you may not use this file except in compliance with the License. 13 | # You may obtain a copy of the License at 14 | # 15 | # http://www.apache.org/licenses/LICENSE-2.0 16 | # 17 | # Unless required by applicable law or agreed to in writing, software 18 | # distributed under the License is distributed on an "AS IS" BASIS, 19 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | # See the License for the specific language governing permissions and 21 | # limitations under the License. 22 | # 23 | 24 | default['zap']['iptables_d']['pattern'] = '*' 25 | -------------------------------------------------------------------------------- /attributes/sudoers_d.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # 4 | # Cookbook:: zap 5 | # Attributes:: sudoers_d 6 | # 7 | # Author:: Joseph J. Nuspl Jr. 8 | # 9 | # Copyright:: 2014-2021, Joseph J. Nuspl Jr. 10 | # 11 | # Licensed under the Apache License, Version 2.0 (the "License"); 12 | # you may not use this file except in compliance with the License. 13 | # You may obtain a copy of the License at 14 | # 15 | # http://www.apache.org/licenses/LICENSE-2.0 16 | # 17 | # Unless required by applicable law or agreed to in writing, software 18 | # distributed under the License is distributed on an "AS IS" BASIS, 19 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | # See the License for the specific language governing permissions and 21 | # limitations under the License. 22 | # 23 | 24 | default['zap']['sudoers_d']['pattern'] = '*' 25 | -------------------------------------------------------------------------------- /attributes/users.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # 4 | # Cookbook:: zap 5 | # Attributes:: users 6 | # 7 | # Author:: Sander Botman. 8 | # 9 | # Copyright:: 2014, Sander Botman. 10 | # Copyright:: 2014-2021, Joseph J. Nuspl Jr. 11 | # 12 | # Licensed under the Apache License, Version 2.0 (the "License"); 13 | # you may not use this file except in compliance with the License. 14 | # You may obtain a copy of the License at 15 | # 16 | # http://www.apache.org/licenses/LICENSE-2.0 17 | # 18 | # Unless required by applicable law or agreed to in writing, software 19 | # distributed under the License is distributed on an "AS IS" BASIS, 20 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | # See the License for the specific language governing permissions and 22 | # limitations under the License. 23 | # 24 | 25 | case node['platform_family'] 26 | when 'debian' 27 | default['zap']['users']['keep'] = %w( 28 | root 29 | daemon 30 | bin 31 | sys 32 | sync 33 | games 34 | man 35 | lp 36 | mail 37 | news 38 | uucp 39 | proxy 40 | www-data 41 | backup 42 | list 43 | irc 44 | gnats 45 | nobody 46 | libuuid 47 | avahi-autoipd 48 | messagebus 49 | colord 50 | usbmux 51 | Debian-exim 52 | statd 53 | avahi 54 | pulse 55 | speech-dispatcher 56 | hplip 57 | sshd 58 | rtkit 59 | saned 60 | Debian-gdm 61 | ) 62 | 63 | when 'rhel', 'fedora' 64 | default['zap']['users']['keep'] = %w( 65 | root 66 | bin 67 | daemon 68 | adm 69 | lp 70 | sync 71 | shutdown 72 | halt 73 | mail 74 | uucp 75 | operator 76 | games 77 | gopher 78 | ftp 79 | nobody 80 | vcsa 81 | rpc 82 | ntp 83 | saslauth 84 | postfix 85 | rpcuser 86 | nfsnobody 87 | sshd 88 | dbus 89 | haldaemon 90 | ) 91 | 92 | when 'freebsd' 93 | default['zap']['users']['keep'] = %w( 94 | root 95 | ) 96 | 97 | else 98 | default['zap']['users']['keep'] = %w( 99 | root 100 | ) 101 | end 102 | -------------------------------------------------------------------------------- /attributes/yum_repos.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # 4 | # Cookbook:: zap 5 | # Attributes:: yum_repos 6 | # 7 | # Author:: Joseph J. Nuspl Jr. 8 | # 9 | # Copyright:: 2014-2021, Joseph J. Nuspl Jr. 10 | # 11 | # Licensed under the Apache License, Version 2.0 (the "License"); 12 | # you may not use this file except in compliance with the License. 13 | # You may obtain a copy of the License at 14 | # 15 | # http://www.apache.org/licenses/LICENSE-2.0 16 | # 17 | # Unless required by applicable law or agreed to in writing, software 18 | # distributed under the License is distributed on an "AS IS" BASIS, 19 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | # See the License for the specific language governing permissions and 21 | # limitations under the License. 22 | # 23 | 24 | default['zap']['yum_repos']['pattern'] = '*' 25 | default['zap']['yum_repos']['immediately'] = true 26 | -------------------------------------------------------------------------------- /chefignore: -------------------------------------------------------------------------------- 1 | */*file 2 | */*file.lock 3 | */chefignore 4 | */spec 5 | */test 6 | -------------------------------------------------------------------------------- /libraries/crontab.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # 4 | # Cookbook:: zap 5 | # HWRP:: crontab 6 | # 7 | # Author:: Joseph J. Nuspl Jr. 8 | # 9 | # Copyright:: 2014-2021 Joseph J. Nuspl Jr. 10 | # 11 | # Licensed under the Apache License, Version 2.0 (the "License"); 12 | # you may not use this file except in compliance with the License. 13 | # You may obtain a copy of the License at 14 | # 15 | # http://www.apache.org/licenses/LICENSE-2.0 16 | # 17 | # Unless required by applicable law or agreed to in writing, software 18 | # distributed under the License is distributed on an "AS IS" BASIS, 19 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | # See the License for the specific language governing permissions and 21 | # limitations under the License. 22 | # 23 | 24 | require_relative 'default' 25 | 26 | if defined?(ChefSpec) # rubocop:disable Chef/Modernize/DefinesChefSpecMatchers 27 | def call_zap_crontab(resource_name) 28 | ChefSpec::Matchers::ResourceMatcher.new(:zap_crontab, :delete, resource_name) 29 | end 30 | end 31 | 32 | # chef 33 | class Chef 34 | # resource 35 | class Resource 36 | # zap_crontab 'USER' 37 | class ZapCrontab < Zap 38 | include ::Chef::Mixin::ShellOut 39 | 40 | provides :zap_crontab 41 | 42 | def initialize(name, run_context = nil) 43 | super 44 | 45 | register :cron do |r| 46 | r.name if r.user == @name 47 | end 48 | 49 | collect do 50 | all = [] 51 | 52 | cmd = shell_out!("crontab -l -u #{@name}") 53 | cmd.stdout.split("\n").each do |line| 54 | if line =~ /^\# Chef Name: (.*)/ 55 | # Ugly hack!!! Need to follow what the cron provider does 56 | all << Regexp.last_match(1) 57 | end 58 | end 59 | 60 | all 61 | end 62 | 63 | purge do |id| 64 | # cannot use build_resource 65 | r = ::Chef::Resource::Cron.new(id, @run_context) 66 | r.action(:delete) 67 | r.user(@name) 68 | r 69 | end 70 | end 71 | end 72 | end 73 | end 74 | -------------------------------------------------------------------------------- /libraries/default.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # 4 | # Cookbook:: zap 5 | # HWRP:: zap 6 | # 7 | # Author:: Joseph J. Nuspl Jr. 8 | # 9 | # Copyright:: 2014-2020, Joseph J. Nuspl Jr. 10 | # 11 | # Licensed under the Apache License, Version 2.0 (the "License"); 12 | # you may not use this file except in compliance with the License. 13 | # You may obtain a copy of the License at 14 | # 15 | # http://www.apache.org/licenses/LICENSE-2.0 16 | # 17 | # Unless required by applicable law or agreed to in writing, software 18 | # distributed under the License is distributed on an "AS IS" BASIS, 19 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | # See the License for the specific language governing permissions and 21 | # limitations under the License. 22 | # 23 | 24 | if defined?(ChefSpec) # rubocop:disable Chef/Modernize/DefinesChefSpecMatchers 25 | def call_zap_delete(resource_name) 26 | ChefSpec::Matchers::ResourceMatcher.new(:zap, :delete, resource_name) 27 | end 28 | 29 | def call_zap_remove(resource_name) 30 | ChefSpec::Matchers::ResourceMatcher.new(:zap, :remove, resource_name) 31 | end 32 | end 33 | 34 | # Chef 35 | class Chef 36 | # resource 37 | class Resource 38 | # zap 39 | class Zap < Chef::Resource 40 | include Chef::DSL::DeclareResource 41 | 42 | provides :zap 43 | default_action :delete 44 | 45 | attr_reader :klass 46 | 47 | property :immediately, [true, false], default: false 48 | property :force, [true, false], default: false 49 | property :pattern, String, default: '*' 50 | 51 | def initialize(name, run_context = nil) 52 | super 53 | 54 | # registered resource names 55 | @klass = {} 56 | @klass.default = lambda { |_| nil } # rubocop:disable Style/Lambda 57 | 58 | # supported features 59 | @supports = [] 60 | 61 | @delayed = false 62 | 63 | @filter = lambda { |_| true } # rubocop:disable Style/Lambda 64 | 65 | # Set the provider 66 | @provider = Provider::Zap 67 | 68 | # Set default actions and allowed actions 69 | @allowed_actions.push(:delete, :remove, :disable) 70 | end 71 | 72 | def filter(&block) 73 | if !block.nil? && !@supports.include?(:filter) 74 | Chef::Log.warn "#{@resource_name} does not support filter" 75 | end 76 | set_or_return(:filter, block, kind_of: Proc) # rubocop:disable Chef/Modernize/SetOrReturnInResources 77 | end 78 | 79 | def collect(&block) 80 | set_or_return(:collect, block, kind_of: Proc) # rubocop:disable Chef/Modernize/SetOrReturnInResources 81 | end 82 | 83 | def purge(&block) 84 | set_or_return(:purge, block, kind_of: Proc) # rubocop:disable Chef/Modernize/SetOrReturnInResources 85 | end 86 | 87 | def delayed(arg = nil) 88 | if arg == true 89 | @delayed = true 90 | elsif @delayed == false && immediately == false 91 | r = dup 92 | r.delayed(true) 93 | @run_context.resource_collection.all_resources << r 94 | end 95 | @delayed 96 | end 97 | 98 | def register(*multiple, &block) 99 | multiple.each do |name| 100 | cb = block 101 | 102 | if block.nil? 103 | obj = Chef::ResourceResolver.resolve(name, node: @run_context.node).new('') 104 | 105 | if obj.respond_to?(:path) # rubocop:disable Style/ConditionalAssignment 106 | cb = lambda { |r| r.path } # rubocop:disable Style/Lambda 107 | else 108 | cb = lambda { |r| r.name } # rubocop:disable Style/Lambda 109 | end 110 | end 111 | 112 | @klass[name] = cb 113 | end 114 | end 115 | end 116 | end 117 | 118 | # provider 119 | class Provider 120 | # zap 121 | class Zap < Chef::Provider 122 | def load_current_resource 123 | @name = @new_resource.name 124 | @klass = @new_resource.klass 125 | @pattern = @new_resource.pattern 126 | @filter = @new_resource.filter 127 | @collect = @new_resource.collect || method(:collect) 128 | @purge = @new_resource.purge || method(:purge) 129 | end 130 | 131 | if Chef::VERSION.to_i < 13 132 | def whyrun_supported? # rubocop:disable Chef/Modernize/WhyRunSupportedTrue 133 | true 134 | end 135 | end 136 | 137 | def action_delete 138 | iterate 139 | end 140 | 141 | def action_disable 142 | iterate 143 | end 144 | 145 | def action_remove 146 | iterate 147 | end 148 | 149 | private 150 | 151 | def collect 152 | raise ":collect undefined for #{@new_resource}" 153 | end 154 | 155 | # collect all existing resources 156 | # keep only those that match the specified pattern 157 | def existing 158 | @existing ||= begin 159 | @collect 160 | .call 161 | .select { |name| ::File.fnmatch(@pattern, name) } 162 | end 163 | end 164 | 165 | def desired 166 | @desired ||= begin 167 | @run_context 168 | .resource_collection 169 | .map { |r| @klass[r.resource_name].call(r) } 170 | .flatten 171 | .reject(&:nil?) 172 | end 173 | end 174 | 175 | def extraneous 176 | @extraneous ||= existing - desired 177 | end 178 | 179 | def iterate 180 | return if override_runlist? 181 | return unless @new_resource.delayed || @new_resource.immediately 182 | return if extraneous.empty? 183 | 184 | converge_by "#{@new_resource.resource_name} #{@new_resource.name}" do 185 | extraneous.each do |id| 186 | r = @purge.call(id) 187 | @run_context.resource_collection << r 188 | end 189 | end 190 | end 191 | 192 | def override_runlist? 193 | return if @run_context.node.override_runlist.empty? 194 | 195 | if @new_resource.force 196 | Chef::Log.warn "Forcing #{@new_resource} during override_runlist" 197 | false 198 | else 199 | Chef::Log.warn "Skipping #{@new_resource} during override_runlist" 200 | true 201 | end 202 | end 203 | 204 | def purge(id) 205 | type = @klass.first[0] 206 | meth = @new_resource.action 207 | build_resource(type, id) do 208 | action meth 209 | end 210 | end 211 | end 212 | end 213 | end 214 | -------------------------------------------------------------------------------- /libraries/directory.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # 4 | # Cookbook:: zap 5 | # HWRP:: directory 6 | # 7 | # Author:: Joseph J. Nuspl Jr. 8 | # 9 | # Copyright:: 2014-2021, Joseph J. Nuspl Jr. 10 | # 11 | # Licensed under the Apache License, Version 2.0 (the "License"); 12 | # you may not use this file except in compliance with the License. 13 | # You may obtain a copy of the License at 14 | # 15 | # http://www.apache.org/licenses/LICENSE-2.0 16 | # 17 | # Unless required by applicable law or agreed to in writing, software 18 | # distributed under the License is distributed on an "AS IS" BASIS, 19 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | # See the License for the specific language governing permissions and 21 | # limitations under the License. 22 | # 23 | 24 | require_relative 'default' 25 | 26 | # chef 27 | class Chef 28 | # resource 29 | class Resource 30 | # zap_directory 'DIR' 31 | class ZapDirectory < Chef::Resource::Zap 32 | provides :zap_directory 33 | 34 | property :recursive, [true, false], default: false 35 | property :path, String 36 | 37 | def initialize(name, run_context = nil) 38 | super 39 | 40 | # Set the provider 41 | @provider = Provider::ZapDirectory 42 | @supports << :filter 43 | 44 | register :file, :cookbook_file, :template, :link 45 | @path = name 46 | end 47 | end 48 | end 49 | 50 | # provider 51 | class Provider 52 | # zap_directory 53 | class ZapDirectory < Chef::Provider::Zap 54 | def collect 55 | walk(@new_resource.path) 56 | end 57 | 58 | private 59 | 60 | def walk(base) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity 61 | all = [] 62 | 63 | dirs = if base =~ /\*/ 64 | ::Dir.glob(base) 65 | else 66 | [base] 67 | end 68 | dirs.each do |dir| 69 | ::Dir.entries(dir).each do |name| 70 | next if %w(. ..).include?(name) 71 | 72 | path = ::File.join(dir, name) 73 | 74 | if ::File.directory?(path) 75 | if @new_resource.recursive 76 | all.concat walk(path) 77 | end 78 | elsif ::File.fnmatch(@new_resource.pattern, path) 79 | all.push path if @filter.call(path) 80 | end 81 | end 82 | end 83 | all 84 | end 85 | 86 | def purge(name) 87 | if ::File.symlink?(name) 88 | build_resource(:link, name) do 89 | action :delete 90 | end 91 | else 92 | build_resource(:file, name) do 93 | action :delete 94 | end 95 | end 96 | end 97 | end 98 | end 99 | end 100 | -------------------------------------------------------------------------------- /libraries/groups.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # 4 | # Cookbook:: zap 5 | # HWRP:: groups 6 | # 7 | # Author:: Sander Botman. 8 | # Author:: Joseph J. Nuspl Jr. 9 | # 10 | # Copyright:: 2014, Sander Botman. 11 | # Copyright:: 2017-2021, Joseph J. Nuspl Jr. 12 | # 13 | # Licensed under the Apache License, Version 2.0 (the "License"); 14 | # you may not use this file except in compliance with the License. 15 | # You may obtain a copy of the License at 16 | # 17 | # http://www.apache.org/licenses/LICENSE-2.0 18 | # 19 | # Unless required by applicable law or agreed to in writing, software 20 | # distributed under the License is distributed on an "AS IS" BASIS, 21 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | # See the License for the specific language governing permissions and 23 | # limitations under the License. 24 | # 25 | 26 | require_relative 'default' 27 | 28 | # chef 29 | class Chef 30 | # resource 31 | class Resource 32 | # zap_groups '/etc/group' 33 | class ZapGroups < Chef::Resource::Zap 34 | provides :zap_groups 35 | 36 | property :path, String, default: '/etc/group' 37 | 38 | def initialize(name, run_context = nil) 39 | super 40 | 41 | @supports << :filter 42 | 43 | register :group do |r| # rubocop:disable Style/SymbolProc 44 | r.group_name 45 | end 46 | 47 | collect do 48 | all = [] 49 | 50 | IO.foreach(path) do |line| 51 | g = Struct::Group.new(*line.chomp.split(':')) 52 | g.gid = g.gid.to_i 53 | 54 | next if node['zap']['groups']['keep'].include?(g.name) 55 | 56 | all << g.name if @filter.call(g) 57 | end 58 | 59 | all 60 | end 61 | 62 | purge do |id| 63 | build_resource(:group, id) do 64 | action :remove 65 | end 66 | end 67 | end 68 | end 69 | end 70 | end 71 | -------------------------------------------------------------------------------- /libraries/users.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # 4 | # Cookbook:: zap 5 | # HWRP:: users 6 | # 7 | # Author:: Sander Botman. 8 | # Author:: Joseph J. Nuspl Jr. 9 | # 10 | # Copyright:: 2014, Sander Botman. 11 | # Copyright:: 2017-2021, Joseph J. Nuspl Jr. 12 | # 13 | # Licensed under the Apache License, Version 2.0 (the "License"); 14 | # you may not use this file except in compliance with the License. 15 | # You may obtain a copy of the License at 16 | # 17 | # http://www.apache.org/licenses/LICENSE-2.0 18 | # 19 | # Unless required by applicable law or agreed to in writing, software 20 | # distributed under the License is distributed on an "AS IS" BASIS, 21 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | # See the License for the specific language governing permissions and 23 | # limitations under the License. 24 | # 25 | 26 | require_relative 'default' 27 | 28 | # chef 29 | class Chef 30 | # resource 31 | class Resource 32 | # zap_users '/etc/passwd' 33 | class ZapUsers < Chef::Resource::Zap 34 | provides :zap_users 35 | 36 | property :path, String, default: '/etc/passwd' 37 | 38 | def initialize(name, run_context = nil) 39 | super 40 | 41 | @supports << :filter 42 | 43 | register :user, :linux_user do |r| # rubocop:disable Style/SymbolProc 44 | r.username 45 | end 46 | 47 | collect do 48 | all = [] 49 | 50 | IO.foreach(path) do |line| 51 | u = Struct::Passwd.new(*line.chomp.split(':')) 52 | u.uid = u.uid.to_i 53 | u.gid = u.gid.to_i 54 | 55 | next if node['zap']['users']['keep'].include?(u.name) 56 | 57 | all << u.name if @filter.call(u) 58 | end 59 | 60 | all 61 | end 62 | 63 | purge do |id| 64 | build_resource(:user, id) do 65 | action :remove 66 | end 67 | end 68 | end 69 | end 70 | end 71 | end 72 | -------------------------------------------------------------------------------- /metadata.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | name 'zap' 4 | maintainer 'Joseph J. Nuspl Jr.' 5 | maintainer_email 'nuspl@nvwls.com' 6 | license 'Apache-2.0' 7 | description 'Provides HWRPs for creating authoritative resources' 8 | version '2.3.0' 9 | 10 | %w(amazon centos fedora oracle redhat scientific).each do |os| 11 | supports os 12 | end 13 | 14 | %w(debian ubuntu freebsd windows).each do |os| 15 | supports os 16 | end 17 | 18 | source_url 'https://github.com/nvwls/zap' 19 | issues_url 'https://github.com/nvwls/zap/issues' 20 | 21 | chef_version '>= 12.1' 22 | -------------------------------------------------------------------------------- /recipes/apt_repos.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # 4 | # Cookbook:: zap 5 | # Recipe:: apt_repos 6 | # 7 | # Author:: Joseph J. Nuspl Jr. 8 | # 9 | # Copyright:: 2017-2021, Joseph J. Nuspl Jr. 10 | # 11 | # Licensed under the Apache License, Version 2.0 (the "License"); 12 | # you may not use this file except in compliance with the License. 13 | # You may obtain a copy of the License at 14 | # 15 | # http://www.apache.org/licenses/LICENSE-2.0 16 | # 17 | # Unless required by applicable law or agreed to in writing, software 18 | # distributed under the License is distributed on an "AS IS" BASIS, 19 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | # See the License for the specific language governing permissions and 21 | # limitations under the License. 22 | # 23 | 24 | zap 'apt_repos' do 25 | action :remove 26 | 27 | register :apt_repository 28 | 29 | immediately node['zap']['apt_repos']['immediately'] 30 | 31 | collect do 32 | ::Dir 33 | .glob("/etc/apt/sources.list.d/#{node['zap']['apt_repos']['pattern']}.list") 34 | .map { |path| ::File.basename(path, '.list') } 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /recipes/cron_d.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # 4 | # Cookbook:: zap 5 | # Recipe:: cron_d 6 | # 7 | # Author:: Joseph J. Nuspl Jr. 8 | # 9 | # Copyright:: 2017-2021, Joseph J. Nuspl Jr. 10 | # 11 | # Licensed under the Apache License, Version 2.0 (the "License"); 12 | # you may not use this file except in compliance with the License. 13 | # You may obtain a copy of the License at 14 | # 15 | # http://www.apache.org/licenses/LICENSE-2.0 16 | # 17 | # Unless required by applicable law or agreed to in writing, software 18 | # distributed under the License is distributed on an "AS IS" BASIS, 19 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | # See the License for the specific language governing permissions and 21 | # limitations under the License. 22 | # 23 | 24 | zap 'cron_d' do 25 | register :cron_d do |r| 26 | # sanitized_name 27 | r.name.tr('.', '-') 28 | end 29 | 30 | collect do 31 | ::Dir 32 | .glob("/etc/cron.d/#{node['zap']['cron_d']['pattern']}") 33 | .map { |path| ::File.basename(path) } 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /recipes/init_d.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # 4 | # Cookbook:: zap 5 | # Recipe:: init_d 6 | # 7 | # Author:: Joseph J. Nuspl Jr. 8 | # 9 | # Copyright:: 2017-2021, Joseph J. Nuspl Jr. 10 | # 11 | # Licensed under the Apache License, Version 2.0 (the "License"); 12 | # you may not use this file except in compliance with the License. 13 | # You may obtain a copy of the License at 14 | # 15 | # http://www.apache.org/licenses/LICENSE-2.0 16 | # 17 | # Unless required by applicable law or agreed to in writing, software 18 | # distributed under the License is distributed on an "AS IS" BASIS, 19 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | # See the License for the specific language governing permissions and 21 | # limitations under the License. 22 | # 23 | 24 | zap 'init_d' do 25 | register :service do |r| # rubocop:disable Style/SymbolProc 26 | r.service_name 27 | end 28 | 29 | collect do 30 | all = [] 31 | cmd = shell_out!('/sbin/chkconfig --list') 32 | cmd.stdout.split("\n").each do |line| 33 | next if line !~ /^(\S+)\s+0:(on|off)\s/ 34 | 35 | svc = Regexp.last_match(1) 36 | next if line !~ /\s\d:on\s/ 37 | next unless File.fnmatch(node['zap']['init_d']['pattern'], svc) 38 | 39 | all << svc 40 | end 41 | all 42 | end 43 | 44 | purge do |svc| 45 | build_resource(:execute, "Disable #{svc}") do 46 | action :run 47 | command "chkconfig --level 0123456 #{svc} off" 48 | end 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /recipes/iptables_d.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # 4 | # Cookbook:: zap 5 | # Recipe:: iptables_d 6 | # < 7 | # Used in connection with iptables < 5 8 | # > 9 | # Author:: Joseph J. Nuspl Jr. 10 | # 11 | # Copyright:: 2017-2021, Joseph J. Nuspl Jr. 12 | # 13 | # Licensed under the Apache License, Version 2.0 (the "License"); 14 | # you may not use this file except in compliance with the License. 15 | # You may obtain a copy of the License at 16 | # 17 | # http://www.apache.org/licenses/LICENSE-2.0 18 | # 19 | # Unless required by applicable law or agreed to in writing, software 20 | # distributed under the License is distributed on an "AS IS" BASIS, 21 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | # See the License for the specific language governing permissions and 23 | # limitations under the License. 24 | # 25 | 26 | zap 'iptables_d' do 27 | action :disable 28 | 29 | register :iptables_rule 30 | 31 | collect do 32 | ::Dir 33 | .glob("/etc/iptables.d/#{node['zap']['iptables_d']['pattern']}") 34 | .map { |path| ::File.basename(path) } 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /recipes/sudoers_d.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # 4 | # Cookbook:: zap 5 | # Recipe:: sudoers_d 6 | # 7 | # Used in conjunctions with the sudo cookbook, zap /etc/sudoers.d files. 8 | # 9 | # Author:: Joseph J. Nuspl Jr. 10 | # 11 | # Copyright:: 2017-2021, Joseph J. Nuspl Jr. 12 | # 13 | # Licensed under the Apache License, Version 2.0 (the "License"); 14 | # you may not use this file except in compliance with the License. 15 | # You may obtain a copy of the License at 16 | # 17 | # http://www.apache.org/licenses/LICENSE-2.0 18 | # 19 | # Unless required by applicable law or agreed to in writing, software 20 | # distributed under the License is distributed on an "AS IS" BASIS, 21 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | # See the License for the specific language governing permissions and 23 | # limitations under the License. 24 | # 25 | 26 | if ENV['TEST_KITCHEN'] 27 | # Don't zap the vagrant sudoers file 28 | sudo 'vagrant' do 29 | action :nothing 30 | end 31 | end 32 | 33 | zap_directory '/etc/sudoers.d' do 34 | pattern node['zap']['sudoers_d']['pattern'] 35 | 36 | register :sudo do |r| 37 | # sudo_filename 38 | "/etc/sudoers.d/#{r.name.gsub(/[\.~]/, '__')}" 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /recipes/yum_repos.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # 4 | # Cookbook:: zap 5 | # Recipe:: yum_repos 6 | # 7 | # Author:: Joseph J. Nuspl Jr. 8 | # 9 | # Copyright:: 2017-2021, Joseph J. Nuspl Jr. 10 | # 11 | # Licensed under the Apache License, Version 2.0 (the "License"); 12 | # you may not use this file except in compliance with the License. 13 | # You may obtain a copy of the License at 14 | # 15 | # http://www.apache.org/licenses/LICENSE-2.0 16 | # 17 | # Unless required by applicable law or agreed to in writing, software 18 | # distributed under the License is distributed on an "AS IS" BASIS, 19 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | # See the License for the specific language governing permissions and 21 | # limitations under the License. 22 | # 23 | 24 | zap 'yum_repos' do 25 | register :yum_repository 26 | 27 | immediately node['zap']['yum_repos']['immediately'] 28 | 29 | collect do 30 | ::Dir 31 | .glob("/etc/yum.repos.d/#{node['zap']['yum_repos']['pattern']}.repo") 32 | .map { |path| ::File.basename(path, '.repo') } 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/attributes/default.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | default['directory']['recursive'] = nil 4 | default['directory']['pattern'] = nil 5 | 6 | default['groups']['pattern'] = nil 7 | 8 | default['users']['pattern'] = nil 9 | 10 | default['force_zap_on_override'] = false 11 | 12 | default['obsolete'] = nil 13 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/files/cron: -------------------------------------------------------------------------------- 1 | # Chef Name: a 2 | * * * * * echo a 3 | 4 | # Chef Name: b 5 | * * * * * echo b 6 | 7 | # Chef Name: c 8 | * * * * * echo c 9 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/files/file.txt: -------------------------------------------------------------------------------- 1 | This is a cookbook file 2 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/metadata.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | name 'test' 4 | version '0.0.0' 5 | 6 | depends 'zap' 7 | depends 'cron' 8 | depends 'iptables', '~> 4.2' 9 | depends 'sudo' 10 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/apt_repos.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | execute 'test prep' do 4 | command <<-COMMAND 5 | cat >/etc/apt/sources.list.d/dummy.list <<-EOF 6 | deb [trusted=yes] "https://dummy.net/stable-apt" wheezy main 7 | EOF 8 | COMMAND 9 | end 10 | 11 | include_recipe 'zap::apt_repos' 12 | 13 | apt_repository 'chef-stable' do 14 | uri 'https://packages.chef.io/stable-apt' 15 | components ['main'] 16 | trusted true 17 | cache_rebuild false 18 | end 19 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/cron.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | cookbook_file '/tmp/cron' 4 | 5 | execute 'test prep' do 6 | command <<-COMMAND 7 | cat >/tmp/empty /dev/null 6 | groupadd larry &> /dev/null 7 | groupadd curly &> /dev/null 8 | COMMAND 9 | end 10 | 11 | group 'moe' 12 | 13 | group 'input' do 14 | action :nothing 15 | end 16 | 17 | group 'vagrant' do 18 | action :nothing 19 | end 20 | 21 | zap_groups '/etc/group' do 22 | pattern node['groups']['pattern'] if node['groups']['pattern'] 23 | filter do |g| 24 | g.gid >= 500 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/init_d.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | execute 'test prep' do 4 | command <<-COMMAND 5 | chkconfig postfix on &>/dev/null 6 | chkconfig --level 4 rsyslog on &>/dev/null 7 | COMMAND 8 | end 9 | 10 | service 'crond' do 11 | action :enable 12 | end 13 | 14 | service 'iptables' do 15 | action :nothing 16 | end 17 | 18 | service 'netfs' do 19 | action :nothing 20 | end 21 | 22 | service 'network' do 23 | action :nothing 24 | end 25 | 26 | include_recipe 'zap::init_d' 27 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/iptables_d.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | include_recipe 'iptables::default' 4 | 5 | if node['platform_version'].to_i == 6 6 | edit_resource!(:package, 'iptables') do 7 | package_name %w(iptables iptables-ipv6) 8 | end 9 | end 10 | 11 | execute 'test setup' do 12 | command <<-COMMAND 13 | echo '-A FWR -p tcp -m tcp --dport 22 -j ACCEPT' >/etc/iptables.d/ssh 14 | COMMAND 15 | end 16 | 17 | iptables_rule 'http_8080' do 18 | action :enable 19 | lines <<-LINES 20 | -A FWR -p tcp -m tcp --dport 8080 -j ACCEPT 21 | LINES 22 | end 23 | 24 | include_recipe 'zap::iptables_d' 25 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/notifies.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | execute 'prep' do 4 | command <<-COMMAND 5 | rm -f /tmp/notifies 6 | rm -f /tmp/subscribes 7 | mkdir -p /etc/conf.d 8 | COMMAND 9 | end 10 | 11 | execute 'touch /etc/conf.d/obsolete' do 12 | only_if { node['obsolete'] } 13 | end 14 | 15 | file '/tmp/notifies' do 16 | action :nothing 17 | end 18 | 19 | zap_directory '/etc/conf.d' do 20 | notifies :touch, 'file[/tmp/notifies]' 21 | end 22 | 23 | file '/tmp/subscribes' do 24 | action :nothing 25 | subscribes :touch, 'zap_directory[/etc/conf.d]' 26 | end 27 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/sudoers_d.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | node.default['authorization']['sudo']['include_sudoers_d'] = true 4 | 5 | include_recipe 'sudo::default' 6 | 7 | execute 'test setup' do 8 | command <<-COMMAND 9 | touch /etc/sudoers.d/obsolete 10 | touch /etc/sudoers.d/foo.bar 11 | touch /etc/sudoers.d/foo_bar 12 | touch /etc/sudoers.d/baz~ 13 | touch /etc/sudoers.d/baz_ 14 | COMMAND 15 | end 16 | 17 | include_recipe 'zap::sudoers_d' 18 | 19 | sudo 'tomcat' do 20 | user '%tomcat' 21 | commands ['/etc/init.d/tomcat restart'] 22 | end 23 | 24 | sudo 'foo.bar' do 25 | user '%wheel' 26 | commands ['/bin/true'] 27 | end 28 | 29 | sudo 'baz~' do 30 | user '%wheel' 31 | commands ['/bin/false'] 32 | end 33 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/users.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | execute 'test prep' do 4 | command <<-COMMAND 5 | useradd -s larry &>/dev/null 6 | useradd curly &>/dev/null 7 | useradd waldo &>/dev/null 8 | COMMAND 9 | end 10 | 11 | user 'moe' 12 | 13 | user 'vagrant' do 14 | action :nothing 15 | end 16 | 17 | zap_users '/etc/passwd' do 18 | pattern node['users']['pattern'] if node['users']['pattern'] 19 | filter do |u| 20 | u.uid >= 500 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/yum_repos.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | execute 'test prep' do 4 | command <<-COMMAND 5 | mkdir -p /etc/yum.repos.d 6 | touch /etc/yum.repos.d/a.repo 7 | COMMAND 8 | end 9 | 10 | include_recipe 'zap::yum_repos' 11 | 12 | yum_repository 'chef-stable' do 13 | description 'Chef Software Inc stable channel' 14 | baseurl 'https://packages.chef.io/stable-yum/el/$releasever/$basearch' 15 | make_cache false 16 | skip_if_unavailable true 17 | end 18 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/templates/source.erb: -------------------------------------------------------------------------------- 1 | This is a template 2 | -------------------------------------------------------------------------------- /test/integration/apt_repos/default.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | describe apt('https://dummy.net/stable-apt') do 4 | it { should_not exist } 5 | end 6 | 7 | describe apt('https://packages.chef.io/stable-apt') do 8 | it { should exist } 9 | end 10 | -------------------------------------------------------------------------------- /test/integration/cron/default.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | describe crontab('root') do 4 | its('commands') { should include 'echo a' } 5 | its('commands') { should_not include 'echo b' } 6 | its('commands') { should include 'echo c' } 7 | end 8 | 9 | describe crontab('nobody') do 10 | its('commands') { should_not include 'echo a' } 11 | its('commands') { should include 'echo b' } 12 | its('commands') { should_not include 'echo c' } 13 | end 14 | 15 | describe crontab('daemon') do 16 | its('commands') { should_not include 'echo a' } 17 | its('commands') { should_not include 'echo b' } 18 | its('commands') { should_not include 'echo c' } 19 | end 20 | -------------------------------------------------------------------------------- /test/integration/cron_d/default.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | describe file('/etc/cron.d/a') do 4 | it { should_not exist } 5 | end 6 | 7 | describe file('/etc/cron.d/b') do 8 | it { should exist } 9 | end 10 | 11 | describe file('/etc/cron.d/c') do 12 | it { should_not exist } 13 | end 14 | 15 | describe file('/etc/cron.d/d') do 16 | it { should exist } 17 | end 18 | -------------------------------------------------------------------------------- /test/integration/directory/default.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | describe file('/etc/conf.d/a') do 4 | it { should_not exist } 5 | end 6 | 7 | describe file('/etc/conf.d/b') do 8 | it { should_not exist } 9 | end 10 | 11 | describe directory('/etc/conf.d/c') do 12 | it { should exist } 13 | end 14 | 15 | describe file('/etc/conf.d/link') do 16 | it { should exist } 17 | end 18 | 19 | describe file('/etc/conf.d/symlink') do 20 | it { should exist } 21 | end 22 | 23 | describe file('/etc/conf.d/file') do 24 | it { should exist } 25 | end 26 | 27 | describe file('/etc/conf.d/cookbook_file') do 28 | it { should exist } 29 | end 30 | 31 | describe file('/etc/conf.d/template') do 32 | it { should exist } 33 | end 34 | 35 | describe directory('/etc/conf.d/dir') do 36 | it { should exist } 37 | end 38 | -------------------------------------------------------------------------------- /test/integration/groups/default.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | describe group('root') do 4 | it { should exist } 5 | end 6 | 7 | describe group('daemon') do 8 | it { should exist } 9 | end 10 | 11 | describe group('input') do 12 | it { should exist } 13 | end 14 | 15 | describe group('larry') do 16 | it { should_not exist } 17 | end 18 | 19 | describe group('moe') do 20 | it { should exist } 21 | end 22 | 23 | describe group('curly') do 24 | it { should_not exist } 25 | end 26 | -------------------------------------------------------------------------------- /test/integration/init_d/default.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | describe sysv_service('crond') do 4 | it { should be_enabled } 5 | end 6 | 7 | describe sysv_service('iptables') do 8 | it { should be_enabled } 9 | end 10 | 11 | describe sysv_service('netfs') do 12 | it { should be_enabled } 13 | end 14 | 15 | describe sysv_service('network') do 16 | it { should be_enabled } 17 | end 18 | 19 | describe sysv_service('postfix') do 20 | it { should_not be_enabled } 21 | end 22 | 23 | describe sysv_service('rsyslog') do 24 | it { should_not be_enabled } 25 | end 26 | -------------------------------------------------------------------------------- /test/integration/iptables_d/default.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | describe file('/etc/iptables.d/ssh') do 4 | it { should_not exist } 5 | end 6 | 7 | describe file('/etc/iptables.d/http_8080') do 8 | it { should exist } 9 | end 10 | -------------------------------------------------------------------------------- /test/integration/notified/default.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | describe file('/tmp/notifies') do 4 | it { should exist } 5 | end 6 | 7 | describe file('/tmp/subscribes') do 8 | it { should exist } 9 | end 10 | -------------------------------------------------------------------------------- /test/integration/sudoers_d/default.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | describe file('/etc/sudoers.d/README') do 4 | it { should exist } 5 | end 6 | 7 | describe file('/etc/sudoers.d/obsolete') do 8 | it { should_not exist } 9 | end 10 | 11 | describe file('/etc/sudoers.d/tomcat') do 12 | it { should exist } 13 | end 14 | 15 | describe file('/etc/sudoers.d/foo__bar') do 16 | it { should exist } 17 | end 18 | 19 | describe file('/etc/sudoers.d/foo.bar') do 20 | it { should_not exist } 21 | end 22 | 23 | describe file('/etc/sudoers.d/foo_bar') do 24 | it { should_not exist } 25 | end 26 | 27 | describe file('/etc/sudoers.d/baz__') do 28 | it { should exist } 29 | end 30 | 31 | describe file('/etc/sudoers.d/baz~') do 32 | it { should_not exist } 33 | end 34 | 35 | describe file('/etc/sudoers.d/baz_') do 36 | it { should_not exist } 37 | end 38 | -------------------------------------------------------------------------------- /test/integration/unnotified/default.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | describe file('/etc/notifies') do 4 | it { should_not exist } 5 | end 6 | 7 | describe file('/etc/subscribes') do 8 | it { should_not exist } 9 | end 10 | -------------------------------------------------------------------------------- /test/integration/users/default.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | describe user('root') do 4 | it { should exist } 5 | end 6 | 7 | describe user('larry') do 8 | it { should_not exist } 9 | end 10 | 11 | describe user('moe') do 12 | it { should exist } 13 | end 14 | 15 | describe user('curly') do 16 | it { should_not exist } 17 | end 18 | -------------------------------------------------------------------------------- /test/integration/yum_repos/default.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | describe yum.repo('a') do 4 | it { should_not exist } 5 | end 6 | 7 | describe yum.repo('chef-stable') do 8 | it { should exist } 9 | end 10 | --------------------------------------------------------------------------------