diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..d77700e --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ +# editorconfig.org + +# MANAGED BY MODULESYNC + +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 2 +tab_width = 2 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..f28c97d --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,77 @@ +name: CI + +on: + - pull_request + - push + +jobs: + setup_matrix: + name: 'Setup Test Matrix' + runs-on: ubuntu-latest + timeout-minutes: 40 + outputs: + beaker_setfiles: ${{ steps.get-outputs.outputs.beaker_setfiles }} + puppet_major_versions: ${{ steps.get-outputs.outputs.puppet_major_versions }} + puppet_unit_test_matrix: ${{ steps.get-outputs.outputs.puppet_unit_test_matrix }} + env: + BUNDLE_WITHOUT: development:release + steps: + - uses: actions/checkout@v2 + - name: Setup ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '2.7' + bundler-cache: true + - name: Run rake validate + run: bundle exec rake validate + - name: Run rake rubocop + run: bundle exec rake rubocop + - name: Setup Test Matrix + id: get-outputs + run: bundle exec metadata2gha --use-fqdn --pidfile-workaround false + + unit: + needs: setup_matrix + runs-on: ubuntu-latest + timeout-minutes: 40 + strategy: + fail-fast: false + matrix: + include: ${{fromJson(needs.setup_matrix.outputs.puppet_unit_test_matrix)}} + env: + BUNDLE_WITHOUT: development:system_tests:release + PUPPET_VERSION: "~> ${{ matrix.puppet }}.0" + name: Puppet ${{ matrix.puppet }} (Ruby ${{ matrix.ruby }}) + steps: + - uses: actions/checkout@v2 + - name: Setup ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + bundler-cache: true + - name: Run tests + run: bundle exec rake + + acceptance: + needs: setup_matrix + runs-on: ubuntu-latest + env: + BUNDLE_WITHOUT: development:test:release + strategy: + fail-fast: false + matrix: + setfile: ${{fromJson(needs.setup_matrix.outputs.beaker_setfiles)}} + puppet: ${{fromJson(needs.setup_matrix.outputs.puppet_major_versions)}} + name: ${{ matrix.puppet.name }} - ${{ matrix.setfile.name }} + steps: + - uses: actions/checkout@v2 + - name: Setup ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '2.7' + bundler-cache: true + - name: Run tests + run: bundle exec rake beaker + env: + BEAKER_PUPPET_COLLECTION: ${{ matrix.puppet.collection }} + BEAKER_setfile: ${{ matrix.setfile.value }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..68b8528 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,29 @@ +name: Release + +on: + push: + tags: + - '*' + +env: + BUNDLE_WITHOUT: development:test:system_tests + +jobs: + deploy: + name: 'deploy to forge' + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - name: Setup Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '2.7' + bundler-cache: true + - name: Build and Deploy + env: + # Configure secrets here: + # https://docs.github.com/en/free-pro-team@latest/actions/reference/encrypted-secrets + BLACKSMITH_FORGE_USERNAME: '${{ secrets.PUPPET_FORGE_USERNAME }}' + BLACKSMITH_FORGE_API_KEY: '${{ secrets.PUPPET_FORGE_API_KEY }}' + run: bundle exec rake module:push diff --git a/.gitignore b/.gitignore index 5caea85..e9b3cf4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,13 +1,20 @@ +pkg/ +Gemfile.lock +Gemfile.local +vendor/ +.vendor/ +spec/fixtures/manifests/ +spec/fixtures/modules/ +.vagrant/ +.bundle/ +.ruby-version +coverage/ +log/ +.idea/ +.dependencies/ +.librarian/ +Puppetfile.lock +*.iml .*.sw? -/pkg -/spec/fixtures/manifests -/spec/fixtures/modules -/.rspec_system -/.vagrant -/.bundle -/vendor -/Gemfile.lock -/junit -/log -.yardoc -coverage +.yardoc/ +Guardfile diff --git a/.msync.yml b/.msync.yml new file mode 100644 index 0000000..57ff503 --- /dev/null +++ b/.msync.yml @@ -0,0 +1,2 @@ +--- +modulesync_config_version: '4.1.0' diff --git a/.overcommit.yml b/.overcommit.yml new file mode 100644 index 0000000..0af0fdc --- /dev/null +++ b/.overcommit.yml @@ -0,0 +1,64 @@ +# Managed by https://github.com/voxpupuli/modulesync_configs +# +# Hooks are only enabled if you take action. +# +# To enable the hooks run: +# +# ``` +# bundle exec overcommit --install +# # ensure .overcommit.yml does not harm to you and then +# bundle exec overcommit --sign +# ``` +# +# (it will manage the .git/hooks directory): +# +# Examples howto skip a test for a commit or push: +# +# ``` +# SKIP=RuboCop git commit +# SKIP=PuppetLint git commit +# SKIP=RakeTask git push +# ``` +# +# Don't invoke overcommit at all: +# +# ``` +# OVERCOMMIT_DISABLE=1 git commit +# ``` +# +# Read more about overcommit: https://github.com/brigade/overcommit +# +# To manage this config yourself in your module add +# +# ``` +# .overcommit.yml: +# unmanaged: true +# ``` +# +# to your modules .sync.yml config +--- +PreCommit: + RuboCop: + enabled: true + description: 'Runs rubocop on modified files only' + command: ['bundle', 'exec', 'rubocop'] + PuppetLint: + enabled: true + description: 'Runs puppet-lint on modified files only' + command: ['bundle', 'exec', 'puppet-lint'] + YamlSyntax: + enabled: true + JsonSyntax: + enabled: true + TrailingWhitespace: + enabled: true + +PrePush: + RakeTarget: + enabled: true + description: 'Run rake targets' + targets: + - 'validate' + - 'test' + - 'rubocop' + command: ['bundle', 'exec', 'rake'] diff --git a/.pmtignore b/.pmtignore index fb58957..33a8c65 100644 --- a/.pmtignore +++ b/.pmtignore @@ -1,20 +1,34 @@ docs/ pkg/ +Gemfile Gemfile.lock Gemfile.local vendor/ .vendor/ -spec/fixtures/manifests/ -spec/fixtures/modules/ +spec/ +Rakefile .vagrant/ .bundle/ .ruby-version coverage/ log/ .idea/ .dependencies/ +.github/ .librarian/ Puppetfile.lock *.iml +.editorconfig +.fixtures.yml +.gitignore +.msync.yml +.overcommit.yml +.pmtignore +.rspec +.rspec_parallel +.rubocop.yml +.sync.yml .*.sw? .yardoc/ +.yardopts +Dockerfile diff --git a/.rspec b/.rspec new file mode 100644 index 0000000..8c18f1a --- /dev/null +++ b/.rspec @@ -0,0 +1,2 @@ +--format documentation +--color diff --git a/.rspec_parallel b/.rspec_parallel new file mode 100644 index 0000000..e4d136b --- /dev/null +++ b/.rspec_parallel @@ -0,0 +1 @@ +--format progress diff --git a/.rubocop.yml b/.rubocop.yml index 4a63134..198a359 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,511 +1,3 @@ -require: rubocop-rspec -AllCops: - TargetRubyVersion: 2.2 - Include: - - ./**/*.rb - Exclude: - - files/**/* - - vendor/**/* - - .vendor/**/* - - pkg/**/* - - spec/fixtures/**/* - - Gemfile - - Rakefile -Layout/ConditionPosition: - Enabled: true - -Lint/ElseLayout: - Enabled: true - -Lint/UnreachableCode: - Enabled: true - -Lint/UselessComparison: - Enabled: true - -Lint/EnsureReturn: - Enabled: true - -Lint/SuppressedException: - Enabled: true - -Lint/ShadowingOuterLocalVariable: - Enabled: true - -Lint/LiteralInInterpolation: - Enabled: true - -Style/HashSyntax: - Enabled: false - -Style/RedundantReturn: - Enabled: true - -Lint/AmbiguousOperator: - Enabled: true - -Lint/AssignmentInCondition: - Enabled: true - -Layout/SpaceBeforeComment: - Enabled: true - -Style/AndOr: - Enabled: true - -Style/RedundantSelf: - Enabled: true - -# Method length is not necessarily an indicator of code quality -Metrics/MethodLength: - Enabled: false - -# Module length is not necessarily an indicator of code quality -Metrics/ModuleLength: - Enabled: false - -Style/WhileUntilModifier: - Enabled: true - -Lint/AmbiguousRegexpLiteral: - Enabled: true - -Security/Eval: - Enabled: true - -Layout/BlockAlignment: - Enabled: true - -Layout/DefEndAlignment: - Enabled: true - -Layout/EndAlignment: - Enabled: true - -Lint/DeprecatedClassMethods: - Enabled: true - -Lint/Loop: - Enabled: true - -Lint/ParenthesesAsGroupedExpression: - Enabled: true - -Lint/RescueException: - Enabled: true - -Lint/RedundantStringCoercion: - Enabled: true - -Lint/UnusedBlockArgument: - Enabled: true - -Lint/UnusedMethodArgument: - Enabled: true - -Lint/UselessAccessModifier: - Enabled: true - -Lint/UselessAssignment: - Enabled: true - -Lint/Void: - Enabled: true - -Layout/AccessModifierIndentation: - Enabled: true - -Naming/AccessorMethodName: - Enabled: true - -Style/Alias: - Enabled: true - -Layout/ArrayAlignment: - Enabled: true - -Layout/HashAlignment: - Enabled: true - -Layout/ParameterAlignment: - Enabled: true - -Metrics/BlockNesting: - Enabled: true - -Style/AsciiComments: - Enabled: true - -Style/Attr: - Enabled: true - -Style/BracesAroundHashParameters: - Enabled: true - -Style/CaseEquality: - Enabled: true - -Layout/CaseIndentation: - Enabled: true - -Style/CharacterLiteral: - Enabled: true - -Naming/ClassAndModuleCamelCase: - Enabled: true - -Style/ClassAndModuleChildren: - Enabled: false - -Style/ClassCheck: - Enabled: true - -# Class length is not necessarily an indicator of code quality -Metrics/ClassLength: - Enabled: false - -Style/ClassMethods: - Enabled: true - -Style/ClassVars: - Enabled: true - -Style/WhenThen: - Enabled: true - -Style/WordArray: - Enabled: true - -Style/RedundantPercentQ: - Enabled: true - -Layout/Tab: - Enabled: true - -Layout/SpaceBeforeSemicolon: - Enabled: true - -Layout/TrailingEmptyLines: - Enabled: true - -Layout/SpaceInsideBlockBraces: - Enabled: true - -Layout/SpaceInsideHashLiteralBraces: - Enabled: true - -Layout/SpaceInsideParens: - Enabled: true - -Layout/LeadingCommentSpace: - Enabled: true - -Layout/SpaceAfterColon: - Enabled: true - -Layout/SpaceAfterComma: - Enabled: true - -Layout/SpaceAfterMethodName: - Enabled: true - -Layout/SpaceAfterNot: - Enabled: true - -Layout/SpaceAfterSemicolon: - Enabled: true - -Layout/SpaceAroundEqualsInParameterDefault: - Enabled: true - -Layout/SpaceAroundOperators: - Enabled: true - -Layout/SpaceBeforeBlockBraces: - Enabled: true - -Layout/SpaceBeforeComma: - Enabled: true - -Style/CollectionMethods: - Enabled: true - -Layout/CommentIndentation: - Enabled: true - -Style/ColonMethodCall: - Enabled: true - -Style/CommentAnnotation: - Enabled: true - -# 'Complexity' is very relative -Metrics/CyclomaticComplexity: - Enabled: false - -Naming/ConstantName: - Enabled: true - -Style/Documentation: - Enabled: false - -Style/DefWithParentheses: - Enabled: true - -Style/PreferredHashMethods: - Enabled: true - -Layout/DotPosition: - EnforcedStyle: trailing - -Style/DoubleNegation: - Enabled: true - -Style/EachWithObject: - Enabled: true - -Layout/EmptyLineBetweenDefs: - Enabled: true - -Layout/FirstArrayElementIndentation: - Enabled: true - -Layout/FirstHashElementIndentation: - Enabled: true - -Layout/IndentationConsistency: - Enabled: true - -Layout/IndentationWidth: - Enabled: true - -Layout/EmptyLines: - Enabled: true - -Layout/EmptyLinesAroundAccessModifier: - Enabled: true - -Style/EmptyLiteral: - Enabled: true - -# Configuration parameters: AllowURI, URISchemes. -Layout/LineLength: - Enabled: false - -Style/MethodDefParentheses: - Enabled: true - -Style/LineEndConcatenation: - Enabled: true - -Layout/TrailingWhitespace: - Enabled: true - -Style/StringLiterals: - Enabled: true - -Style/TrailingCommaInArguments: - Enabled: true - -Style/TrailingCommaInHashLiteral: - Enabled: true - -Style/TrailingCommaInArrayLiteral: - Enabled: true - -Style/GlobalVars: - Enabled: true - -Style/GuardClause: - Enabled: true - -Style/IfUnlessModifier: - Enabled: true - -Style/MultilineIfThen: - Enabled: true - -Style/NegatedIf: - Enabled: true - -Style/NegatedWhile: - Enabled: true - -Style/Next: - Enabled: true - -Style/SingleLineBlockParams: - Enabled: true - -Style/SingleLineMethods: - Enabled: true - -Style/SpecialGlobalVars: - Enabled: true - -Style/TrivialAccessors: - Enabled: true - -Style/UnlessElse: - Enabled: true - -Style/VariableInterpolation: - Enabled: true - -Naming/VariableName: - Enabled: true - -Style/WhileUntilDo: - Enabled: true - -Style/EvenOdd: - Enabled: true - -Naming/FileName: - Enabled: true - -Style/For: - Enabled: true - -Style/Lambda: - Enabled: true - -Naming/MethodName: - Enabled: true - -Style/MultilineTernaryOperator: - Enabled: true - -Style/NestedTernaryOperator: - Enabled: true - -Style/NilComparison: - Enabled: true - -Style/FormatString: - Enabled: true - -Style/MultilineBlockChain: - Enabled: true - -Style/Semicolon: - Enabled: true - -Style/SignalException: - Enabled: true - -Style/NonNilCheck: - Enabled: true - -Style/Not: - Enabled: true - -Style/NumericLiterals: - Enabled: true - -Style/OneLineConditional: - Enabled: true - -Naming/BinaryOperatorParameterName: - Enabled: true - -Style/ParenthesesAroundCondition: - Enabled: true - -Style/PercentLiteralDelimiters: - Enabled: true - -Style/PerlBackrefs: - Enabled: true - -Naming/PredicateName: - Enabled: true - -Style/RedundantException: - Enabled: true - -Style/SelfAssignment: - Enabled: true - -Style/Proc: - Enabled: true - -Style/RaiseArgs: - Enabled: true - -Style/RedundantBegin: - Enabled: true - -Style/RescueModifier: - Enabled: true - -# based on https://github.com/voxpupuli/modulesync_config/issues/168 -Style/RegexpLiteral: - EnforcedStyle: percent_r - Enabled: true - -Lint/UnderscorePrefixedVariableName: - Enabled: true - -Metrics/ParameterLists: - Enabled: false - -Lint/RequireParentheses: - Enabled: true - -Layout/SpaceBeforeFirstArg: - Enabled: true - -Style/ModuleFunction: - Enabled: true - -Lint/Debugger: - Enabled: true - -Style/IfWithSemicolon: - Enabled: true - -Style/Encoding: - Enabled: true - -Style/BlockDelimiters: - Enabled: true - -Style/FormatStringToken: - Enabled: false - -Layout/MultilineBlockLayout: - Enabled: true - -# 'Complexity' is very relative -Metrics/AbcSize: - Enabled: False - -Metrics/BlockLength: - Enabled: False - -# 'Complexity' is very relative -Metrics/PerceivedComplexity: - Enabled: False - -Layout/ClosingParenthesisIndentation: - Enabled: false - -# RSpec - -# We don't use rspec in this way -RSpec/DescribeClass: - Enabled: False - -# Example length is not necessarily an indicator of code quality -RSpec/ExampleLength: - Enabled: False - -RSpec/NestedGroups: - Max: 4 - -RSpec/MultipleExpectations: - Max: 2 - -RSpec/NamedSubject: - Enabled: false +--- +inherit_gem: + voxpupuli-test: rubocop.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index ebcdc21..0000000 --- a/.travis.yml +++ /dev/null @@ -1,42 +0,0 @@ -sudo: false -language: ruby -cache: bundler -bundler_args: "--without system_tests development" -before_install: -- bundle -v -- rm Gemfile.lock || true -- gem update --system -- gem update bundler -- gem --version -- bundle -v -script: -- bundle exec rake $CHECK -matrix: - fast_finish: true - include: - - rvm: 2.3.1 - env: PUPPET_VERSION="~> 4.0" STRICT_VARIABLES="yes" CHECK=test - - rvm: 2.3.1 - env: PUPPET_VERSION="~> 4.0" STRICT_VARIABLES="yes" CHECK=rubocop - - rvm: 2.3.1 - env: PUPPET_VERSION="~> 4.0" STRICT_VARIABLES="yes" CHECK=build FORGEDEPLOY=true - - rvm: 2.3.1 - env: PUPPET_VERSION="~> 5.0" STRICT_VARIABLES="yes" CHECK=test - - rvm: 2.3.1 - env: PUPPET_VERSION="~> 5.0" STRICT_VARIABLES="yes" CHECK=rubocop - - rvm: 2.5.3 - env: PUPPET_VERSION="~> 6.1" STRICT_VARIABLES="yes" CHECK=test - - rvm: 2.5.3 - env: PUPPET_VERSION="~> 6.1" STRICT_VARIABLES="yes" CHECK=rubocop -notifications: - email: false -deploy: - provider: puppetforge - user: saz - password: - secure: KREyzEFK9Xa72gtqYv2iI1AScrM9eh9fwZgYz/83uH/spHAxlgx2K4ISjiM8WN4drrBXhZ+JgYRsIGE0TGHW1p35P1P0loNniwhKn0ghU6wEP80t0c/FP6G+qYnBwFbkDMOumtxJ/LB73zXxwDdxBPeATLwzz3cPLUYel6PeqI8= - on: - tags: true - all_branches: true - rvm: 2.3.1 - condition: "$FORGEDEPLOY = true" diff --git a/.yardopts b/.yardopts new file mode 100644 index 0000000..3687f51 --- /dev/null +++ b/.yardopts @@ -0,0 +1,2 @@ +--markup markdown +--output-dir docs/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a51c641 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,21 @@ +FROM ruby:2.7 + +WORKDIR /opt/puppet + +# https://github.com/puppetlabs/puppet/blob/06ad255754a38f22fb3a22c7c4f1e2ce453d01cb/lib/puppet/provider/service/runit.rb#L39 +RUN mkdir -p /etc/sv + +ARG PUPPET_VERSION="~> 6.0" +ARG PARALLEL_TEST_PROCESSORS=4 + +# Cache gems +COPY Gemfile . +RUN bundle install --without system_tests development release --path=${BUNDLE_PATH:-vendor/bundle} + +COPY . . + +RUN bundle install +RUN bundle exec rake release_checks + +# Container should not saved +RUN exit 1 diff --git a/Gemfile b/Gemfile index 015fc4d..f4855f6 100644 --- a/Gemfile +++ b/Gemfile @@ -1,56 +1,33 @@ -source ENV['GEM_SOURCE'] || 'https://rubygems.org' - -def location_for(place, fake_version = nil) - if place =~ /^(git[:@][^#]*)#(.*)/ - [fake_version, { git: $1, branch: $2, require: false }].compact - elsif place =~ /^file:\/\/(.*)/ - ['>= 0', { path: File.expand_path($1), require: false }] - else - [place, { require: false }] - end -end +source ENV['GEM_SOURCE'] || "https://rubygems.org" group :test do - gem 'puppetlabs_spec_helper', require: false - gem 'rspec-puppet', require: false, git: 'https://github.com/rodjek/rspec-puppet.git' - gem 'rspec-puppet-facts', require: false - gem 'rspec-puppet-utils', require: false - gem 'puppet-lint-absolute_classname-check', require: false - gem 'puppet-lint-leading_zero-check', require: false - gem 'puppet-lint-trailing_comma-check', require: false - gem 'puppet-lint-version_comparison-check', require: false - gem 'puppet-lint-classes_and_types_beginning_with_digits-check', require: false - gem 'puppet-lint-unquoted_string-check', require: false - gem 'puppet-lint-variable_contains_upcase', require: false - gem 'metadata-json-lint', require: false - gem 'puppet-blacksmith', require: false - gem 'voxpupuli-release', require: false, git: 'https://github.com/voxpupuli/voxpupuli-release-gem.git' - gem 'rubocop', '~> 0.49.1', require: false - gem 'rubocop-rspec', require: false - gem 'json_pure', '<= 2.0.1', require: false if RUBY_VERSION < '2.0.0' - gem 'rspec-its', require: false + gem 'voxpupuli-test', '~> 2.1', :require => false + gem 'coveralls', :require => false + gem 'simplecov-console', :require => false end group :development do - gem 'travis', require: false - gem 'travis-lint', require: false - gem 'guard-rake', require: false + gem 'guard-rake', :require => false + gem 'overcommit', '>= 0.39.1', :require => false end group :system_tests do - gem 'beaker', :require => false - gem 'beaker-rspec', :require => false - gem 'serverspec', :require => false - gem 'beaker-puppet_install_helper', require: false + gem 'puppet_metadata', '~> 0.3.0', :require => false + gem 'voxpupuli-acceptance', :require => false end -if (facterversion = ENV['FACTER_GEM_VERSION']) - gem 'facter', facterversion.to_s, require: false, groups: [:test] -else - gem 'facter', require: false, groups: [:test] +group :release do + gem 'github_changelog_generator', '>= 1.16.1', :require => false + gem 'puppet-blacksmith', :require => false + gem 'voxpupuli-release', :require => false + gem 'puppet-strings', '>= 2.2', :require => false end -ENV['PUPPET_VERSION'].nil? ? puppetversion = '~> 4.0' : puppetversion = ENV['PUPPET_VERSION'].to_s -gem 'puppet', puppetversion, require: false, groups: [:test] +gem 'puppetlabs_spec_helper', '~> 2.0', :require => false +gem 'rake', :require => false +gem 'facter', ENV['FACTER_GEM_VERSION'], :require => false, :groups => [:test] + +puppetversion = ENV['PUPPET_VERSION'] || '~> 6.0' +gem 'puppet', puppetversion, :require => false, :groups => [:test] # vim: syntax=ruby diff --git a/README.md b/README.md index e89793c..1945d07 100644 --- a/README.md +++ b/README.md @@ -1,223 +1,236 @@ # puppet-sudo [![Build Status](https://secure.travis-ci.org/saz/puppet-sudo.png)](http://travis-ci.org/saz/puppet-sudo) https://github.com/saz/puppet-sudo Manage sudo configuration via Puppet ### Supported Puppet versions * Puppet >= 4 * Last version supporting Puppet 3: v4.2.0 ### Supported OS Some family and some specific os are supported by this module * debian osfamily (debian, ubuntu, kali, ...) * redhat osfamily (redhat, centos, fedora, ...) * suse osfamily (suse, opensuse, ...) * solaris osfamily (Solaris, OmniOS, SmartOS, ...) * freebsd osfamily * openbsd osfamily * aix osfamily * darwin osfamily * gentoo operating system * archlinux operating system * amazon operating system ### Gittip [![Support via Gittip](https://rawgithub.com/twolfson/gittip-badge/0.2.0/dist/gittip.png)](https://www.gittip.com/saz/) ## Usage ### WARNING **This module will purge your current sudo config** If this is not what you're expecting, set `purge` and/or `config_file_replace` to **false** ### Install sudo with default sudoers #### Purge current sudo config ```puppet class { 'sudo': } ``` #### Purge sudoers.d directory, but leave sudoers file as it is ```puppet class { 'sudo': config_file_replace => false, } ``` +#### Selective Purge of sudoers.d Directory +A combination of `suffix` and `purge_ignore` can be used to purge only files that puppet previously created. +If `suffix` is specified all puppet created sudoers.d entries will have this suffix apprended to +the thier file name. A ruby glob can be used as `purge_ignore` to ignore all files that do not have +this suffix. + +```puppet + class{'sudo': + suffix => '_puppet', + purge_ignore => '*[!_puppet]', + } +``` + #### Leave current sudo config as it is ```puppet class { 'sudo': purge => false, config_file_replace => false, } ``` #### Use LDAP along with sudo Sudo do not always include by default the support for LDAP. On Debian and Ubuntu a special package sudo-ldap will be used. On Gentoo there is also the needing to include [puppet portage module by Gentoo](https://forge.puppetlabs.com/gentoo/portage). If not present, only a notification will be shown. ```puppet class { 'sudo': ldap_enable => true, } ``` ### Adding sudoers configuration #### Using Code ```puppet class { 'sudo': } sudo::conf { 'web': source => 'puppet:///files/etc/sudoers.d/web', } sudo::conf { 'admins': priority => 10, content => '%admins ALL=(ALL) NOPASSWD: ALL', } sudo::conf { 'joe': priority => 60, source => 'puppet:///files/etc/sudoers.d/users/joe', } ``` #### Using Hiera A hiera hash may be used to assemble the sudoers configuration. Hash merging is also enabled, which supports layering the configuration settings. Examples using: - YAML backend - an environment called __production__ - a __/etc/puppet/hiera.yaml__ hierarchy configuration: ```yaml :hierarchy: - "%{environment}" - "defaults" ``` ##### Load module Load the module via Puppet Code or your ENC. ```puppet include sudo ``` ##### Configure Hiera YAML __(defaults.yaml)__ These defaults will apply to all systems. ```yaml sudo::configs: 'web': 'source' : 'puppet:///files/etc/sudoers.d/web' 'admins': 'content' : '%admins ALL=(ALL) NOPASSWD: ALL' 'priority' : 10 'joe': 'priority' : 60 'source' : 'puppet:///files/etc/sudoers.d/users/joe' ``` ##### Configure Hiera YAML __(production.yaml)__ This will only apply to the production environment. In this example we are: - inheriting/preserving the __web__ configuration - overriding the __admins__ configuration - removing the __joe__ configuration - adding the __bill__ template ```yaml lookup_options: sudo::configs: merge: strategy: deep merge_hash_arrays: true sudo::configs: 'admins': 'content' : "%prodadmins ALL=(ALL) NOPASSWD: ALL" 'priority' : 10 'joe': 'ensure' : 'absent' 'source' : 'puppet:///files/etc/sudoers.d/users/joe' 'bill': 'template' : "mymodule/bill.erb" ``` In this example we are: - inheriting/preserving the __web__ configuration - overriding the __admins:content__ setting - inheriting/preserving the __admins:priority__ setting - inheriting/preserving the __joe:source__ and __joe:priority__ settings - removing the __joe__ configuration - adding the __bill__ template ```yaml lookup_options: sudo::configs: merge: strategy: deep merge_hash_arrays: true sudo::configs: 'admins': 'content' : "%prodadmins ALL=(ALL) NOPASSWD: ALL" 'joe': 'ensure' : 'absent' 'bill': 'template' : "mymodule/bill.erb" ``` ##### Set a custom name for the sudoers file -In some edge cases, the automatically generated sudoers file name is insufficient. For example, when an application generates a sudoers file with a fixed file name, using this class with the purge option enabled will always delete the custom file and adding it manually will generate a file with the right content, but the wrong name. To solve this, you can use the ```sudo_file_name``` option to manually set the desired file name. +In some edge cases, the automatically generated sudoers file name is insufficient. For example, when an application generates a sudoers file with a fixed file name, using this class with the purge option enabled will always delete the custom file and adding it manually will generate a file with the right content, but the wrong name. To solve this, you can use the ```sudo_file_name``` option to manually set the desired file name. ```puppet sudo::conf { "foreman-proxy": ensure => "present", source => "puppet:///modules/sudo/foreman-proxy", sudo_file_name => "foreman-proxy", } ``` ### sudo::conf / sudo::configs notes * One of content or source must be set. * Content may be an array, string will be added with return carriage after each element. * In order to properly pass a template() use template instead of content, as hiera would run template function otherwise. ## sudo class parameters | Parameter | Type | Default | Description | | :-------------- | :------ |:----------- | :---------- | | enable | boolean | true | Set this to remove or purge all sudoers configs | | package | string | OS specific | Set package name _(for unsupported platforms)_ | | package_ensure | string | present | latest, absent, or a specific package version | | package_source | string | OS specific | Set package source _(for unsupported platforms)_ | | purge | boolean | true | Purge unmanaged files from config_dir | | purge_ignore | string | undef | Files excluded from purging in config_dir | | config_file | string | OS specific | Set config_file _(for unsupported platforms)_ | | config_file_replace | boolean | true | Replace config file with module config file | | includedirsudoers | boolean | OS specific | Add #includedir /etc/sudoers.d with augeas | | config_dir | string | OS specific | Set config_dir _(for unsupported platforms)_ | | content | string | OS specific | Alternate content file location | | ldap_enable | boolean | false | Add support to LDAP | | configs | hash | {} | A hash of sudo::conf's | ## sudo::conf class / sudo::configs hash parameters | Parameter | Type | Default | Description | | :-------------- | :----- |:----------- | :---------- | | ensure | string | present | present or absent | | priority | number | 10 | file name prefix | | content | string | undef | content of configuration snippet | | source | string | undef | source of configuration snippet | | template | string | undef | template of configuration snippet | | sudo_config_dir | string | OS Specific | configuration snippet directory _(for unsupported platforms)_ | | sudo_file_name | string | undef | custom file name for sudo file in sudoers directory | diff --git a/Rakefile b/Rakefile index dc3ab55..1e8a898 100644 --- a/Rakefile +++ b/Rakefile @@ -1,43 +1,61 @@ -require 'puppetlabs_spec_helper/rake_tasks' -require 'puppet_blacksmith/rake_tasks' -require 'voxpupuli/release/rake_tasks' +# Attempt to load voxupuli-test (which pulls in puppetlabs_spec_helper), +# otherwise attempt to load it directly. +begin + require 'voxpupuli/test/rake' +rescue LoadError + require 'puppetlabs_spec_helper/rake_tasks' +end -if RUBY_VERSION >= '2.2.0' - require 'rubocop/rake_task' +# load optional tasks for releases +# only available if gem group releases is installed +begin + require 'voxpupuli/release/rake_tasks' +rescue LoadError +end - RuboCop::RakeTask.new(:rubocop) do |task| - # These make the rubocop experience maybe slightly less terrible - task.options = ['-D', '-S', '-E'] +desc "Run main 'test' task and report merged results to coveralls" +task test_with_coveralls: [:test] do + if Dir.exist?(File.expand_path('../lib', __FILE__)) + require 'coveralls/rake/task' + Coveralls::RakeTask.new + Rake::Task['coveralls:push'].invoke + else + puts 'Skipping reporting to coveralls. Module has no lib dir' end end -PuppetLint.configuration.fail_on_warnings = true -PuppetLint.configuration.absolute_classname_reverse = true -PuppetLint.configuration.send('relative') -PuppetLint.configuration.send('disable_140chars') -PuppetLint.configuration.send('disable_class_inherits_from_params_class') -PuppetLint.configuration.send('disable_documentation') -PuppetLint.configuration.send('disable_single_quote_string_with_variables') +desc 'Generate REFERENCE.md' +task :reference, [:debug, :backtrace] do |t, args| + patterns = '' + Rake::Task['strings:generate:reference'].invoke(patterns, args[:debug], args[:backtrace]) +end -exclude_paths = %w( - pkg/**/* - vendor/**/* - .vendor/**/* - spec/**/* -) -PuppetLint.configuration.ignore_paths = exclude_paths -PuppetSyntax.exclude_paths = exclude_paths +begin + require 'github_changelog_generator/task' + require 'puppet_blacksmith' + GitHubChangelogGenerator::RakeTask.new :changelog do |config| + version = (Blacksmith::Modulefile.new).version + config.future_release = "v#{version}" if version =~ /^\d+\.\d+.\d+$/ + config.header = "# Changelog\n\nAll notable changes to this project will be documented in this file.\nEach new release typically also includes the latest modulesync defaults.\nThese should not affect the functionality of the module." + config.exclude_labels = %w{duplicate question invalid wontfix wont-fix modulesync skip-changelog} + config.user = 'saz' + metadata_json = File.join(File.dirname(__FILE__), 'metadata.json') + metadata = JSON.load(File.read(metadata_json)) + config.project = metadata['name'] + end -desc 'Run acceptance tests' -RSpec::Core::RakeTask.new(:acceptance) do |t| - t.pattern = 'spec/acceptance' -end + # Workaround for https://github.com/github-changelog-generator/github-changelog-generator/issues/715 + require 'rbconfig' + if RbConfig::CONFIG['host_os'] =~ /linux/ + task :changelog do + puts 'Fixing line endings...' + changelog_file = File.join(__dir__, 'CHANGELOG.md') + changelog_txt = File.read(changelog_file) + new_contents = changelog_txt.gsub(%r{\r\n}, "\n") + File.open(changelog_file, "w") {|file| file.puts new_contents } + end + end -desc 'Run tests metadata_lint, lint, syntax, spec' -task test: [ - :metadata_lint, - :lint, - :syntax, - :spec, -] +rescue LoadError +end # vim: syntax=ruby diff --git a/lib/facter/sudoversion.rb b/lib/facter/sudoversion.rb index cf80bdf..6ec9eac 100644 --- a/lib/facter/sudoversion.rb +++ b/lib/facter/sudoversion.rb @@ -1,13 +1,16 @@ require 'puppet' Facter.add(:sudoversion) do + confine :os do |os| + os['family'] != 'windows' + end setcode do if Facter::Util::Resolution.which('sudo') sudoversion = Facter::Util::Resolution.exec('sudo -V 2>&1') %r{^Sudo version ([\w\.]+)}.match(sudoversion)[1] elsif Facter::Util::Resolution.which('rpm') Facter::Util::Resolution.exec('rpm -q sudo --qf \'%{VERSION}\'') elsif Facter::Util::Resolution.which('dpkg-query') Facter::Util::Resolution.exec('dpkg-query -W -f=\'${Version}\n\' sudo') end end end diff --git a/manifests/allow.pp b/manifests/allow.pp index fb026a1..556f340 100644 --- a/manifests/allow.pp +++ b/manifests/allow.pp @@ -1,76 +1,76 @@ # Class: sudo::allow # # This class allows you to take complete advantage of automatic parameter # lookup using a Hiera database. Providing a singleton class that accepts # arrays in the parameters makes it possible to implement specific user # or group configuration in Hiera, whereas the use of defined types is # normally restricted to Puppet manifests. # # Furthermore, having separate parameters for "add" and "replace" modes # allows you to take full advantage of inheritance in the Hiera database # while still allowing for exceptions if required. # # This class works best with Puppet 3.0 or higher. # # Parameters: # [*add_users*] # Define the set of users with sudo privileges by getting all values in # the hierarchy for this key, then flattening them into a single array # of unique values. # Default: empty array # # [*add_groups*] # Define the set of groups with sudo privileges by getting all values in # the hierarchy for this key, then flattening them into a single array # of unique values. # Default: empty array # # [*replace_users*] # Override any values specified in add_users. If you specify this value # in your manifest or Hiera database, the contents of "add_users" will # be ignored. With Hiera, a standard priority lookup is used. Note that # if replace_users is specified at ANY level of the hierarchy, then # add_users is ignored at EVERY level of the hierarchy. # Default: undef # # [*replace_groups*] # Override any values specified in add_groups. If you specify this value # in your manifest or Hiera database, the contents of "add_groups" will # be ignored. With Hiera, a standard priority lookup is used. Note that # if replace_groups is specified at ANY level of the hierarchy, then # add_groups is ignored at EVERY level of the hierarchy. # Default: undef # # Actions: # Creates file in sudoers.d that permits specific users and groups to sudo. # # Sample Usage: # class { 'sudo::allow': # add_users => ['jsmith'], # add_groups => ['wheel'], # } # # [Remember: No empty lines between comments and class definition] -class sudo::allow( +class sudo::allow ( $add_users = [], $add_groups = [], $replace_users = undef, $replace_groups = undef ) { # TODO validate that all input is arrays if $replace_users != undef { $users = $replace_users } else { $users = lookup("${module_name}::allow::add_users", Array, 'unique', $add_users) } if $replace_groups != undef { $groups = $replace_groups } else { $groups = lookup("${module_name}::allow::add_groups", Array, 'unique', $add_groups) } sudo::conf { 'sudo_users_groups': content => template("${module_name}/users_groups.erb"), } } diff --git a/manifests/conf.pp b/manifests/conf.pp index 7f0154d..943a344 100644 --- a/manifests/conf.pp +++ b/manifests/conf.pp @@ -1,137 +1,143 @@ # Define: sudo::conf # # This module manages sudo configurations # # Parameters: # [*ensure*] # Ensure if present or absent. # Default: present # # [*priority*] # Prefix file name with $priority # Default: 10 # # [*content*] # Content of configuration snippet. # Default: undef # # [*source*] # Source of configuration snippet. # Default: undef # # [*sudo_config_dir*] # Where to place configuration snippets. # Only set this, if your platform is not supported or # you know, what you're doing. # Default: auto-set, platform specific # # Actions: # Installs sudo configuration snippets # # Requires: # Class sudo # # Sample Usage: # sudo::conf { 'admins': # source => 'puppet:///files/etc/sudoers.d/admins', # } # # [Remember: No empty lines between comments and class definition] -define sudo::conf( +define sudo::conf ( $ensure = present, $priority = 10, $content = undef, $source = undef, $template = undef, $sudo_config_dir = undef, $sudo_file_name = undef, $sudo_syntax_path = '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' ) { include sudo # Hack to allow the user to set the config_dir from the # sudo::config parameter, but default to $sudo::params::config_dir # if it is not provided. $sudo::params isn't included before # the parameters are loaded in. $sudo_config_dir_real = $sudo_config_dir ? { undef => $sudo::config_dir, $sudo_config_dir => $sudo_config_dir } + # Append suffix + if $sudo::suffix { + $_name_suffix = "${name}${sudo::suffix}" + } else { + $_name_suffix = $name + } # sudo skip file name that contain a "." - $dname = regsubst($name, '\.', '-', 'G') + $dname = regsubst($_name_suffix, '\.', '-', 'G') if size("x${priority}") == 2 { $priority_real = "0${priority}" } else { $priority_real = $priority } # build current file name with path if $sudo_file_name != undef { $cur_file = "${sudo_config_dir_real}/${sudo_file_name}" } else { $cur_file = "${sudo_config_dir_real}/${priority_real}_${dname}" } # replace whitespace in file name $cur_file_real = regsubst($cur_file, '\s+', '_', 'G') - if $::osfamily == 'RedHat' { + if $facts['os']['family'] == 'RedHat' { if (versioncmp($::sudoversion, '1.7.2p1') < 0) { warning("Found sudo with version ${::sudoversion}, but at least version 1.7.2p1 is required!") } } if $content != undef { if $content =~ Array { $lines = join($content, "\n") $content_real = "# This file is managed by Puppet; changes may be overwritten\n${lines}\n" } else { $content_real = "# This file is managed by Puppet; changes may be overwritten\n${content}\n" } } elsif $template != undef { $content_real = template($template) } else { $content_real = undef } if $ensure == 'present' { if $sudo::validate_single { $validate_cmd_real = 'visudo -c -f %' } else { $validate_cmd_real = undef } if $sudo::delete_on_error { $notify_real = Exec["sudo-syntax-check for file ${cur_file}"] $delete_cmd = "( rm -f '${cur_file_real}' && exit 1)" } else { $notify_real = Exec["sudo-syntax-check for file ${cur_file}"] $errormsg = "Error on global-syntax-check with file ${cur_file_real}" $delete_cmd = "( echo '${errormsg}' && echo '#${errormsg}' >>${cur_file_real} && exit 1)" } } else { $delete_cmd = '' $notify_real = undef $validate_cmd_real = undef } file { "${priority_real}_${dname}": ensure => $ensure, path => $cur_file_real, owner => 'root', group => $sudo::params::config_file_group, mode => $sudo::params::config_file_mode, source => $source, content => $content_real, notify => $notify_real, require => File[$sudo_config_dir_real], validate_cmd => $validate_cmd_real, } - exec {"sudo-syntax-check for file ${cur_file}": + exec { "sudo-syntax-check for file ${cur_file}": command => "visudo -c || ${delete_cmd}", refreshonly => true, path => $sudo_syntax_path, } } diff --git a/manifests/init.pp b/manifests/init.pp index 2088bf3..7165bf5 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -1,213 +1,219 @@ # Class: sudo # # This module manages sudo # # Parameters: # [*ensure*] # Ensure if present or absent. # Default: present # # [*package*] # Name of the package. # Only set this, if your platform is not supported or you know, # what you're doing. # Default: auto-set, platform specific # # [*package_ensure*] # Allows you to ensure a particular version of a package # Default: present / lastest for RHEL < 5.5 # # [*package_source*] # Where to find the package. Only set this on AIX (required) and # Solaris (required) or if your platform is not supported or you # know, what you're doing. # # The default for aix is the perzl sudo package. For solaris 10 we # use the official www.sudo.ws binary package. # # Default: AIX: perzl.org # Solaris: www.sudo.ws # # [*package_provider_override*] # Allows you to override the default package provider. # Default: rpm # # [*package_admin_file*] # Where to find a Solaris 10 package admin file for # an unattended installation. We do not supply a default file, so # this has to be staged separately # # Only set this on Solaris 10 (required) # Default: /var/sadm/install/admin/puppet # # [*purge*] # Whether or not to purge sudoers.d directory # Default: true # # [*purge_ignore*] # Files to exclude from purging in sudoers.d directory # Default: undef # +# [*suffix*] +# Adds a custom suffix to all files created in sudoers.d directory. +# # [*config_file*] # Main configuration file. # Only set this, if your platform is not supported or you know, # what you're doing. # Default: auto-set, platform specific # # [*config_dir*] # Main directory containing sudo snippets, imported via # includedir stanza in sudoers file # Default: auto-set, platform specific # # [*extra_include_dirs*] # Array of additional directories containing sudo snippets # Default: undef # # [*content*] # Alternate content file location # Only set this, if your platform is not supported or you know, # what you're doing. # Default: auto-set, platform specific # # [*ldap_enable*] # Enable ldap support on the package # Default: false # # [*delete_on_error*] # True if you want that the configuration is deleted on an error # during a complete visudo -c run. If false it will just return # an error and will add a comment to the sudoers configuration so # that the resource will be checked at the following run. # Default: true # # [*validate_single*] # Do a validate on the "single" file in the sudoers.d directory. # If the validate fail the file will not be saved or changed # if a file already exist. # Default: false # +# [*wheel_config*] +# How to configure the wheel group in /etc/sudoers +# Options are either not to configure it it, configure it prompting for password, +# or configuring it without password prompt. +# Default: 'absent' (don't configure it at all) +# # [*use_sudoreplay*] # Boolean to enable the usage of sudoreplay. # Default: false # # [*sudoreplay_discard*] # Array of additional command to discard in sudo log. # Default: undef # # [*configs*] # A hash of sudo::conf's # Default: {} # # Actions: # Installs sudo package and checks the state of sudoers file and # sudoers.d directory. # # Requires: # Nothing # # Sample Usage: # class { 'sudo': } # # [Remember: No empty lines between comments and class definition] class sudo ( Boolean $enable = true, Optional[String] $package = $sudo::params::package, Optional[String] $package_ldap = $sudo::params::package_ldap, String $package_ensure = $sudo::params::package_ensure, Optional[String] $package_source = $sudo::params::package_source, Optional[String] $package_provider_override = $sudo::params::package_provider_override, Optional[String] $package_admin_file = $sudo::params::package_admin_file, Boolean $purge = true, Optional[Variant[String, Array[String]]] $purge_ignore = undef, + Optional[String] $suffix = undef, String $config_file = $sudo::params::config_file, Boolean $config_file_replace = true, String $config_file_mode = $sudo::params::config_file_mode, String $config_dir = $sudo::params::config_dir, String $config_dir_mode = $sudo::params::config_dir_mode, Optional[Array[String]] $extra_include_dirs = undef, String $content = $sudo::params::content, Boolean $ldap_enable = false, Boolean $delete_on_error = true, Boolean $validate_single = false, Boolean $config_dir_keepme = $sudo::params::config_dir_keepme, Boolean $use_sudoreplay = false, + Enum['absent','password','nopassword'] $wheel_config = 'absent', Optional[Array[String]] $sudoreplay_discard = undef, Hash $configs = {}, ) inherits sudo::params { - - case $enable { true: { $dir_ensure = 'directory' $file_ensure = 'present' } false: { $dir_ensure = 'absent' $file_ensure = 'absent' } default: { fail('no $enable is set') } } case $ldap_enable { true: { if $package_ldap == undef { fail('on your os ldap support for sudo is not yet supported') } $package_real = $package_ldap } false: { $package_real = $package } default: { fail('no $ldap_enable is set') } } if $package_real { class { 'sudo::package': package => $package_real, package_ensure => $package_ensure, package_source => $package_source, package_provider_override => $package_provider_override, package_admin_file => $package_admin_file, ldap_enable => $ldap_enable, - before => [ File[$config_file], File[$config_dir] ], + before => [ + File[$config_file], + File[$config_dir], + ], } } file { $config_file: ensure => $file_ensure, owner => 'root', group => $sudo::params::config_file_group, mode => $config_file_mode, replace => $config_file_replace, content => template($content), } file { $config_dir: ensure => $dir_ensure, owner => 'root', group => $sudo::params::config_file_group, mode => $config_dir_mode, recurse => $purge, purge => $purge, ignore => $purge_ignore, } if $config_dir_keepme { file { "${config_dir}/.keep-me": ensure => file, owner => 'root', group => $sudo::params::config_file_group, } } $configs.each |$config_name, $config| { sudo::conf { $config_name: * => $config, } } - - if $package_real { - anchor { 'sudo::begin': } - -> Class['sudo::package'] - -> anchor { 'sudo::end': } - } } diff --git a/manifests/package.pp b/manifests/package.pp index 239250c..376ee39 100644 --- a/manifests/package.pp +++ b/manifests/package.pp @@ -1,86 +1,89 @@ # == Class: sudo::package # # Installs the sudo package on various platforms. # # === Parameters # # Document parameters here. # # [*package*] # The name of the sudo package to be installed # # [*package_ensure*] # Ensure if present or absent # # [*package_source*] # Where to find the sudo packge, should be a local file or a uri # # [*package_provider_override*] # Override the default package provider # # === Examples # # class { sysdoc::package # package => 'sudo', # } # # === Authors # # Toni Schmidbauer # # === Copyright # # Copyright 2013 Toni Schmidbauer # -class sudo::package( +class sudo::package ( $package = '', $package_ensure = present, $package_source = '', $package_provider_override = '', $package_admin_file = '', $ldap_enable = false, ) { - if $ldap_enable == true { - case $::osfamily { + case $facts['os']['family'] { 'Gentoo': { if defined( 'portage' ) { Class['sudo'] -> Class['portage'] package_use { 'app-admin/sudo': ensure => present, use => ['ldap'], target => 'sudo-flags', } } else { fail ('portage package needed to define ldap use on sudo') } } - default: { } + default: {} } } - case $::osfamily { + case $facts['os']['family'] { 'AIX': { class { 'sudo::package::aix': package => $package, package_source => $package_source, package_ensure => $package_ensure, package_provider_override => $package_provider_override, } } 'Darwin': {} 'Solaris': { class { 'sudo::package::solaris': package => $package, package_source => $package_source, package_ensure => $package_ensure, package_admin_file => $package_admin_file, } } default: { if $package != '' { - ensure_packages([$package], {'ensure' => $package_ensure}) + ensure_packages([ + $package, + ], { + 'ensure' => $package_ensure, + }) } } } } diff --git a/manifests/package/aix.pp b/manifests/package/aix.pp index e0ad7ad..622aada 100644 --- a/manifests/package/aix.pp +++ b/manifests/package/aix.pp @@ -1,49 +1,48 @@ # == Class: sudo::package::aix # # Install the perzl.org sudo package. It also requires the openldap # rpm. so we add a dependencies to the ldap module. # # === Parameters # # Document parameters here. # # [*package*] # The name of the sudo package to be installed # # [*package_ensure*] # Ensure if present or absent # # [*package_source*] # Where to find the sudo packge, should be a local file or a uri # # [*package_provider_override*] # Override the default package provider # # === Examples # # class { sudo::package::aix: # package => 'sudo', # package_source 'http://myaixpkgserver/pkgs/aix/sudo-1.8.6p7-1.aix5.1.ppc.rpm'', # } # # === Authors # # Toni Schmidbauer # # === Copyright # # Copyright 2013 Toni Schmidbauer # class sudo::package::aix ( $package = '', $package_source = '', $package_ensure = 'present', $package_provider_override = '', - ) { - - package { $package: - ensure => $package_ensure, - source => $package_source, - provider => $package_provider_override, - } +) { + package { $package: + ensure => $package_ensure, + source => $package_source, + provider => $package_provider_override, + } } diff --git a/manifests/package/solaris.pp b/manifests/package/solaris.pp index ad2bcf6..d5cf4d0 100644 --- a/manifests/package/solaris.pp +++ b/manifests/package/solaris.pp @@ -1,60 +1,61 @@ # == Class: sudo::package::solaris # # install sudo under solaris 10/11. # # === Parameters # # Document parameters here. # # [*package*] # The name of the sudo package to be installed # # [*package_ensure*] # Ensure if present or absent # # [*package_source*] # Where to find the sudo packge, should be a local file or a uri # # [*package_admin_file*] # Solaris 10 package admin file for unattended installation # # === Examples # # class { sudo::package::solaris: # package => 'sudo', # } # # === Authors # # Toni Schmidbauer # # === Copyright # # Copyright 2013 Toni Schmidbauer # class sudo::package::solaris ( - $package = '', + $package = '', $package_source = '', $package_ensure = 'present', $package_admin_file = '', - ) { - +) { case $::kernelrelease { '5.11': { package { $package: ensure => $package_ensure, } } '5.10': { package { $package: ensure => $package_ensure, source => $package_source, adminfile => $package_admin_file, - install_options => ['-G', ], + install_options => [ + '-G', + ], } } default: { fail("Unsupported Solaris kernelrelease ${::kernelrelease}!") } } } diff --git a/manifests/params.pp b/manifests/params.pp index 0c42935..1119d7d 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -1,228 +1,228 @@ #class sudo::params #Set the paramters for the sudo module class sudo::params { $content_base = "${module_name}/" $config_file_mode = '0440' $config_dir_mode = '0550' - case $::osfamily { + case $facts['os']['family'] { 'Debian': { - case $::operatingsystem { + case $facts['os']['name'] { 'Ubuntu': { $content = "${content_base}sudoers.ubuntu.erb" } default: { - if (versioncmp($::operatingsystemmajrelease, '7') >= 0) or - ($::operatingsystemmajrelease =~ /\/sid/) or - ($::operatingsystemmajrelease =~ /Kali/) { + if (versioncmp($facts['os']['release']['major'], '7') >= 0) or + ($facts['os']['release']['major'] =~ /\/sid/) or + ($facts['os']['release']['major'] =~ /Kali/) { $content = "${content_base}sudoers.debian.erb" } else { $content = "${content_base}sudoers.olddebian.erb" } } } $package = 'sudo' $package_ldap = 'sudo-ldap' $package_ensure = 'present' $package_source = '' $package_admin_file = '' $config_file = '/etc/sudoers' $config_dir = '/etc/sudoers.d' $config_file_group = 'root' $config_dir_keepme = false } 'RedHat': { $package = 'sudo' # in redhat sudo package is already compiled for ldap support $package_ldap = $package # rhel 5.0 to 5.4 use sudo 1.6.9 which does not support # includedir, so we have to make sure sudo 1.7 (comes with rhel # 5.5) is installed. - $package_ensure = $::operatingsystemrelease ? { + $package_ensure = $facts['os']['release']['full'] ? { /^5.[01234]$/ => 'latest', default => 'present', } $package_source = '' $package_admin_file = '' $config_file = '/etc/sudoers' $config_dir = '/etc/sudoers.d' - $content = $::operatingsystemrelease ? { + $content = $facts['os']['release']['full'] ? { /^5/ => "${content_base}sudoers.rhel5.erb", /^6/ => "${content_base}sudoers.rhel6.erb", /^7/ => "${content_base}sudoers.rhel7.erb", /^8/ => "${content_base}sudoers.rhel8.erb", default => "${content_base}sudoers.rhel8.erb", - } + } $config_file_group = 'root' $config_dir_keepme = false } 'Suse': { $package = 'sudo' $package_ldap = $package $package_ensure = 'present' $package_source = '' $package_admin_file = '' $config_file = '/etc/sudoers' $config_dir = '/etc/sudoers.d' $content = "${content_base}sudoers.suse.erb" $config_file_group = 'root' $config_dir_keepme = false } 'Solaris': { - case $::operatingsystem { + case $facts['os']['name'] { 'OmniOS': { $package = 'sudo' $package_ldap = undef $package_ensure = 'present' $package_source = '' $package_admin_file = '' $config_file = '/etc/sudoers' $config_dir = '/etc/sudoers.d' $content = "${content_base}sudoers.omnios.erb" $config_file_group = 'root' $config_dir_keepme = false } 'SmartOS': { $package = 'sudo' $package_ldap = undef $package_ensure = 'present' $package_source = '' $package_admin_file = '' $config_file = '/opt/local/etc/sudoers' $config_dir = '/opt/local/etc/sudoers.d' $content = "${content_base}sudoers.smartos.erb" $config_file_group = 'root' $config_dir_keepme = false } default: { case $::kernelrelease { '5.11': { $package = 'pkg://solaris/security/sudo' $package_ldap = undef $package_ensure = 'present' $package_source = '' $package_admin_file = '' $config_file = '/etc/sudoers' $config_dir = '/etc/sudoers.d' $content = "${content_base}sudoers.solaris.erb" $config_file_group = 'root' $config_dir_keepme = false } '5.10': { $package = 'TCMsudo' $package_ldap = undef $package_ensure = 'present' - $package_source = "http://www.sudo.ws/sudo/dist/packages/Solaris/10/TCMsudo-1.8.9p5-${::hardwareisa}.pkg.gz" + $package_source = "http://www.sudo.ws/sudo/dist/packages/Solaris/10/TCMsudo-1.8.9p5-${facts['os']['hardware']}.pkg.gz" $package_admin_file = '/var/sadm/install/admin/puppet' $config_file = '/etc/sudoers' $config_dir = '/etc/sudoers.d' $content = "${content_base}sudoers.solaris.erb" $config_file_group = 'root' $config_dir_keepme = false } default: { - fail("Unsupported platform: ${::osfamily}/${::operatingsystem}/${::kernelrelease}") + fail("Unsupported platform: ${facts['os']['family']}/${facts['os']['name']}/${::kernelrelease}") } } } } } 'FreeBSD': { $package = 'security/sudo' $package_ldap = undef $package_ensure = 'present' $package_source = '' $package_admin_file = '' $config_file = '/usr/local/etc/sudoers' $config_dir = '/usr/local/etc/sudoers.d' $content = "${content_base}sudoers.freebsd.erb" $config_file_group = 'wheel' $config_dir_keepme = true } 'OpenBSD': { if (versioncmp($::kernelversion, '5.8') < 0) { $package = undef } else { $package = 'sudo' } $package_ldap = undef $package_ensure = 'present' $package_source = '' $package_admin_file = '' $config_file = '/etc/sudoers' $config_dir = '/etc/sudoers.d' $content = "${content_base}sudoers.openbsd.erb" $config_file_group = 'wheel' $config_dir_keepme = false } 'AIX': { $package = 'sudo' $package_ldap = undef $package_ensure = 'present' $package_provider_override = 'rpm' $package_source = 'http://www.sudo.ws/sudo/dist/packages/AIX/5.3/sudo-1.8.27-1.aix53.rpm' $package_admin_file = '' $config_file = '/etc/sudoers' $config_dir = '/etc/sudoers.d' $content = "${content_base}sudoers.aix.erb" $config_file_group = 'system' $config_dir_keepme = false } 'Darwin': { $package = undef $package_ldap = undef $package_ensure = 'present' $package_source = '' $package_admin_file = '' $config_file = '/etc/sudoers' $config_dir = '/etc/sudoers.d' $content = "${content_base}sudoers.darwin.erb" $config_file_group = 'wheel' $config_dir_keepme = false } default: { - case $::operatingsystem { + case $facts['os']['name'] { 'Gentoo': { $package = 'sudo' $package_ldap = $package $package_ensure = 'present' $config_file = '/etc/sudoers' $config_dir = '/etc/sudoers.d' $content = "${content_base}sudoers.gentoo.erb" $config_file_group = 'root' $config_dir_keepme = false } - /^(Archlinux|Manjarolinux)$/: { + /^(Arch|Manjaro)(.{0}|linux)$/: { $package = 'sudo' $package_ldap = $package $package_ensure = 'present' $config_file = '/etc/sudoers' $config_dir = '/etc/sudoers.d' $content = "${content_base}sudoers.archlinux.erb" $config_file_group = 'root' $config_dir_keepme = false } 'Amazon': { $package = 'sudo' $package_ldap = $package $package_ensure = 'present' $config_file = '/etc/sudoers' $config_dir = '/etc/sudoers.d' - $content = $::operatingsystemrelease ? { + $content = $facts['os']['release']['full'] ? { /^5/ => "${content_base}sudoers.rhel5.erb", /^6/ => "${content_base}sudoers.rhel6.erb", default => "${content_base}sudoers.rhel6.erb", } $config_file_group = 'root' $config_dir_keepme = false } default: { - fail("Unsupported platform: ${::osfamily}/${::operatingsystem}") + fail("Unsupported platform: ${facts['os']['family']}/${facts['os']['name']}") } } $package_source = '' $package_admin_file = '' } } } diff --git a/metadata.json b/metadata.json index 9a89407..00e1d89 100644 --- a/metadata.json +++ b/metadata.json @@ -1,64 +1,90 @@ { "name": "saz-sudo", "version": "6.0.1", "author": "saz", "license": "Apache-2.0", "summary": "Manage sudo configuration via Puppet", "source": "https://github.com/saz/puppet-sudo", "project_page": "https://github.com/saz/puppet-sudo", "issues_url": "https://github.com/saz/puppet-sudo/issues", "tags": ["sudo"], "operatingsystem_support": [ { - "operatingsystem": "RedHat" + "operatingsystem": "RedHat", + "operatingsystemrelease": [ + "7" + ] }, { - "operatingsystem": "CentOS" + "operatingsystem": "CentOS", + "operatingsystemrelease": [ + "7" + ] }, { - "operatingsystem": "OracleLinux" + "operatingsystem": "OracleLinux", + "operatingsystemrelease": [ + "7" + ] }, { - "operatingsystem": "Scientific" + "operatingsystem": "Scientific", + "operatingsystemrelease": [ + "7" + ] }, { - "operatingsystem": "Debian" + "operatingsystem": "Debian", + "operatingsystemrelease": [ + "9", + "10" + ] }, { - "operatingsystem": "Ubuntu" + "operatingsystem": "Ubuntu", + "operatingsystemrelease": [ + "18.04", + "20.04" + ] }, { "operatingsystem": "SmartOS" }, { "operatingsystem": "OmniOS" }, { "operatingsystem": "FreeBSD" }, { "operatingsystem": "OpenBSD" }, { "operatingsystem": "AIX" }, { "operatingsystem": "Darwin" }, { "operatingsystem": "Gentoo" }, { "operatingsystem": "Archlinux" }, { "operatingsystem": "Amazon" }, { "operatingsystem": "Suse" } ], "dependencies": [ - { "name": "puppetlabs/stdlib", "version_requirement": ">=2.6.0 < 7.0.0" } + { "name": "puppetlabs/stdlib", "version_requirement": ">=2.6.0 < 8.0.0" } + ], + "requirements": [ + { + "name": "puppet", + "version_requirement": ">= 6.1.0 < 8.0.0" + } ] } diff --git a/spec/acceptance/class_spec.rb b/spec/acceptance/class_spec.rb index 267bc1e..2d96071 100644 --- a/spec/acceptance/class_spec.rb +++ b/spec/acceptance/class_spec.rb @@ -1,16 +1,16 @@ require 'spec_helper_acceptance' describe 'sudo class' do context 'with default parameters' do # Using puppet_apply as a helper it 'works with no errors' do pp = <<-PP class { 'sudo': } PP # Run it twice and test for idempotency - apply_manifest(pp, :catch_failures => true) - apply_manifest(pp, :catch_changes => true) + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) end end end diff --git a/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml b/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml deleted file mode 100644 index cba1cd0..0000000 --- a/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml +++ /dev/null @@ -1,11 +0,0 @@ -HOSTS: - ubuntu-server-1404-x64: - roles: - - master - platform: ubuntu-14.04-amd64 - box : puppetlabs/ubuntu-14.04-64-nocm - box_url : https://vagrantcloud.com/puppetlabs/ubuntu-14.04-64-nocm - hypervisor : vagrant -CONFIG: - log_level : debug - type: git diff --git a/spec/acceptance/sudo_conf_spec.rb b/spec/acceptance/sudo_conf_spec.rb index a682e93..86898dd 100644 --- a/spec/acceptance/sudo_conf_spec.rb +++ b/spec/acceptance/sudo_conf_spec.rb @@ -1,52 +1,109 @@ require 'spec_helper_acceptance' describe 'sudo::conf class' do context 'with default parameters' do # Using puppet_apply as a helper it 'works with no errors' do pp = <<-PP group { 'janedoe': ensure => present; } -> user { 'janedoe' : gid => 'janedoe', home => '/home/janedoe', shell => '/bin/bash', managehome => true, membership => minimum, } -> user { 'nosudoguy' : home => '/home/nosudoguy', shell => '/bin/bash', managehome => true, membership => minimum, } -> class {'sudo': purge => false, config_file_replace => false, } -> sudo::conf { 'janedoe_nopasswd': content => "janedoe ALL=(ALL) NOPASSWD: ALL\n" } PP # Run it twice and test for idempotency - apply_manifest(pp, :catch_failures => true) - apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_failures: true) end describe command("su - janedoe -c 'sudo echo Hello World'") do its(:stdout) { is_expected.to match %r{Hello World} } its(:exit_status) { is_expected.to eq 0 } end describe command("su - nosudoguy -c 'sudo echo Hello World'") do - its(:stderr) { is_expected.to match %r{no tty present and no askpass program specified} } + its(:stderr) { is_expected.to match %r{no tty present and no askpass program specified|a terminal is required to read the password} } its(:exit_status) { is_expected.to eq 1 } end end + + context 'with ignore and suffix specified managed file' do + describe command('touch /etc/sudoers.d/file-from-rpm') do + its(:exit_status) { is_expected.to eq 0 } + end + + it 'create a puppet managed file' do + pp = <<-PP + class {'sudo': + suffix => '_puppet', + purge_ignore => '[*!_puppet]', + } + sudo::conf { 'janedoe_nopasswd': + content => "janedoe ALL=(ALL) NOPASSWD: ALL\n" + } + PP + + # Run it twice and test for idempotency + apply_manifest(pp, catch_failures: true) + expect(apply_manifest(pp, catch_failures: true).exit_code).to be_zero + end + + describe file('/etc/sudoers.d/10_janedoe_nopasswd_puppet') do + it { is_expected.to be_file } + it { is_expected.to contain 'janedoe ALL=(ALL) NOPASSWD: ALL' } + end + + describe file('/etc/sudoers.d/file-from-rpm') do + it { is_expected.to exist } + end + end + + context 'with ignore and suffix specified without managed file' do + describe command('touch /etc/sudoers.d/file-from-rpm') do + its(:exit_status) { is_expected.to eq 0 } + end + + it 'without a puppet managed file' do + pp = <<-PP + class {'sudo': + suffix => '_puppet', + purge_ignore => '[*!_puppet]', + } + PP + # Run it twice and test for idempotency + apply_manifest(pp, catch_failures: true) + expect(apply_manifest(pp, catch_failures: true).exit_code).to be_zero + end + + describe file('/etc/sudoers.d/10_janedoe_nopasswd_puppet') do + it { is_expected.not_to exist } + end + + describe file('/etc/sudoers.d/file-from-rpm') do + it { is_expected.to exist } + end + end end diff --git a/spec/classes/package_aix_spec.rb b/spec/classes/package_aix_spec.rb index d254428..9b0f194 100644 --- a/spec/classes/package_aix_spec.rb +++ b/spec/classes/package_aix_spec.rb @@ -1,51 +1,51 @@ require 'spec_helper' describe 'sudo::package::aix' do describe 'on supported osfamily: AIX' do let :params do { - :package_provider_override => 'rpm' :package => 'sudo', :package_ensure => 'present', - :package_source => 'http://www.sudo.ws/sudo/dist/packages/AIX/5.3/sudo-1.8.27-1.aix53.rpm' + :package_source => 'http://www.sudo.ws/sudo/dist/packages/AIX/5.3/sudo-1.8.27-1.aix53.rpm', + :package_provider_override => 'rpm' } end let :facts do { - :osfamily => 'AIX' + osfamily: 'AIX' } end it do is_expected.to contain_package('sudo').with( 'ensure' => 'present', 'source' => 'http://www.sudo.ws/sudo/dist/packages/AIX/5.3/sudo-1.8.27-1.aix53.rpm', 'provider' => 'rpm' ) end end let :params do { :package => 'sudo', :package_ensure => 'present', :package_source => undef :package_provider_override => 'yum' } end let :facts do { :osfamily => 'AIX' } end it do is_expected.to contain_package('sudo').with( 'ensure' => 'present', 'source' => undef, 'provider' => 'yum' ) end end end diff --git a/spec/classes/package_spec.rb b/spec/classes/package_spec.rb index 4638524..3c3571e 100644 --- a/spec/classes/package_spec.rb +++ b/spec/classes/package_spec.rb @@ -1,77 +1,85 @@ require 'spec_helper' describe 'sudo::package' do describe 'on supported osfamily: RedHat' do let :params do { - :package => 'sudo', - :package_ensure => 'present' + package: 'sudo', + package_ensure: 'present' } end let :facts do { - :osfamily => 'RedHat' + os: { + 'family' => 'RedHat', + }, } end it do is_expected.to contain_package('sudo').with('ensure' => 'present') end end describe 'on supported osfamily: OpenBSD 5.8' do let :params do { - :package => 'sudo', - :package_ensure => 'present' + package: 'sudo', + package_ensure: 'present' } end let :facts do { - :osfamily => 'OpenBSD', - :kernelversion => '5.8' + os: { + 'family' => 'OpenBSD', + }, + kernelversion: '5.8' } end it do is_expected.to contain_package('sudo').with('ensure' => 'present') end end describe 'on supported osfamily: OpenBSD 5.7' do let :facts do { - :osfamily => 'OpenBSD', - :kernelversion => '5.7' + os: { + 'family' => 'OpenBSD', + }, + kernelversion: '5.7' } end it do is_expected.not_to contain_package('sudo') end end describe 'on supported osfamily: AIX' do let :params do { - :package => 'sudo', - :package_ensure => 'present', - :package_source => 'http://www.oss4aix.org/compatible/aix53/sudo-1.8.7-1.aix5.1.ppc.rpm' + package: 'sudo', + package_ensure: 'present', + package_source: 'http://www.oss4aix.org/compatible/aix53/sudo-1.8.7-1.aix5.1.ppc.rpm' } end let :facts do { - :osfamily => 'AIX' + os: { + 'family' => 'AIX', + }, } end it do is_expected.to contain_class('sudo::package::aix').with( 'package' => 'sudo', 'package_source' => 'http://www.oss4aix.org/compatible/aix53/sudo-1.8.7-1.aix5.1.ppc.rpm', 'package_ensure' => 'present' ) end end end diff --git a/spec/classes/sudo_spec.rb b/spec/classes/sudo_spec.rb index e18aa20..a074058 100644 --- a/spec/classes/sudo_spec.rb +++ b/spec/classes/sudo_spec.rb @@ -1,242 +1,257 @@ require 'spec_helper' describe 'sudo' do let :default_params do { - :enable => true, - :package_ensure => 'present', - :purge => true, - :config_file_replace => true + enable: true, + package_ensure: 'present', + purge: true, + config_file_replace: true } end [{}, { - :package_ensure => 'present', - :purge => false, - :config_file_replace => false + package_ensure: 'present', + purge: false, + config_file_replace: false }, { - :package_ensure => 'latest', - :purge => true, - :config_file_replace => false + package_ensure: 'latest', + purge: true, + config_file_replace: false }].each do |param_set| describe "when #{param_set == {} ? 'using default' : 'specifying'} class parameters" do let :param_hash do default_params.merge(param_set) end let :params do param_set end %w[Debian Redhat].each do |osfamily| let :facts do { - :operatingsystem => osfamily, - :operatingsystemrelease => '7.0', - :operatingsystemmajrelease => '7', - :osfamily => osfamily, - :puppetversion => '3.7.0' + os: { + 'family' => osfamily, + 'name' => osfamily, + 'release' => { + 'full' => '7.0', + 'major' => '7', + }, + }, + puppetversion: '3.7.0' } end describe "on supported osfamily: #{osfamily}" do it { is_expected.to contain_class('sudo::params') } it do is_expected.to contain_file('/etc/sudoers').with( 'ensure' => 'present', 'owner' => 'root', 'group' => 'root', 'mode' => '0440', 'replace' => param_hash[:config_file_replace] ) end it do is_expected.to contain_file('/etc/sudoers.d').with( 'ensure' => 'directory', 'owner' => 'root', 'group' => 'root', 'mode' => '0550', 'recurse' => param_hash[:purge], 'purge' => param_hash[:purge] ) end it do is_expected.to contain_class('sudo::package').with( 'package' => 'sudo', 'package_ensure' => param_hash[:package_ensure] ) end end end describe 'on RedHat 5.4' do let :facts do { - :osfamily => 'RedHat', - :operatingsystemrelease => '5.4', - :operatingsystemmajrelease => '5', - :puppetversion => '3.7.0' + os: { + 'family' => 'RedHat', + 'name' => 'RedHat', + 'release' => { + 'full' => '5.4', + 'major' => '5', + }, + }, + puppetversion: '3.7.0' } end it do if params == {} is_expected.to contain_class('sudo::package').with( 'package' => 'sudo', 'package_ensure' => 'latest' ) else is_expected.to contain_class('sudo::package').with( 'package' => 'sudo', 'package_ensure' => param_hash[:package_ensure] ) end end end describe 'on supported osfamily: AIX' do let :facts do { - :osfamily => 'AIX', - :puppetversion => '3.7.0' + os: { + 'family' => 'AIX', + }, + puppetversion: '3.7.0' } end it { is_expected.to contain_class('sudo::params') } it do is_expected.to contain_file('/etc/sudoers').with( 'ensure' => 'present', 'owner' => 'root', 'group' => 'system', 'mode' => '0440', 'replace' => param_hash[:config_file_replace] ) end it do is_expected.to contain_file('/etc/sudoers.d').with( 'ensure' => 'directory', 'owner' => 'root', 'group' => 'system', 'mode' => '0550', 'recurse' => param_hash[:purge], 'purge' => param_hash[:purge] ) end it do is_expected.to contain_class('sudo::package').with( 'package' => 'sudo', 'package_ensure' => param_hash[:package_ensure], 'package_source' => 'http://www.sudo.ws/sudo/dist/packages/AIX/5.3/sudo-1.8.27-1.aix53.rpm' 'package_provider_override' => param_hash[:package_provider_override] ) end end describe 'on supported osfamily: Solaris 10' do let :facts do { - :operatingsystem => 'Solaris', - :osfamily => 'Solaris', - :kernelrelease => '5.10', - :puppetversion => '3.7.0', - :hardwareisa => 'i386' + os: { + 'family' => 'Solaris', + 'name' => 'Solaris', + 'hardware' => 'i386', + }, + kernelrelease: '5.10', + puppetversion: '3.7.0', } end it { is_expected.to contain_class('sudo::params') } it do is_expected.to contain_file('/etc/sudoers').with( 'ensure' => 'present', 'owner' => 'root', 'group' => 'root', 'mode' => '0440', 'replace' => param_hash[:config_file_replace] ) end it do is_expected.to contain_file('/etc/sudoers.d').with( 'ensure' => 'directory', 'owner' => 'root', 'group' => 'root', 'mode' => '0550', 'recurse' => param_hash[:purge], 'purge' => param_hash[:purge] ) end it do is_expected.to contain_class('sudo::package').with( 'package' => 'TCMsudo', 'package_ensure' => param_hash[:package_ensure], 'package_source' => 'http://www.sudo.ws/sudo/dist/packages/Solaris/10/TCMsudo-1.8.9p5-i386.pkg.gz', 'package_admin_file' => '/var/sadm/install/admin/puppet' ) end context 'when package is set' do let :params do { - :package => 'mysudo' + package: 'mysudo' } end it do is_expected.to contain_class('sudo::package').with( 'package' => 'mysudo' - ) + ) end end end describe 'on supported osfamily: Solaris 11' do let :facts do { - :operatingsystem => 'Solaris', - :osfamily => 'Solaris', - :kernelrelease => '5.11', - :puppetversion => '3.7.0' + os: { + 'family' => 'Solaris', + 'name' => 'Solaris', + }, + kernelrelease: '5.11', + puppetversion: '3.7.0' } end it { is_expected.to contain_class('sudo::params') } it do is_expected.to contain_file('/etc/sudoers').with( 'ensure' => 'present', 'owner' => 'root', 'group' => 'root', 'mode' => '0440', 'replace' => param_hash[:config_file_replace] ) end it do is_expected.to contain_file('/etc/sudoers.d').with( 'ensure' => 'directory', 'owner' => 'root', 'group' => 'root', 'mode' => '0550', 'recurse' => param_hash[:purge], 'purge' => param_hash[:purge] ) end it do is_expected.to contain_class('sudo::package').with( 'package' => 'pkg://solaris/security/sudo', 'package_ensure' => param_hash[:package_ensure] ) end end end end end diff --git a/spec/defines/sudo_spec.rb b/spec/defines/sudo_spec.rb index ca7aa8c..0b9313c 100644 --- a/spec/defines/sudo_spec.rb +++ b/spec/defines/sudo_spec.rb @@ -1,207 +1,238 @@ require 'spec_helper' -describe 'sudo::conf', :type => :define do +describe 'sudo::conf', type: :define do let(:title) { 'admins' } let(:filename) { '10_admins' } let(:file_path) { '/etc/sudoers.d/10_admins' } let :facts do { + os: { + 'family' => 'Debian', + 'name' => 'Debian', + 'release' => { + 'full' => '7.0', + 'major' => '7', + }, + }, lsbdistcodename: 'wheezy', - operatingsystemmajrelease: '7', - operatingsystem: 'Debian', - osfamily: 'Debian', puppetversion: '3.7.0' } end let :params do { priority: 10, content: '%admins ALL=(ALL) NOPASSWD: ALL', sudo_config_dir: '/etc/sudoers.d' } end describe 'when creating a sudo entry' do it do is_expected.to contain_sudo__conf('admins').with( priority: params[:priority], content: params[:content] ) end it do is_expected.to contain_file(filename).with( ensure: 'present', content: "# This file is managed by Puppet; changes may be overwritten\n%admins ALL=(ALL) NOPASSWD: ALL\n", owner: 'root', group: 'root', path: file_path, mode: '0440' ) end it do is_expected.to contain_exec("sudo-syntax-check for file #{params[:sudo_config_dir]}/#{params[:priority]}_#{title}").with( command: "visudo -c || ( rm -f '#{params[:sudo_config_dir]}/#{params[:priority]}_#{title}' && exit 1)", refreshonly: 'true' ) end it { is_expected.to contain_file(filename).that_notifies("Exec[sudo-syntax-check for file #{params[:sudo_config_dir]}/#{params[:priority]}_#{title}]") } it { is_expected.not_to contain_file(filename).that_requires("Exec[sudo-syntax-check for file #{params[:sudo_config_dir]}/#{params[:priority]}_#{title}]") } end describe 'when creating a sudo entry with single number priority' do let(:filename) { '05_admins' } let(:file_path) { '/etc/sudoers.d/05_admins' } let :params do { priority: 5, content: '%admins ALL=(ALL) NOPASSWD: ALL', sudo_config_dir: '/etc/sudoers.d' } end it do is_expected.to contain_sudo__conf('admins').with( priority: params[:priority], content: params[:content] ) end it do is_expected.to contain_file(filename).with( ensure: 'present', content: "# This file is managed by Puppet; changes may be overwritten\n%admins ALL=(ALL) NOPASSWD: ALL\n", owner: 'root', group: 'root', path: file_path, mode: '0440' ) end it do is_expected.to contain_exec("sudo-syntax-check for file #{params[:sudo_config_dir]}/0#{params[:priority]}_#{title}").with( command: "visudo -c || ( rm -f '#{params[:sudo_config_dir]}/0#{params[:priority]}_#{title}' && exit 1)", refreshonly: 'true' ) end it { is_expected.to contain_file(filename).that_notifies("Exec[sudo-syntax-check for file #{params[:sudo_config_dir]}/0#{params[:priority]}_#{title}]") } it { is_expected.not_to contain_file(filename).that_requires("Exec[sudo-syntax-check for file #{params[:sudo_config_dir]}/0#{params[:priority]}_#{title}]") } end describe 'when creating a sudo entry with whitespace in name' do let(:title) { 'admins hq' } let(:filename) { '05_admins hq' } let(:file_path) { '/etc/sudoers.d/05_admins_hq' } let :params do { priority: 5, content: '%admins_hq ALL=(ALL) NOPASSWD: ALL', sudo_config_dir: '/etc/sudoers.d' } end it do - is_expected.to contain_sudo__conf('admins hq').with(:priority => params[:priority], - :content => params[:content]) + is_expected.to contain_sudo__conf('admins hq').with(priority: params[:priority], + content: params[:content]) end it do is_expected.to contain_file(filename).with( ensure: 'present', content: "# This file is managed by Puppet; changes may be overwritten\n%admins_hq ALL=(ALL) NOPASSWD: ALL\n", owner: 'root', group: 'root', path: file_path, mode: '0440' ) end it do is_expected.to contain_exec("sudo-syntax-check for file #{params[:sudo_config_dir]}/0#{params[:priority]}_#{title}").with( command: "visudo -c || ( rm -f '#{file_path}' && exit 1)", refreshonly: 'true' ) end it { is_expected.to contain_file(filename).that_notifies("Exec[sudo-syntax-check for file #{params[:sudo_config_dir]}/0#{params[:priority]}_#{title}]") } it { is_expected.not_to contain_file(filename).that_requires("Exec[sudo-syntax-check for file #{params[:sudo_config_dir]}/0#{params[:priority]}_#{title}]") } end describe 'when removing an sudo entry' do let :params do { ensure: 'absent', priority: 10, content: '%admins ALL=(ALL) NOPASSWD: ALL', sudo_config_dir: '/etc/sudoers.d' } end it do is_expected.to contain_file(filename).with( ensure: 'absent', content: "# This file is managed by Puppet; changes may be overwritten\n%admins ALL=(ALL) NOPASSWD: ALL\n", owner: 'root', group: 'root', path: file_path, mode: '0440' ) end end describe 'when removing an sudo entry with single number priority' do let :params do { ensure: 'absent', priority: 5, content: '%admins ALL=(ALL) NOPASSWD: ALL', sudo_config_dir: '/etc/sudoers.d' } end let(:filename) { '05_admins' } let(:file_path) { '/etc/sudoers.d/05_admins' } it do is_expected.to contain_file(filename).with( ensure: 'absent', content: "# This file is managed by Puppet; changes may be overwritten\n%admins ALL=(ALL) NOPASSWD: ALL\n", owner: 'root', group: 'root', path: file_path, mode: '0440' ) end end describe 'when adding a sudo entry with array content' do let :params do { content: [ '%admins ALL=(ALL) NOPASSWD: ALL', '%wheel ALL=(ALL) NOPASSWD: ALL' ] } end let(:filename) { '10_admins' } let(:file_path) { '/etc/sudoers.d/10_admins' } it do is_expected.to contain_file(filename).with( ensure: 'present', content: "# This file is managed by Puppet; changes may be overwritten\n%admins ALL=(ALL) NOPASSWD: ALL\n%wheel ALL=(ALL) NOPASSWD: ALL\n", owner: 'root', group: 'root', path: file_path, mode: '0440' ) end end + + describe 'when adding a sudo entry with a suffix _foobar' do + let :pre_condition do + 'class{"sudo": suffix => "_foobar"}' + end + + let :params do + { + ensure: 'absent', + priority: 10, + content: '%admins ALL=(ALL) NOPASSWD: ALL', + sudo_config_dir: '/etc/sudoers.d', + } + end + + it do + is_expected.to contain_file("#{filename}_foobar").with( + ensure: 'absent', + content: "# This file is managed by Puppet; changes may be overwritten\n%admins ALL=(ALL) NOPASSWD: ALL\n", + owner: 'root', + group: 'root', + path: "#{file_path}_foobar", + mode: '0440' + ) + end + end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 0b9b0e4..d266f6b 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,24 +1,18 @@ -require 'puppetlabs_spec_helper/module_spec_helper' +# This file is managed via modulesync +# https://github.com/voxpupuli/modulesync +# https://github.com/voxpupuli/modulesync_config -RSpec.configure do |c| - c.include PuppetlabsSpec::Files +# puppetlabs_spec_helper will set up coverage if the env variable is set. +# We want to do this if lib exists and it hasn't been explicitly set. +ENV['COVERAGE'] ||= 'yes' if Dir.exist?(File.expand_path('../../lib', __FILE__)) - c.before do - # Ensure that we don't accidentally cache facts and environment - # between test cases. - Facter.clear - Facter.clear_messages +require 'voxpupuli/test/spec_helper' - # Store any environment variables away to be restored later - @old_env = {} - ENV.each_key { |k| @old_env[k] = ENV[k] } - - if Gem::Version.new(`puppet --version`) >= Gem::Version.new('3.5') - Puppet.settings[:strict_variables] = true +if File.exist?(File.join(__dir__, 'default_module_facts.yml')) + facts = YAML.safe_load(File.read(File.join(__dir__, 'default_module_facts.yml'))) + if facts + facts.each do |name, value| + add_custom_fact name.to_sym, value end end - - c.after do - PuppetlabsSpec::Files.cleanup - end end diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb index 57f4e26..bec34fd 100644 --- a/spec/spec_helper_acceptance.rb +++ b/spec/spec_helper_acceptance.rb @@ -1,34 +1,6 @@ -require 'beaker-rspec' +# This file is completely managed via modulesync +require 'voxpupuli/acceptance/spec_helper_acceptance' -# Install Puppet -unless ENV['RS_PROVISION'] == 'no' - # This will install the latest available package on el and deb based - # systems fail on windows and osx, and install via gem on other *nixes - foss_opts = { :default_action => 'gem_install' } +configure_beaker - default.is_pe? ? install_pe : install_puppet(foss_opts) - - hosts.each do |host| - on host, "mkdir -p #{host['distmoduledir']}" - end -end - -UNSUPPORTED_PLATFORMS = ['windows'].freeze - -RSpec.configure do |c| - # Project root - proj_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) - - # Readable test descriptions - c.formatter = :documentation - - # Configure all nodes in nodeset - c.before :suite do - # Install module and dependencies - puppet_module_install(:source => proj_root, :module_name => 'sudo') - hosts.each do |_host| - shell("/bin/touch #{default['puppetpath']}/hiera.yaml") - shell('puppet module install puppetlabs-stdlib --version >= 2.6.0', :acceptable_exit_codes => [0]) - end - end -end +Dir['./spec/support/acceptance/**/*.rb'].sort.each { |f| require f } diff --git a/templates/sudoers.aix.erb b/templates/sudoers.aix.erb index b1e4fb3..3c322fb 100644 --- a/templates/sudoers.aix.erb +++ b/templates/sudoers.aix.erb @@ -1,105 +1,107 @@ # file managed by puppet (unless config_file_replace=false) # ## sudoers file. ## ## This file MUST be edited with the 'visudo' command as root. ## Failure to use 'visudo' may result in syntax or file permission errors ## that prevent sudo from running. ## ## See the sudoers man page for the details on how to write a sudoers file. ## ## ## Host alias specification ## ## Groups of machines. These may include host names (optionally with wildcards), ## IP addresses, network numbers or netgroups. # Host_Alias WEBSERVERS = www1, www2, www3 ## ## User alias specification ## ## Groups of users. These may consist of user names, uids, Unix groups, ## or netgroups. # User_Alias ADMINS = millert, dowdy, mikef ## ## Cmnd alias specification ## ## Groups of commands. Often used to group related commands together. # Cmnd_Alias PROCESSES = /usr/bin/nice, /bin/kill, /usr/bin/renice, \ # /usr/bin/pkill, /usr/bin/top ## ## Defaults specification ## ## You may wish to keep some of the following environment variables ## when running commands via sudo. ## ## Locale settings # Defaults env_keep += "LANG LANGUAGE LINGUAS LC_* _XKB_CHARSET" ## ## Run X applications through sudo; HOME is used to find the ## .Xauthority file. Note that other programs use HOME to find ## configuration files and this may lead to privilege escalation! # Defaults env_keep += "HOME" ## ## X11 resource path settings # Defaults env_keep += "XAPPLRESDIR XFILESEARCHPATH XUSERFILESEARCHPATH" ## ## Desktop path settings # Defaults env_keep += "QTDIR KDEDIR" ## ## Allow sudo-run commands to inherit the callers' ConsoleKit session # Defaults env_keep += "XDG_SESSION_COOKIE" ## ## Uncomment to enable special input methods. Care should be taken as ## this may allow users to subvert the command being run via sudo. # Defaults env_keep += "XMODIFIERS GTK_IM_MODULE QT_IM_MODULE QT_IM_SWITCHER" ## ## Uncomment to enable logging of a command's output, except for ## sudoreplay and reboot. Use sudoreplay to play back logged sessions. # Defaults log_output # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!/sbin/reboot !log_output <% if @use_sudoreplay %> Defaults log_output Defaults!/usr/bin/sudoreplay !log_output <% if @sudoreplay_discard %> <% @sudoreplay_discard.each do |command| -%> Defaults!<%= command %> !log_output <% end -%> <% end -%> <% end -%> ## ## Runas alias specification ## ## ## User privilege specification ## root ALL=(ALL) ALL +<% if @wheel_config == 'password' %> ## Uncomment to allow members of group wheel to execute any command -# %wheel ALL=(ALL) ALL - +%wheel ALL=(ALL) ALL +<% elsif @wheel_config == 'nopassword' %> ## Same thing without a password -# %wheel ALL=(ALL) NOPASSWD: ALL +%wheel ALL=(ALL) NOPASSWD: ALL +<% end %> ## Uncomment to allow members of group sudo to execute any command # %sudo ALL=(ALL) ALL ## Uncomment to allow any user to run sudo if they know the password ## of the user they are running the command as (root by default). # Defaults targetpw # Ask for the password of the target user # ALL ALL=(ALL) ALL # WARNING: only use this together with 'Defaults targetpw' ## Read drop-in files ## (the '#' here does not indicate a comment) #includedir <%= @config_dir %> <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> diff --git a/templates/sudoers.archlinux.erb b/templates/sudoers.archlinux.erb index 1782f8c..3c322fb 100644 --- a/templates/sudoers.archlinux.erb +++ b/templates/sudoers.archlinux.erb @@ -1,105 +1,107 @@ # file managed by puppet (unless config_file_replace=false) # ## sudoers file. ## ## This file MUST be edited with the 'visudo' command as root. ## Failure to use 'visudo' may result in syntax or file permission errors ## that prevent sudo from running. ## ## See the sudoers man page for the details on how to write a sudoers file. ## ## ## Host alias specification ## ## Groups of machines. These may include host names (optionally with wildcards), ## IP addresses, network numbers or netgroups. # Host_Alias WEBSERVERS = www1, www2, www3 ## ## User alias specification ## ## Groups of users. These may consist of user names, uids, Unix groups, ## or netgroups. # User_Alias ADMINS = millert, dowdy, mikef ## ## Cmnd alias specification ## ## Groups of commands. Often used to group related commands together. # Cmnd_Alias PROCESSES = /usr/bin/nice, /bin/kill, /usr/bin/renice, \ # /usr/bin/pkill, /usr/bin/top ## ## Defaults specification ## ## You may wish to keep some of the following environment variables ## when running commands via sudo. ## ## Locale settings # Defaults env_keep += "LANG LANGUAGE LINGUAS LC_* _XKB_CHARSET" ## ## Run X applications through sudo; HOME is used to find the ## .Xauthority file. Note that other programs use HOME to find ## configuration files and this may lead to privilege escalation! # Defaults env_keep += "HOME" ## ## X11 resource path settings # Defaults env_keep += "XAPPLRESDIR XFILESEARCHPATH XUSERFILESEARCHPATH" ## ## Desktop path settings # Defaults env_keep += "QTDIR KDEDIR" ## ## Allow sudo-run commands to inherit the callers' ConsoleKit session # Defaults env_keep += "XDG_SESSION_COOKIE" ## ## Uncomment to enable special input methods. Care should be taken as ## this may allow users to subvert the command being run via sudo. # Defaults env_keep += "XMODIFIERS GTK_IM_MODULE QT_IM_MODULE QT_IM_SWITCHER" ## ## Uncomment to enable logging of a command's output, except for ## sudoreplay and reboot. Use sudoreplay to play back logged sessions. # Defaults log_output # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!/sbin/reboot !log_output <% if @use_sudoreplay %> Defaults log_output Defaults!/usr/bin/sudoreplay !log_output <% if @sudoreplay_discard %> <% @sudoreplay_discard.each do |command| -%> Defaults!<%= command %> !log_output <% end -%> <% end -%> <% end -%> ## ## Runas alias specification ## ## ## User privilege specification ## root ALL=(ALL) ALL +<% if @wheel_config == 'password' %> ## Uncomment to allow members of group wheel to execute any command -#%wheel ALL=(ALL) ALL - +%wheel ALL=(ALL) ALL +<% elsif @wheel_config == 'nopassword' %> ## Same thing without a password -# %wheel ALL=(ALL) NOPASSWD: ALL +%wheel ALL=(ALL) NOPASSWD: ALL +<% end %> ## Uncomment to allow members of group sudo to execute any command # %sudo ALL=(ALL) ALL ## Uncomment to allow any user to run sudo if they know the password ## of the user they are running the command as (root by default). # Defaults targetpw # Ask for the password of the target user # ALL ALL=(ALL) ALL # WARNING: only use this together with 'Defaults targetpw' ## Read drop-in files ## (the '#' here does not indicate a comment) #includedir <%= @config_dir %> <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> diff --git a/templates/sudoers.darwin.erb b/templates/sudoers.darwin.erb index 124c608..f8e5487 100644 --- a/templates/sudoers.darwin.erb +++ b/templates/sudoers.darwin.erb @@ -1,61 +1,63 @@ # file managed by puppet (unless config_file_replace=false) # # sudoers file. # # This file MUST be edited with the 'visudo' command as root. # Failure to use 'visudo' may result in syntax or file permission errors # that prevent sudo from running. # # See the sudoers man page for the details on how to write a sudoers file. # # Host alias specification # User alias specification # Cmnd alias specification # Defaults specification Defaults env_reset Defaults env_keep += "BLOCKSIZE" Defaults env_keep += "COLORFGBG COLORTERM" Defaults env_keep += "__CF_USER_TEXT_ENCODING" Defaults env_keep += "CHARSET LANG LANGUAGE LC_ALL LC_COLLATE LC_CTYPE" Defaults env_keep += "LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME" Defaults env_keep += "LINES COLUMNS" Defaults env_keep += "LSCOLORS" Defaults env_keep += "SSH_AUTH_SOCK" Defaults env_keep += "TZ" Defaults env_keep += "DISPLAY XAUTHORIZATION XAUTHORITY" Defaults env_keep += "EDITOR VISUAL" Defaults env_keep += "HOME MAIL" <% if @use_sudoreplay %> Defaults log_output Defaults!/usr/bin/sudoreplay !log_output <% if @sudoreplay_discard %> <% @sudoreplay_discard.each do |command| -%> Defaults!<%= command %> !log_output <% end -%> <% end -%> <% end -%> # Runas alias specification # User privilege specification root ALL=(ALL) ALL %admin ALL=(ALL) ALL +<% if @wheel_config == 'password' %> # Uncomment to allow people in group wheel to run all commands -# %wheel ALL=(ALL) ALL - +%wheel ALL=(ALL) ALL +<% elsif @wheel_config == 'nopassword' %> # Same thing without a password -# %wheel ALL=(ALL) NOPASSWD: ALL +%wheel ALL=(ALL) NOPASSWD: ALL +<% end %> # Samples # %users ALL=/sbin/mount /cdrom,/sbin/umount /cdrom # %users localhost=/sbin/shutdown -h now #includedir <%= @config_dir %> <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> diff --git a/templates/sudoers.freebsd.erb b/templates/sudoers.freebsd.erb index 1cd94d1..02847e1 100644 --- a/templates/sudoers.freebsd.erb +++ b/templates/sudoers.freebsd.erb @@ -1,120 +1,122 @@ # file managed by puppet (unless config_file_replace=false) # ## sudoers file. ## ## This file MUST be edited with the 'visudo' command as root. ## Failure to use 'visudo' may result in syntax or file permission errors ## that prevent sudo from running. ## ## See the sudoers man page for the details on how to write a sudoers file. ## ## ## Host alias specification ## ## Groups of machines. These may include host names (optionally with wildcards), ## IP addresses, network numbers or netgroups. # Host_Alias WEBSERVERS = www1, www2, www3 ## ## User alias specification ## ## Groups of users. These may consist of user names, uids, Unix groups, ## or netgroups. # User_Alias ADMINS = millert, dowdy, mikef ## ## Cmnd alias specification ## ## Groups of commands. Often used to group related commands together. # Cmnd_Alias PROCESSES = /usr/bin/nice, /bin/kill, /usr/bin/renice, \ # /usr/bin/pkill, /usr/bin/top # Cmnd_Alias REBOOT = /sbin/halt, /sbin/reboot, /sbin/poweroff ## ## Defaults specification ## ## Uncomment if needed to preserve environmental variables related to the ## FreeBSD pkg utility and fetch. # Defaults env_keep += "PKG_CACHEDIR PKG_DBDIR FTP_PASSIVE_MODE" ## ## Additionally uncomment if needed to preserve environmental variables ## related to portupgrade # Defaults env_keep += "PORTSDIR PORTS_INDEX PORTS_DBDIR PACKAGES PKGTOOLS_CONF" ## ## You may wish to keep some of the following environment variables ## when running commands via sudo. ## ## Locale settings # Defaults env_keep += "LANG LANGUAGE LINGUAS LC_* _XKB_CHARSET" ## ## Run X applications through sudo; HOME is used to find the ## .Xauthority file. Note that other programs use HOME to find ## configuration files and this may lead to privilege escalation! # Defaults env_keep += "HOME" ## ## X11 resource path settings # Defaults env_keep += "XAPPLRESDIR XFILESEARCHPATH XUSERFILESEARCHPATH" ## ## Desktop path settings # Defaults env_keep += "QTDIR KDEDIR" ## ## Allow sudo-run commands to inherit the callers' ConsoleKit session # Defaults env_keep += "XDG_SESSION_COOKIE" ## ## Uncomment to enable special input methods. Care should be taken as ## this may allow users to subvert the command being run via sudo. # Defaults env_keep += "XMODIFIERS GTK_IM_MODULE QT_IM_MODULE QT_IM_SWITCHER" ## ## Uncomment to use a hard-coded PATH instead of the user's to find commands # Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/puppetlabs/bin" ## ## Uncomment to send mail if the user does not enter the correct password. # Defaults mail_badpass ## ## Uncomment to enable logging of a command's output, except for ## sudoreplay and reboot. Use sudoreplay to play back logged sessions. # Defaults log_output # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!REBOOT !log_output <% if @use_sudoreplay %> Defaults log_output Defaults!/usr/local/bin/sudoreplay !log_output <% if @sudoreplay_discard %> <% @sudoreplay_discard.each do |command| -%> Defaults!<%= command %> !log_output <% end -%> <% end -%> <% end -%> ## ## Runas alias specification ## ## ## User privilege specification ## root ALL=(ALL) ALL +<% if @wheel_config == 'password' %> ## Uncomment to allow members of group wheel to execute any command -# %wheel ALL=(ALL) ALL - +%wheel ALL=(ALL) ALL +<% elsif @wheel_config == 'nopassword' %> ## Same thing without a password -# %wheel ALL=(ALL) NOPASSWD: ALL +%wheel ALL=(ALL) NOPASSWD: ALL +<% end %> ## Uncomment to allow members of group sudo to execute any command # %sudo ALL=(ALL) ALL ## Uncomment to allow any user to run sudo if they know the password ## of the user they are running the command as (root by default). # Defaults targetpw # Ask for the password of the target user # ALL ALL=(ALL) ALL # WARNING: only use this together with 'Defaults targetpw' ## Read drop-in files ## (the '#' here does not indicate a comment) #includedir <%= @config_dir %> <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> diff --git a/templates/sudoers.gentoo.erb b/templates/sudoers.gentoo.erb index 0d88832..edd7176 100644 --- a/templates/sudoers.gentoo.erb +++ b/templates/sudoers.gentoo.erb @@ -1,106 +1,108 @@ # file managed by puppet (unless config_file_replace=false) # ## sudoers file. ## ## This file MUST be edited with the 'visudo' command as root. ## Failure to use 'visudo' may result in syntax or file permission errors ## that prevent sudo from running. ## ## See the sudoers man page for the details on how to write a sudoers file. ## ## ## Host alias specification ## ## Groups of machines. These may include host names (optionally with wildcards), ## IP addresses, network numbers or netgroups. # Host_Alias WEBSERVERS = www1, www2, www3 ## ## User alias specification ## ## Groups of users. These may consist of user names, uids, Unix groups, ## or netgroups. # User_Alias ADMINS = millert, dowdy, mikef ## ## Cmnd alias specification ## ## Groups of commands. Often used to group related commands together. # Cmnd_Alias PROCESSES = /usr/bin/nice, /bin/kill, /usr/bin/renice, \ # /usr/bin/pkill, /usr/bin/top # Cmnd_Alias REBOOT = /sbin/halt, /sbin/reboot, /sbin/poweroff ## ## Defaults specification ## ## You may wish to keep some of the following environment variables ## when running commands via sudo. ## ## Locale settings # Defaults env_keep += "LANG LANGUAGE LINGUAS LC_* _XKB_CHARSET" ## ## Run X applications through sudo; HOME is used to find the ## .Xauthority file. Note that other programs use HOME to find ## configuration files and this may lead to privilege escalation! # Defaults env_keep += "HOME" ## ## X11 resource path settings # Defaults env_keep += "XAPPLRESDIR XFILESEARCHPATH XUSERFILESEARCHPATH" ## ## Desktop path settings # Defaults env_keep += "QTDIR KDEDIR" ## ## Allow sudo-run commands to inherit the callers' ConsoleKit session # Defaults env_keep += "XDG_SESSION_COOKIE" ## ## Uncomment to enable special input methods. Care should be taken as ## this may allow users to subvert the command being run via sudo. # Defaults env_keep += "XMODIFIERS GTK_IM_MODULE QT_IM_MODULE QT_IM_SWITCHER" ## ## Uncomment to enable logging of a command's output, except for ## sudoreplay and reboot. Use sudoreplay to play back logged sessions. # Defaults log_output # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!REBOOT !log_output <% if @use_sudoreplay %> Defaults log_output Defaults!/usr/bin/sudoreplay !log_output <% if @sudoreplay_discard %> <% @sudoreplay_discard.each do |command| -%> Defaults!<%= command %> !log_output <% end -%> <% end -%> <% end -%> ## ## Runas alias specification ## ## ## User privilege specification ## root ALL=(ALL) ALL +<% if @wheel_config == 'password' %> ## Uncomment to allow members of group wheel to execute any command -# %wheel ALL=(ALL) ALL - +%wheel ALL=(ALL) ALL +<% elsif @wheel_config == 'nopassword' %> ## Same thing without a password -# %wheel ALL=(ALL) NOPASSWD: ALL +%wheel ALL=(ALL) NOPASSWD: ALL +<% end %> ## Uncomment to allow members of group sudo to execute any command # %sudo ALL=(ALL) ALL ## Uncomment to allow any user to run sudo if they know the password ## of the user they are running the command as (root by default). # Defaults targetpw # Ask for the password of the target user # ALL ALL=(ALL) ALL # WARNING: only use this together with 'Defaults targetpw' ## Read drop-in files ## (the '#' here does not indicate a comment) #includedir <%= @config_dir %> <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> diff --git a/templates/sudoers.olddebian.erb b/templates/sudoers.olddebian.erb index ecaeada..5db890c 100644 --- a/templates/sudoers.olddebian.erb +++ b/templates/sudoers.olddebian.erb @@ -1,105 +1,107 @@ # file managed by puppet (unless config_file_replace=false) # ## sudoers file. ## ## This file MUST be edited with the 'visudo' command as root. ## Failure to use 'visudo' may result in syntax or file permission errors ## that prevent sudo from running. ## ## See the sudoers man page for the details on how to write a sudoers file. ## ## ## Host alias specification ## ## Groups of machines. These may include host names (optionally with wildcards), ## IP addresses, network numbers or netgroups. # Host_Alias WEBSERVERS = www1, www2, www3 ## ## User alias specification ## ## Groups of users. These may consist of user names, uids, Unix groups, ## or netgroups. # User_Alias ADMINS = millert, dowdy, mikef ## ## Cmnd alias specification ## ## Groups of commands. Often used to group related commands together. # Cmnd_Alias PROCESSES = /usr/bin/nice, /bin/kill, /usr/bin/renice, \ # /usr/bin/pkill, /usr/bin/top ## ## Defaults specification ## ## You may wish to keep some of the following environment variables ## when running commands via sudo. ## ## Locale settings Defaults env_keep += "LANG LANGUAGE LINGUAS LC_* _XKB_CHARSET" ## ## Run X applications through sudo; HOME is used to find the ## .Xauthority file. Note that other programs use HOME to find ## configuration files and this may lead to privilege escalation! # Defaults env_keep += "HOME" ## ## X11 resource path settings Defaults env_keep += "XAPPLRESDIR XFILESEARCHPATH XUSERFILESEARCHPATH" ## ## Desktop path settings # Defaults env_keep += "QTDIR KDEDIR" ## ## Allow sudo-run commands to inherit the callers' ConsoleKit session # Defaults env_keep += "XDG_SESSION_COOKIE" ## ## Uncomment to enable special input methods. Care should be taken as ## this may allow users to subvert the command being run via sudo. # Defaults env_keep += "XMODIFIERS GTK_IM_MODULE QT_IM_MODULE QT_IM_SWITCHER" ## ## Uncomment to enable logging of a command's output, except for ## sudoreplay and reboot. Use sudoreplay to play back logged sessions. # Defaults log_output # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!/sbin/reboot !log_output <% if @use_sudoreplay %> Defaults log_output Defaults!/usr/bin/sudoreplay !log_output <% if @sudoreplay_discard %> <% @sudoreplay_discard.each do |command| -%> Defaults!<%= command %> !log_output <% end -%> <% end -%> <% end -%> ## ## Runas alias specification ## ## ## User privilege specification ## root ALL=(ALL) ALL +<% if @wheel_config == 'password' %> ## Uncomment to allow members of group wheel to execute any command -# %wheel ALL=(ALL) ALL - +%wheel ALL=(ALL) ALL +<% elsif @wheel_config == 'nopassword' %> ## Same thing without a password -# %wheel ALL=(ALL) NOPASSWD: ALL +%wheel ALL=(ALL) NOPASSWD: ALL +<% end %> ## Uncomment to allow members of group sudo to execute any command # %sudo ALL=(ALL) ALL ## Uncomment to allow any user to run sudo if they know the password ## of the user they are running the command as (root by default). # Defaults targetpw # Ask for the password of the target user # ALL ALL=(ALL) ALL # WARNING: only use this together with 'Defaults targetpw' ## Read drop-in files ## (the '#' here does not indicate a comment) #includedir <%= @config_dir %> <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> diff --git a/templates/sudoers.omnios.erb b/templates/sudoers.omnios.erb index 632abb7..5a21d9c 100644 --- a/templates/sudoers.omnios.erb +++ b/templates/sudoers.omnios.erb @@ -1,106 +1,108 @@ # file managed by puppet (unless config_file_replace=false) # ## sudoers file. ## ## This file MUST be edited with the 'visudo' command as root. ## Failure to use 'visudo' may result in syntax or file permission errors ## that prevent sudo from running. ## ## See the sudoers man page for the details on how to write a sudoers file. ## ## ## Host alias specification ## ## Groups of machines. These may include host names (optionally with wildcards), ## IP addresses, network numbers or netgroups. # Host_Alias WEBSERVERS = www1, www2, www3 ## ## User alias specification ## ## Groups of users. These may consist of user names, uids, Unix groups, ## or netgroups. # User_Alias ADMINS = millert, dowdy, mikef ## ## Cmnd alias specification ## ## Groups of commands. Often used to group related commands together. # Cmnd_Alias PROCESSES = /usr/bin/nice, /bin/kill, /usr/bin/renice, \ # /usr/bin/pkill, /usr/bin/top ## ## Defaults specification ## ## You may wish to keep some of the following environment variables ## when running commands via sudo. ## ## Locale settings # Defaults env_keep += "LANG LANGUAGE LINGUAS LC_* _XKB_CHARSET" ## ## Run X applications through sudo; HOME is used to find the ## .Xauthority file. Note that other programs use HOME to find ## configuration files and this may lead to privilege escalation! # Defaults env_keep += "HOME" ## ## X11 resource path settings # Defaults env_keep += "XAPPLRESDIR XFILESEARCHPATH XUSERFILESEARCHPATH" ## ## Desktop path settings # Defaults env_keep += "QTDIR KDEDIR" ## ## Allow sudo-run commands to inherit the callers' ConsoleKit session # Defaults env_keep += "XDG_SESSION_COOKIE" ## ## Uncomment to enable special input methods. Care should be taken as ## this may allow users to subvert the command being run via sudo. # Defaults env_keep += "XMODIFIERS GTK_IM_MODULE QT_IM_MODULE QT_IM_SWITCHER" ## ## Uncomment to enable logging of a command's output, except for ## sudoreplay and reboot. Use sudoreplay to play back logged sessions. # Defaults log_output # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!/sbin/reboot !log_output <% if @use_sudoreplay %> Defaults log_output Defaults!/usr/bin/sudoreplay !log_output <% if @sudoreplay_discard %> <% @sudoreplay_discard.each do |command| -%> Defaults!<%= command %> !log_output <% end -%> <% end -%> <% end -%> ## ## Runas alias specification ## ## ## User privilege specification ## root ALL=(ALL) ALL +<% if @wheel_config == 'password' %> ## Uncomment to allow members of group wheel to execute any command -# %wheel ALL=(ALL) ALL - +%wheel ALL=(ALL) ALL +<% elsif @wheel_config == 'nopassword' %> ## Same thing without a password -# %wheel ALL=(ALL) NOPASSWD: ALL +%wheel ALL=(ALL) NOPASSWD: ALL +<% end %> ## Uncomment to allow members of group sudo to execute any command # %sudo ALL=(ALL) ALL ## Uncomment to allow any user to run sudo if they know the password ## of the user they are running the command as (root by default). # Defaults targetpw # Ask for the password of the target user # ALL ALL=(ALL) ALL # WARNING: only use this together with 'Defaults targetpw' ## Read drop-in files ## (the '#' here does not indicate a comment) #includedir <%= @config_dir %> <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> diff --git a/templates/sudoers.openbsd.erb b/templates/sudoers.openbsd.erb index 65a6915..709536b 100644 --- a/templates/sudoers.openbsd.erb +++ b/templates/sudoers.openbsd.erb @@ -1,67 +1,69 @@ # file managed by puppet (unless config_file_replace=false) # # sudoers file. # # This file MUST be edited with the 'visudo' command as root. # Failure to use 'visudo' may result in syntax or file permission errors # that prevent sudo from running. # # See the sudoers man page for the details on how to write a sudoers file. # # Host alias specification # User alias specification # Cmnd alias specification # Defaults specification Defaults env_keep +="FTPMODE PKG_CACHE PKG_PATH SM_PATH SSH_AUTH_SOCK" # Non-exhaustive list of variables needed to build release(8) and ports(7) Defaults:%wsrc env_keep +="DESTDIR DISTDIR FETCH_CMD FLAVOR GROUP MAKE MAKECONF" Defaults:%wsrc env_keep +="MULTI_PACKAGES NOMAN OKAY_FILES OWNER PKG_DBDIR" Defaults:%wsrc env_keep +="PKG_DESTDIR PKG_TMPDIR PORTSDIR RELEASEDIR SHARED_ONLY" Defaults:%wsrc env_keep +="SUBPACKAGE WRKOBJDIR SUDO_PORT_V1" # Uncomment to preserve the default proxy host variable #Defaults env_keep +="ftp_proxy http_proxy" # Uncomment to disable the lecture the first time you run sudo #Defaults !lecture # Uncomment to preserve the environment for users in group wheel #Defaults:%wheel !env_reset <% if @use_sudoreplay %> Defaults log_output Defaults!/usr/bin/sudoreplay !log_output <% if @sudoreplay_discard %> <% @sudoreplay_discard.each do |command| -%> Defaults!<%= command %> !log_output <% end -%> <% end -%> <% end -%> # Runas alias specification # User privilege specification root ALL=(ALL) SETENV: ALL +<% if @wheel_config == 'password' %> # Uncomment to allow people in group wheel to run all commands # and set environment variables. -# %wheel ALL=(ALL) SETENV: ALL - +%wheel ALL=(ALL) SETENV: ALL +<% elsif @wheel_config == 'nopassword' %> # Same thing without a password -# %wheel ALL=(ALL) NOPASSWD: SETENV: ALL +%wheel ALL=(ALL) NOPASSWD: SETENV: ALL +<% end %> # Samples # %users ALL=/sbin/mount /cdrom,/sbin/umount /cdrom # %users localhost=/sbin/shutdown -h now # Read drop-in files # the # does not mark the line as a comment #includedir <%= @config_dir %> <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> diff --git a/templates/sudoers.rhel5.erb b/templates/sudoers.rhel5.erb index 2d4209e..c3e1087 100644 --- a/templates/sudoers.rhel5.erb +++ b/templates/sudoers.rhel5.erb @@ -1,98 +1,100 @@ # file managed by puppet (unless config_file_replace=false) # ## Sudoers allows particular users to run various commands as ## the root user, without needing the root password. ## ## Examples are provided at the bottom of the file for collections ## of related commands, which can then be delegated out to particular ## users or groups. ## ## This file must be edited with the 'visudo' command. ## Host Aliases ## Groups of machines. You may prefer to use hostnames (perhap using ## wildcards for entire domains) or IP addresses instead. # Host_Alias FILESERVERS = fs1, fs2 # Host_Alias MAILSERVERS = smtp, smtp2 ## User Aliases ## These aren't often necessary, as you can use regular groups ## (ie, from files, LDAP, NIS, etc) in this file - just use %groupname ## rather than USERALIAS # User_Alias ADMINS = jsmith, mikem ## Command Aliases ## These are groups of related commands... ## Networking #Cmnd_Alias NETWORKING = /sbin/route, /sbin/ifconfig, /bin/ping, /sbin/dhclient, /usr/bin/net, /sbin/iptables, /usr/bin/rfcomm, /usr/bin/wvdial, /sbin/iwconfig, /sbin/mii-tool ## Installation and management of software #Cmnd_Alias SOFTWARE = /bin/rpm, /usr/bin/up2date, /usr/bin/yum ## Services #Cmnd_Alias SERVICES = /sbin/service, /sbin/chkconfig ## Updating the locate database #Cmnd_Alias LOCATE = /usr/bin/updatedb ## Storage #Cmnd_Alias STORAGE = /sbin/fdisk, /sbin/sfdisk, /sbin/parted, /sbin/partprobe, /bin/mount, /bin/umount ## Delegating permissions #Cmnd_Alias DELEGATING = /usr/sbin/visudo, /bin/chown, /bin/chmod, /bin/chgrp ## Processes #Cmnd_Alias PROCESSES = /bin/nice, /bin/kill, /usr/bin/kill, /usr/bin/killall ## Drivers #Cmnd_Alias DRIVERS = /sbin/modprobe # Defaults specification # Refuse to run if unable to disable echo on the tty. This setting should also be # changed in order to be able to use sudo without a tty. See requiretty above. # Defaults !visiblepw Defaults env_reset Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR \ LS_COLORS MAIL PS1 PS2 QTDIR USERNAME \ LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC \ LC_PAPER LC_TELEPHONE LC_TIME LC_ALL LANGUAGE LINGUAS \ _XKB_CHARSET XAUTHORITY" ## Next comes the main part: which users can run what software on ## which machines (the sudoers file can be shared between multiple ## systems). ## Syntax: ## ## user MACHINE=COMMANDS ## ## The COMMANDS section may have other options added to it. ## ## Allow root to run any commands anywhere root ALL=(ALL) ALL ## Allows members of the 'sys' group to run networking, software, ## service management apps and more. # %sys ALL = NETWORKING, SOFTWARE, SERVICES, STORAGE, DELEGATING, PROCESSES, LOCATE, DRIVERS +<% if @wheel_config == 'password' %> ## Allows people in group wheel to run all commands -# %wheel ALL=(ALL) ALL - +%wheel ALL=(ALL) ALL +<% elsif @wheel_config == 'nopassword' %> ## Same thing without a password -# %wheel ALL=(ALL) NOPASSWD: ALL +%wheel ALL=(ALL) NOPASSWD: ALL +<% end %> ## Allows members of the users group to mount and unmount the ## cdrom as root # %users ALL=/sbin/mount /mnt/cdrom, /sbin/umount /mnt/cdrom ## Allows members of the users group to shutdown this system # %users localhost=/sbin/shutdown -h now #includedir <%= @config_dir %> <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> diff --git a/templates/sudoers.rhel6.erb b/templates/sudoers.rhel6.erb index 8f1ff78..e6a0c8e 100644 --- a/templates/sudoers.rhel6.erb +++ b/templates/sudoers.rhel6.erb @@ -1,123 +1,125 @@ # file managed by puppet (unless config_file_replace=false) # ## Sudoers allows particular users to run various commands as ## the root user, without needing the root password. ## ## Examples are provided at the bottom of the file for collections ## of related commands, which can then be delegated out to particular ## users or groups. ## ## This file must be edited with the 'visudo' command. ## Host Aliases ## Groups of machines. You may prefer to use hostnames (perhaps using ## wildcards for entire domains) or IP addresses instead. # Host_Alias FILESERVERS = fs1, fs2 # Host_Alias MAILSERVERS = smtp, smtp2 ## User Aliases ## These aren't often necessary, as you can use regular groups ## (ie, from files, LDAP, NIS, etc) in this file - just use %groupname ## rather than USERALIAS # User_Alias ADMINS = jsmith, mikem ## Command Aliases ## These are groups of related commands... ## Networking # Cmnd_Alias NETWORKING = /sbin/route, /sbin/ifconfig, /bin/ping, /sbin/dhclient, /usr/bin/net, /sbin/iptables, /usr/bin/rfcomm, /usr/bin/wvdial, /sbin/iwconfig, /sbin/mii-tool ## Installation and management of software # Cmnd_Alias SOFTWARE = /bin/rpm, /usr/bin/up2date, /usr/bin/yum ## Services # Cmnd_Alias SERVICES = /sbin/service, /sbin/chkconfig ## Updating the locate database # Cmnd_Alias LOCATE = /usr/bin/updatedb ## Storage # Cmnd_Alias STORAGE = /sbin/fdisk, /sbin/sfdisk, /sbin/parted, /sbin/partprobe, /bin/mount, /bin/umount ## Delegating permissions # Cmnd_Alias DELEGATING = /usr/sbin/visudo, /bin/chown, /bin/chmod, /bin/chgrp ## Processes # Cmnd_Alias PROCESSES = /bin/nice, /bin/kill, /usr/bin/kill, /usr/bin/killall ## Drivers # Cmnd_Alias DRIVERS = /sbin/modprobe # Defaults specification # Refuse to run if unable to disable echo on the tty. This setting should also be # changed in order to be able to use sudo without a tty. See requiretty above. # Defaults !visiblepw # # Preserving HOME has security implications since many programs # use it when searching for configuration files. # Defaults always_set_home Defaults env_reset Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS" Defaults env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE" Defaults env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES" Defaults env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE" Defaults env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY" <% if @use_sudoreplay %> Defaults log_output Defaults!/usr/bin/sudoreplay !log_output <% if @sudoreplay_discard %> <% @sudoreplay_discard.each do |command| -%> Defaults!<%= command %> !log_output <% end -%> <% end -%> <% end -%> # # Adding HOME to env_keep may enable a user to run unrestricted # commands via sudo. # # Defaults env_keep += "HOME" Defaults secure_path = /usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin ## Next comes the main part: which users can run what software on ## which machines (the sudoers file can be shared between multiple ## systems). ## Syntax: ## ## user MACHINE=COMMANDS ## ## The COMMANDS section may have other options added to it. ## ## Allow root to run any commands anywhere root ALL=(ALL) ALL ## Allows members of the 'sys' group to run networking, software, ## service management apps and more. # %sys ALL = NETWORKING, SOFTWARE, SERVICES, STORAGE, DELEGATING, PROCESSES, LOCATE, DRIVERS +<% if @wheel_config == 'password' %> ## Allows people in group wheel to run all commands -# %wheel ALL=(ALL) ALL - +%wheel ALL=(ALL) ALL +<% elsif @wheel_config == 'nopassword' %> ## Same thing without a password -# %wheel ALL=(ALL) NOPASSWD: ALL +%wheel ALL=(ALL) NOPASSWD: ALL +<% end %> ## Allows members of the users group to mount and unmount the ## cdrom as root # %users ALL=/sbin/mount /mnt/cdrom, /sbin/umount /mnt/cdrom ## Allows members of the users group to shutdown this system # %users localhost=/sbin/shutdown -h now ## Read drop-in files #includedir <%= @config_dir %> <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> diff --git a/templates/sudoers.rhel7.erb b/templates/sudoers.rhel7.erb index 92b7fd0..c70f300 100644 --- a/templates/sudoers.rhel7.erb +++ b/templates/sudoers.rhel7.erb @@ -1,126 +1,128 @@ # file managed by puppet (unless config_file_replace=false) # ## Sudoers allows particular users to run various commands as ## the root user, without needing the root password. ## ## Examples are provided at the bottom of the file for collections ## of related commands, which can then be delegated out to particular ## users or groups. ## ## This file must be edited with the 'visudo' command. ## Host Aliases ## Groups of machines. You may prefer to use hostnames (perhaps using ## wildcards for entire domains) or IP addresses instead. # Host_Alias FILESERVERS = fs1, fs2 # Host_Alias MAILSERVERS = smtp, smtp2 ## User Aliases ## These aren't often necessary, as you can use regular groups ## (ie, from files, LDAP, NIS, etc) in this file - just use %groupname ## rather than USERALIAS # User_Alias ADMINS = jsmith, mikem ## Command Aliases ## These are groups of related commands... ## Networking # Cmnd_Alias NETWORKING = /sbin/route, /sbin/ifconfig, /bin/ping, /sbin/dhclient, /usr/bin/net, /sbin/iptables, /usr/bin/rfcomm, /usr/bin/wvdial, /sbin/iwconfig, /sbin/mii-tool ## Installation and management of software # Cmnd_Alias SOFTWARE = /bin/rpm, /usr/bin/up2date, /usr/bin/yum ## Services # Cmnd_Alias SERVICES = /sbin/service, /sbin/chkconfig, /usr/bin/systemctl start, /usr/bin/systemctl stop, /usr/bin/systemctl reload, /usr/bin/systemctl restart, /usr/bin/systemctl status, /usr/bin/systemctl enable, /usr/bin/systemctl disable ## Updating the locate database # Cmnd_Alias LOCATE = /usr/bin/updatedb ## Storage # Cmnd_Alias STORAGE = /sbin/fdisk, /sbin/sfdisk, /sbin/parted, /sbin/partprobe, /bin/mount, /bin/umount ## Delegating permissions # Cmnd_Alias DELEGATING = /usr/sbin/visudo, /bin/chown, /bin/chmod, /bin/chgrp ## Processes # Cmnd_Alias PROCESSES = /bin/nice, /bin/kill, /usr/bin/kill, /usr/bin/killall ## Drivers # Cmnd_Alias DRIVERS = /sbin/modprobe # Defaults specification # Refuse to run if unable to disable echo on the tty. This setting should also be # changed in order to be able to use sudo without a tty. See requiretty above. # Defaults !visiblepw # # Preserving HOME has security implications since many programs # use it when searching for configuration files. Note that HOME # is already set when the the env_reset option is enabled, so # this option is only effective for configurations where either # env_reset is disabled or HOME is present in the env_keep list. # Defaults always_set_home Defaults env_reset Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS" Defaults env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE" Defaults env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES" Defaults env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE" Defaults env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY" <% if @use_sudoreplay %> Defaults log_output Defaults!/usr/bin/sudoreplay !log_output <% if @sudoreplay_discard %> <% @sudoreplay_discard.each do |command| -%> Defaults!<%= command %> !log_output <% end -%> <% end -%> <% end -%> # # Adding HOME to env_keep may enable a user to run unrestricted # commands via sudo. # # Defaults env_keep += "HOME" Defaults secure_path = /usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/puppetlabs/bin ## Next comes the main part: which users can run what software on ## which machines (the sudoers file can be shared between multiple ## systems). ## Syntax: ## ## user MACHINE=COMMANDS ## ## The COMMANDS section may have other options added to it. ## ## Allow root to run any commands anywhere root ALL=(ALL) ALL ## Allows members of the 'sys' group to run networking, software, ## service management apps and more. # %sys ALL = NETWORKING, SOFTWARE, SERVICES, STORAGE, DELEGATING, PROCESSES, LOCATE, DRIVERS +<% if @wheel_config == 'password' %> ## Allows people in group wheel to run all commands %wheel ALL=(ALL) ALL - +<% elsif @wheel_config == 'nopassword' %> ## Same thing without a password -# %wheel ALL=(ALL) NOPASSWD: ALL +%wheel ALL=(ALL) NOPASSWD: ALL +<% end %> ## Allows members of the users group to mount and unmount the ## cdrom as root # %users ALL=/sbin/mount /mnt/cdrom, /sbin/umount /mnt/cdrom ## Allows members of the users group to shutdown this system # %users localhost=/sbin/shutdown -h now ## Read drop-in files from /etc/sudoers.d (the # here does not mean a comment) #includedir <%= @config_dir %> <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> diff --git a/templates/sudoers.rhel8.erb b/templates/sudoers.rhel8.erb index 4489d41..93e316c 100644 --- a/templates/sudoers.rhel8.erb +++ b/templates/sudoers.rhel8.erb @@ -1,135 +1,137 @@ # file managed by puppet (unless config_file_replace=false) # ## Sudoers allows particular users to run various commands as ## the root user, without needing the root password. ## ## Examples are provided at the bottom of the file for collections ## of related commands, which can then be delegated out to particular ## users or groups. ## ## This file must be edited with the 'visudo' command. ## Host Aliases ## Groups of machines. You may prefer to use hostnames (perhaps using ## wildcards for entire domains) or IP addresses instead. # Host_Alias FILESERVERS = fs1, fs2 # Host_Alias MAILSERVERS = smtp, smtp2 ## User Aliases ## These aren't often necessary, as you can use regular groups ## (ie, from files, LDAP, NIS, etc) in this file - just use %groupname ## rather than USERALIAS # User_Alias ADMINS = jsmith, mikem ## Command Aliases ## These are groups of related commands... ## Networking # Cmnd_Alias NETWORKING = /sbin/route, /sbin/ifconfig, /bin/ping, /sbin/dhclient, /usr/bin/net, /sbin/iptables, /usr/bin/rfcomm, /usr/bin/wvdial, /sbin/iwconfig, /sbin/mii-tool ## Installation and management of software # Cmnd_Alias SOFTWARE = /bin/rpm, /usr/bin/up2date, /usr/bin/yum ## Services # Cmnd_Alias SERVICES = /sbin/service, /sbin/chkconfig, /usr/bin/systemctl start, /usr/bin/systemctl stop, /usr/bin/systemctl reload, /usr/bin/systemctl restart, /usr/bin/systemctl status, /usr/bin/systemctl enable, /usr/bin/systemctl disable ## Updating the locate database # Cmnd_Alias LOCATE = /usr/bin/updatedb ## Storage # Cmnd_Alias STORAGE = /sbin/fdisk, /sbin/sfdisk, /sbin/parted, /sbin/partprobe, /bin/mount, /bin/umount ## Delegating permissions # Cmnd_Alias DELEGATING = /usr/sbin/visudo, /bin/chown, /bin/chmod, /bin/chgrp ## Processes # Cmnd_Alias PROCESSES = /bin/nice, /bin/kill, /usr/bin/kill, /usr/bin/killall ## Drivers # Cmnd_Alias DRIVERS = /sbin/modprobe # Defaults specification # # Refuse to run if unable to disable echo on the tty. # Defaults !visiblepw # # Preserving HOME has security implications since many programs # use it when searching for configuration files. Note that HOME # is already set when the the env_reset option is enabled, so # this option is only effective for configurations where either # env_reset is disabled or HOME is present in the env_keep list. # Defaults always_set_home Defaults match_group_by_gid # Prior to version 1.8.15, groups listed in sudoers that were not # found in the system group database were passed to the group # plugin, if any. Starting with 1.8.15, only groups of the form # %:group are resolved via the group plugin by default. # We enable always_query_group_plugin to restore old behavior. # Disable this option for new behavior. Defaults always_query_group_plugin Defaults env_reset Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS" Defaults env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE" Defaults env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES" Defaults env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE" Defaults env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY" <% if @use_sudoreplay %> Defaults log_output Defaults!/usr/bin/sudoreplay !log_output <% if @sudoreplay_discard %> <% @sudoreplay_discard.each do |command| -%> Defaults!<%= command %> !log_output <% end -%> <% end -%> <% end -%> # # Adding HOME to env_keep may enable a user to run unrestricted # commands via sudo. # # Defaults env_keep += "HOME" Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/opt/puppetlabs/bin ## Next comes the main part: which users can run what software on ## which machines (the sudoers file can be shared between multiple ## systems). ## Syntax: ## ## user MACHINE=COMMANDS ## ## The COMMANDS section may have other options added to it. ## ## Allow root to run any commands anywhere root ALL=(ALL) ALL ## Allows members of the 'sys' group to run networking, software, ## service management apps and more. # %sys ALL = NETWORKING, SOFTWARE, SERVICES, STORAGE, DELEGATING, PROCESSES, LOCATE, DRIVERS +<% if @wheel_config == 'password' %> ## Allows people in group wheel to run all commands %wheel ALL=(ALL) ALL - +<% elsif @wheel_config == 'nopassword' %> ## Same thing without a password -# %wheel ALL=(ALL) NOPASSWD: ALL +%wheel ALL=(ALL) NOPASSWD: ALL +<% end %> ## Allows members of the users group to mount and unmount the ## cdrom as root # %users ALL=/sbin/mount /mnt/cdrom, /sbin/umount /mnt/cdrom ## Allows members of the users group to shutdown this system # %users localhost=/sbin/shutdown -h now ## Read drop-in files from /etc/sudoers.d (the # here does not mean a comment) #includedir <%= @config_dir %> <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> diff --git a/templates/sudoers.smartos.erb b/templates/sudoers.smartos.erb index 36f1250..6246268 100644 --- a/templates/sudoers.smartos.erb +++ b/templates/sudoers.smartos.erb @@ -1,98 +1,100 @@ # file managed by puppet (unless config_file_replace=false) # ## sudoers file. ## ## This file MUST be edited with the 'visudo' command as root. ## Failure to use 'visudo' may result in syntax or file permission errors ## that prevent sudo from running. ## ## See the sudoers man page for the details on how to write a sudoers file. ## ## ## Host alias specification ## ## Groups of machines. These may include host names (optionally with wildcards), ## IP addresses, network numbers or netgroups. # Host_Alias WEBSERVERS = www1, www2, www3 ## ## User alias specification ## ## Groups of users. These may consist of user names, uids, Unix groups, ## or netgroups. # User_Alias ADMINS = millert, dowdy, mikef ## ## Defaults specification ## ## You may wish to keep some of the following environment variables ## when running commands via sudo. ## ## Locale settings # Defaults env_keep += "LANG LANGUAGE LINGUAS LC_* _XKB_CHARSET" ## ## Run X applications through sudo; HOME is used to find the ## .Xauthority file. Note that other programs use HOME to find ## configuration files and this may lead to privilege escalation! # Defaults env_keep += "HOME" ## ## X11 resource path settings # Defaults env_keep += "XAPPLRESDIR XFILESEARCHPATH XUSERFILESEARCHPATH" ## ## Desktop path settings # Defaults env_keep += "QTDIR KDEDIR" ## ## Allow sudo-run commands to inherit the callers' ConsoleKit session # Defaults env_keep += "XDG_SESSION_COOKIE" ## ## Uncomment to enable special input methods. Care should be taken as ## this may allow users to subvert the command being run via sudo. # Defaults env_keep += "XMODIFIERS GTK_IM_MODULE QT_IM_MODULE QT_IM_SWITCHER" ## ## Uncomment to enable logging of a command's output, except for ## sudoreplay and reboot. Use sudoreplay to play back logged sessions. # Defaults log_output # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!/sbin/reboot !log_output <% if @use_sudoreplay %> Defaults log_output Defaults!/usr/bin/sudoreplay !log_output <% if @sudoreplay_discard %> <% @sudoreplay_discard.each do |command| -%> Defaults!<%= command %> !log_output <% end -%> <% end -%> <% end -%> ## ## Runas alias specification ## ## ## User privilege specification ## root ALL=(ALL) ALL +<% if @wheel_config == 'password' %> ## Uncomment to allow members of group wheel to execute any command -# %wheel ALL=(ALL) ALL - +%wheel ALL=(ALL) ALL +<% elsif @wheel_config == 'nopassword' %> ## Same thing without a password -# %wheel ALL=(ALL) NOPASSWD: ALL +%wheel ALL=(ALL) NOPASSWD: ALL +<% end %> ## Uncomment to allow members of group sudo to execute any command # %sudo ALL=(ALL) ALL ## Uncomment to allow any user to run sudo if they know the password ## of the user they are running the command as (root by default). # Defaults targetpw # Ask for the password of the target user # ALL ALL=(ALL) ALL # WARNING: only use this together with 'Defaults targetpw' ## Read drop-in files ## (the '#' here does not indicate a comment) #includedir <%= @config_dir %> <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> diff --git a/templates/sudoers.solaris.erb b/templates/sudoers.solaris.erb index fa62779..0c7ac59 100644 --- a/templates/sudoers.solaris.erb +++ b/templates/sudoers.solaris.erb @@ -1,104 +1,106 @@ # file managed by puppet (unless config_file_replace=false) # ## sudoers file. ## ## This file MUST be edited with the 'visudo' command as root. ## Failure to use 'visudo' may result in syntax or file permission errors ## that prevent sudo from running. ## ## See the sudoers man page for the details on how to write a sudoers file. ## ## ## Host alias specification ## ## Groups of machines. These may include host names (optionally with wildcards), ## IP addresses, network numbers or netgroups. # Host_Alias WEBSERVERS = www1, www2, www3 ## ## User alias specification ## ## Groups of users. These may consist of user names, uids, Unix groups, ## or netgroups. # User_Alias ADMINS = millert, dowdy, mikef ## ## Cmnd alias specification ## ## Groups of commands. Often used to group related commands together. # Cmnd_Alias PROCESSES = /usr/bin/nice, /bin/kill, /usr/bin/renice, \ # /usr/bin/pkill, /usr/bin/top ## ## Defaults specification ## ## You may wish to keep some of the following environment variables ## when running commands via sudo. ## ## Locale settings # Defaults env_keep += "LANG LANGUAGE LINGUAS LC_* _XKB_CHARSET" ## ## Run X applications through sudo; HOME is used to find the ## .Xauthority file. Note that other programs use HOME to find ## configuration files and this may lead to privilege escalation! # Defaults env_keep += "HOME" ## ## X11 resource path settings # Defaults env_keep += "XAPPLRESDIR XFILESEARCHPATH XUSERFILESEARCHPATH" ## ## Desktop path settings # Defaults env_keep += "QTDIR KDEDIR" ## ## Allow sudo-run commands to inherit the callers' ConsoleKit session # Defaults env_keep += "XDG_SESSION_COOKIE" ## ## Uncomment to enable special input methods. Care should be taken as ## this may allow users to subvert the command being run via sudo. # Defaults env_keep += "XMODIFIERS GTK_IM_MODULE QT_IM_MODULE QT_IM_SWITCHER" ## ## Uncomment to enable logging of a command's output, except for ## sudoreplay and reboot. Use sudoreplay to play back logged sessions. # Defaults log_output # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!/sbin/reboot !log_output <% if @use_sudoreplay %> Defaults log_output Defaults!/usr/bin/sudoreplay !log_output <% if @sudoreplay_discard %> <% @sudoreplay_discard.each do |command| -%> Defaults!<%= command %> !log_output <% end -%> <% end -%> <% end -%> ## Runas alias specification ## ## ## User privilege specification ## #root ALL=(ALL) ALL +<% if @wheel_config == 'password' %> ## Uncomment to allow members of group wheel to execute any command -# %wheel ALL=(ALL) ALL - +%wheel ALL=(ALL) ALL +<% elsif @wheel_config == 'nopassword' %> ## Same thing without a password -# %wheel ALL=(ALL) NOPASSWD: ALL +%wheel ALL=(ALL) NOPASSWD: ALL +<% end %> ## Uncomment to allow members of group sudo to execute any command # %sudo ALL=(ALL) ALL ## Uncomment to allow any user to run sudo if they know the password ## of the user they are running the command as (root by default). # Defaults targetpw # Ask for the password of the target user # ALL ALL=(ALL) ALL # WARNING: only use this together with 'Defaults targetpw' ## Read drop-in files ## (the '#' here does not indicate a comment) #includedir <%= @config_dir %> <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> diff --git a/templates/sudoers.suse.erb b/templates/sudoers.suse.erb index e3c0977..701f3ea 100644 --- a/templates/sudoers.suse.erb +++ b/templates/sudoers.suse.erb @@ -1,98 +1,100 @@ # file managed by puppet (unless config_file_replace=false) # ## sudoers file. ## ## This file MUST be edited with the 'visudo' command as root. ## Failure to use 'visudo' may result in syntax or file permission errors ## that prevent sudo from running. ## ## See the sudoers man page for the details on how to write a sudoers file. ## ## ## Host alias specification ## ## Groups of machines. These may include host names (optionally with wildcards), ## IP addresses, network numbers or netgroups. # Host_Alias WEBSERVERS = www1, www2, www3 ## ## User alias specification ## ## Groups of users. These may consist of user names, uids, Unix groups, ## or netgroups. # User_Alias ADMINS = millert, dowdy, mikef ## ## Cmnd alias specification ## ## Groups of commands. Often used to group related commands together. # Cmnd_Alias PROCESSES = /usr/bin/nice, /bin/kill, /usr/bin/renice, \ # /usr/bin/pkill, /usr/bin/top ## ## Defaults specification ## ## Prevent environment variables from influencing programs in an ## unexpected or harmful way (CVE-2005-2959, CVE-2005-4158, CVE-2006-0151) Defaults always_set_home ## Path that will be used for every command run from sudo Defaults secure_path="/usr/sbin:/usr/bin:/sbin:/bin:/opt/puppetlabs/bin" Defaults env_reset ## Change env_reset to !env_reset in previous line to keep all environment variables ## Following list will no longer be necessary after this change Defaults env_keep = "LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE LC_TIME LC_ALL LANGUAGE LINGUAS XDG_SESSION_COOKIE" ## Comment out the preceding line and uncomment the following one if you need ## to use special input methods. This may allow users to compromise the root ## account if they are allowed to run commands without authentication. #Defaults env_keep = "LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE LC_TIME LC_ALL LANGUAGE LINGUAS XDG_SESSION_COOKIE XMODIFIERS GTK_IM_MODULE QT_IM_MODULE QT_IM_SWITCHER" ## Do not insult users when they enter an incorrect password. Defaults !insults ## ## Uncomment to enable logging of a command's output, except for ## sudoreplay and reboot. Use sudoreplay to play back logged sessions. # Defaults log_output # Defaults!/usr/bin/sudoreplay !log_output # Defaults!/sbin/reboot !log_output <% if @use_sudoreplay %> Defaults log_output Defaults!/usr/bin/sudoreplay !log_output <% if @sudoreplay_discard %> <% @sudoreplay_discard.each do |command| -%> Defaults!<%= command %> !log_output <% end -%> <% end -%> <% end -%> ## In the default (unconfigured) configuration, sudo asks for the root password. ## This allows use of an ordinary user account for administration of a freshly ## installed system. When configuring sudo, delete the two ## following lines: #Defaults targetpw # ask for the password of the target user i.e. root #ALL ALL=(ALL) ALL # WARNING! Only use this together with 'Defaults targetpw'! ## ## Runas alias specification ## ## ## User privilege specification ## root ALL=(ALL) ALL +<% if @wheel_config == 'password' %> ## Uncomment to allow members of group wheel to execute any command -# %wheel ALL=(ALL) ALL - +%wheel ALL=(ALL) ALL +<% elsif @wheel_config == 'nopassword' %> ## Same thing without a password -# %wheel ALL=(ALL) NOPASSWD: ALL +%wheel ALL=(ALL) NOPASSWD: ALL +<% end %> ## Read drop-in files ## (the '#' here does not indicate a comment) #includedir <%= @config_dir %> <% @extra_include_dirs.each do |include_dir| -%> #includedir <%= include_dir %> <% end if @extra_include_dirs -%> diff --git a/tests/init.pp b/tests/init.pp deleted file mode 100644 index 5218467..0000000 --- a/tests/init.pp +++ /dev/null @@ -1 +0,0 @@ -include ::sudo