{"id":14991378,"url":"https://github.com/raphink/puppet-policy","last_synced_at":"2025-04-12T03:31:32.279Z","repository":{"id":11459886,"uuid":"13923168","full_name":"raphink/puppet-policy","owner":"raphink","description":"Your Policy Driven Infrastructure Starter Kit","archived":false,"fork":false,"pushed_at":"2020-05-24T20:57:54.000Z","size":82,"stargazers_count":7,"open_issues_count":0,"forks_count":2,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-25T23:24:20.227Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/raphink.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":["raphink"]}},"created_at":"2013-10-28T10:48:33.000Z","updated_at":"2021-03-16T16:35:17.000Z","dependencies_parsed_at":"2022-09-26T20:31:36.958Z","dependency_job_id":null,"html_url":"https://github.com/raphink/puppet-policy","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raphink%2Fpuppet-policy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raphink%2Fpuppet-policy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raphink%2Fpuppet-policy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raphink%2Fpuppet-policy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/raphink","download_url":"https://codeload.github.com/raphink/puppet-policy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248512680,"owners_count":21116658,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-09-24T14:27:37.235Z","updated_at":"2025-04-12T03:31:31.908Z","avatar_url":"https://github.com/raphink.png","language":"Ruby","funding_links":["https://github.com/sponsors/raphink"],"categories":[],"sub_categories":[],"readme":"# Policy module for Puppet\n\n[![Puppet Forge](http://img.shields.io/puppetforge/v/raphink/policy.svg)](https://forge.puppetlabs.com/raphink/policy)\n[![Build Status](https://travis-ci.org/raphink/puppet-policy.svg?branch=master)](https://travis-ci.org/raphink/puppet-policy)\n[![Coverage Status](https://img.shields.io/coveralls/raphink/puppet-policy.svg)](https://coveralls.io/r/raphink/puppet-policy)\n\n\n**Your Policy Driven Infrastructure Starter Kit**\n\n\n## Requirements\n\nThis module requires the following Ruby gems:\n\n* `rspec`;\n* [`rspec-puppet`](https://github.com/rodjek/rspec-puppet) for catalog tests;\n* [`serverspec`](https://github.com/mizzy/serverspec) (\u0026gt;= 2.0.0) for functional tests.\n\nFor Puppet Enterprise, this means the gems must be installed in PE's vendored\nrubygems environment. This can be accomplished using the `pe_gem` package\nprovider, or manually using `/opt/puppet/bin/gem`.\n\n\n## Installing\n\nThe policy module should be copied to the `modulepath` which generates\ncatalogs for the puppet master. Pluginsync will ensure it is installed at the\nmaster's next puppet run.\n\nNext, routes.yaml must be configured to use the termini of your choice. See the sections below for details of how to configure routes.yaml.\n\n\n## Catalog policies\n\nThis module provides a new Puppet terminus which allows to evaluate rspec tests on the actual compiled catalog.\n\nIn order to use this terminus:\n\n* Run Puppet with `pluginsync` on the Puppet master to copy the indirectors;\n* Set your `$confdir/routes.yaml` to use the terminus:\n\n        master:\n          catalog:\n            terminus: compiler_spec\n* Restart your Puppet master process\n\n### How it works\n\nThe catalog policy compiler, though it replaces the built in compiler, does not compile\ncatalogs on its own. It works by inheriting the built in compiler and replacing\nthe function call that requests a new catalog with the wrapper code. The process\nessentially looks like this:\n\n  When a catalog is requested:\n  1. Call the built in compiler\n  2. Extract all facter data from the compiled catalog\n  3. Pass the catalog to RSpec along with a `facts` hash with all facts\n  4. Call every *_spec.rb file in `$manifestdir/../policy` that are in a directory matching a declared class\n  5. Fail the catalog if any of the tests fail\n\n\nThe `compiler_spec` terminus extends the `compiler` terminus for catalogs. After retrieving the catalog using the `compiler` terminus, it applies rspec tests to it:\n\n* The rspec tests must be located in `:manifestdir/../policy/catalog/class`, in sub-directories by class;\n* Only the directories named after classes declared in the catalog will be tested;\n* `rspec-puppet` matchers are already loaded, so they are available in tests;\n* the catalog is readily available in the tests, along with a `facts` object.\n\nSample output:\n\n    # puppet agent -t\n\n    info: Retrieving plugin\n    Error: Could not retrieve catalog from remote server: Error 400 on SERVER: Catalog failed to pass security policies:\n    -- Failed policy: expected that the catalogue would contain Package[pe-mcollective]\n    -- Failed policy: expected that the catalogue would not contain Service[pe-mcollective]\n    notice: Using cached catalog\n\n### Writing tests\n\nAll files in `$manifestdir/../policy` that end with `_spec.rb` and are located\nin a directory matching a declared class name will be executed by\nthe policy compiler. Any Ruby, RSpec, or rspec-puppet code is valid in these\nfiles.\n\nUnlike traditional rspec-puppet testing, there is no reason to \"stub\" any data,\nsince the catalog is compiled according to the existing environment and facts\nfor a specific agent (the one that requested a catalog). Since facts are not\nbeing stubbed, and since all tests are automatically executed, Ruby conditional\nlogic should be used to isolate tests to specific machine types. For example:\n\n```ruby\n# security_spec.rb\n\ndescribe \"when a catalog is compiled\", :type =\u003e :catalog do\n  if facts['osfamily'] =~ /RedHat/ then\n    it { should contain_class('selinux').with_mode('enforcing') }\n  elsif facts['osfamily'] =~ /Windows/ then\n    it { should contain_exec('shutdown /s /t 01') }\n  end\nend\n```\n\n\n## Server policies\n\nAfter the catalog has been tested and applied, you might want to run functional tests against the machine. This module provides a `rest_spec` terminus for the report indirector which executes rspec tests using the `serverspec` matchers.\n\nIn order to use it:\n\n* The rspec tests must be located in `:vardir/policy/server` (tests can be deployed using the `policy::serverspec` define);\n* `serverspec` matchers are already loaded, so they are available in tests.\n\nTo activate the terminus, you need set it in `$confdir/routes.yaml`:\n\n    agent:\n      report:\n        terminus: rest_spec\n\nThis indirector will automatically generate serverspec tests from the catalog for known resource types, making the catalog self-asserting. Currently, it supports the following resource types:\n\n* Package\n* Service\n* File\n* User\n\nSample output:\n\n    # puppet agent  -t\n    info: Retrieving plugin\n    info: Caching catalog for foo.example.com\n    info: Applying configuration version 'raphink/a2c8e0f [+]'\n    ... Applying changes ...\n    notice: Finished catalog run in 59.19 seconds\n    err: Could not send report: Unit tests failed:\n    FF\n    \n    Failures:\n    \n      1) augeas \n         Failure/Error: it { should be_installed }\n           expected \"augeas\" to be installed\n         # /var/lib/puppet/policy/server/package_spec.rb:2\n         # /var/lib/puppet/lib/puppet/indirector/report/rest_spec.rb:45:in `save'\n    \n      2) /usr/share/augeas/lenses/dist \n         Failure/Error: it { should be_file }\n           expected \"/usr/share/augeas/lenses/dist\" to be file\n         # /var/lib/puppet/policy/server/package_spec.rb:6\n         # /var/lib/puppet/lib/puppet/indirector/report/rest_spec.rb:45:in `save'\n    \n    Finished in 0.06033 seconds\n    2 examples, 2 failures\n    \n    Failed examples:\n    \n    rspec /var/lib/puppet/policy/server/package_spec.rb:2 # augeas \n    rspec /var/lib/puppet/policy/server/package_spec.rb:6 # /usr/share/augeas/lenses/dist \n\n\n### Writing new automatic serverspec plugins\n\nThe `rest_spec` report terminus automatically generates serverspec test files from the Puppet catalog, by mapping Puppet resources to Serverspec resources.\n\nNew plugins need to be distributed using `pluginsync`. They should be placed in the `lib/puppetx/policy/auto_spec` directory.\n\nHere is an example:\n\n```ruby\nPuppetx::Policy::AutoSpec.newspec 'Openldap_database' do |o|\n  should = (o[:ensure] == 'absent') ? 'should_not' : 'should'\n  content = \"  describe command('ldapsearch -LLL -x -b #{o[:suffix]}') do\\n\"\n  content += \"    its(:stdout) { #{should} match /dn: #{o[:suffix]}/ }\\n\"\n  content += \"  end\\n\"\nend\n```\n\nIt also works with defined resource types:\n\n```ruby\nPuppetx::Policy::AutoSpec.newspec 'Apache::Vhost' do |v|\n  should = (p[:ensure] == 'absent') ? 'should_not' : 'should'\n  \"  describe port('#{v[:port]}') do\\n     it { #{should} be_listening }\\n  end\\n\" if v[:port]\nend\n```\n\n\n## Using the MCollective agent\n\nThis module provides an MCollective agent in `files/mcollective/agent`. This agent currently has two actions:\n\n### Documentation\n\n    $ mco plugin doc spec\n    RSpec tests\n    ===========\n    \n    RSpec tests\n    \n          Author: Raphaël Pinson\n         Version: 0.1\n         License: GPLv3\n         Timeout: 60\n       Home Page: \n    \n    ACTIONS:\n    ========\n       check, run\n    \n       check action:\n       -------------\n           Run a check with the serverspec library\n    \n           INPUT:\n               action:\n                  Description:\n                       Prompt: Action to check\n                         Type: string\n                   Validation: ^\\S+$\n                       Length: 50\n\n               type:\n                  Description:\n                       Prompt: Type of resource\n                         Type: string\n                     Optional: false\n                   Validation: ^\\S+$\n                       Length: 50\n    \n               values:\n                  Description:\n                       Prompt: Values to check\n                         Type: string\n                   Validation: ^\\S+$\n                       Length: 100\n    \n    \n           OUTPUT:\n               passed:\n                  Description: Whether the checked passed\n                   Display As: Passed\n    \n       run action:\n       -----------\n           Run Puppet-policy server tests\n    \n           INPUT:\n    \n           OUTPUT:\n               output:\n                  Description: Output of tests\n                   Display As: Output\n    \n               passed:\n                  Description: Whether the tests passed\n                   Display As: Passed\n\n### Examples\n\nUsing the `check` action:\n\n    $ mco rpc spec check type=service action=running values=ssh\n    Discovering hosts using the mc method for 2 second(s) .... 1\n    \n     * [ ============================================================\u003e ] 1 / 1\n    \n    \n    wrk4                                     \n       Passed: true\n\n    \n    Finished processing 1 / 1 hosts in 373.44 ms\n\n\nUsing the `run` action:\n\n    $ mco rpc spec run \n    Discovering hosts using the mc method for 2 second(s) .... 1\n    \n     * [ ============================================================\u003e ] 1 / 1\n    \n    wrk4                                     \n       Output: F\n               \n               Failures:\n               \n                 1) abc \n                    Failure/Error: it { should be_running }\n                      expected \"abc\" to be running\n                    # /var/lib/puppet/policy/server/my_test_spec.rb:3\n                    # /usr/share/mcollective/plugins/mcollective/agent/spec.rb:75:in `run_action'\n               \n               Finished in 0.00926 seconds\n               1 example, 1 failure\n               \n               Failed examples:\n               \n               rspec /var/lib/puppet/policy/server/my_test_spec.rb:3 # abc \n       Passed: false\n\n\n    Finished processing 1 / 1 hosts in 316.46 ms\n\n\n## Contributing\n\nPlease report bugs and feature request using [GitHub issue\ntracker](https://github.com/raphink/puppet-policy/issues).\n\nFor pull requests, it is very much appreciated to check your Puppet manifest\nwith [puppet-lint](https://github.com/raphink/puppet-policy/issues) to follow the recommended Puppet style guidelines from the\n[Puppet Labs style guide](http://docs.puppetlabs.com/guides/style_guide.html).\n\n## License\n\nCopyright (c) 2013-2014 Raphaël Pinson\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n    \n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n    \n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see \u003chttp://www.gnu.org/licenses/\u003e.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fraphink%2Fpuppet-policy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fraphink%2Fpuppet-policy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fraphink%2Fpuppet-policy/lists"}