diff --git a/.fixtures.yml b/.fixtures.yml index db86e3b..3a9959b 100644 --- a/.fixtures.yml +++ b/.fixtures.yml @@ -1,13 +1,13 @@ fixtures: repositories: cron: - repo: 'git://github.com/puppetlabs/puppetlabs-cron_core.git' - ref: '1.0.0' + repo: 'https://github.com/puppetlabs/puppetlabs-cron_core.git' + ref: 'v1.2.0' inifile: repo: 'https://github.com/puppetlabs/puppetlabs-inifile.git' ref: '1.6.0' stdlib: repo: 'https://github.com/puppetlabs/puppetlabs-stdlib.git' - ref: '4.6.0' + ref: '5.0.0' symlinks: puppet: "#{source_dir}" diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9032a01 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,5 @@ +*.rb eol=lf +*.erb eol=lf +*.pp eol=lf +*.sh eol=lf +*.epp eol=lf diff --git a/.github/workflows/run-pdk-tests-on-puppet-7.yml b/.github/workflows/run-pdk-tests-on-puppet-7.yml new file mode 100644 index 0000000..1b13f18 --- /dev/null +++ b/.github/workflows/run-pdk-tests-on-puppet-7.yml @@ -0,0 +1,34 @@ +name: Run PDK tests on Puppet 7.x + +on: + - push + - pull_request + +jobs: + validate-7: + runs-on: ubuntu-latest + steps: + - name: Clone repository + uses: actions/checkout@v2 + + - name: Run pdk validate + uses: puppets-epic-show-theatre/action-pdk-validate@v1 + with: + puppet-version: "7" + # [optional] A string indicating the Puppet version to validate against, such as "5.4.2" or "5.5". + # pe-version: "" + # [optional] A string indicating the PE version to validate against, such as "2017.3.5" or "2018.1". + + test-7: + runs-on: ubuntu-latest + steps: + - name: Clone repository + uses: actions/checkout@v2 + + - name: Run unit tests + uses: puppets-epic-show-theatre/action-pdk-test-unit@v1 + with: + puppet-version: "7" + # [optional] A string indicating the Puppet version to validate against, such as "5.4.2" or "5.5". + # pe-version: "" + # [optional] A string indicating the PE version to validate against, such as "2017.3.5" or "2018.1". diff --git a/.github/workflows/run-pdk-tests-on-puppet-8.yml b/.github/workflows/run-pdk-tests-on-puppet-8.yml new file mode 100644 index 0000000..12460e0 --- /dev/null +++ b/.github/workflows/run-pdk-tests-on-puppet-8.yml @@ -0,0 +1,34 @@ +name: Run PDK tests on Puppet 8.x + +on: + - push + - pull_request + +jobs: + validate-8: + runs-on: ubuntu-latest + steps: + - name: Clone repository + uses: actions/checkout@v2 + + - name: Run pdk validate + uses: puppets-epic-show-theatre/action-pdk-validate@v1 + with: + puppet-version: "8" + # [optional] A string indicating the Puppet version to validate against, such as "5.4.2" or "5.5". + # pe-version: "" + # [optional] A string indicating the PE version to validate against, such as "2017.3.5" or "2018.1". + + test-8: + runs-on: ubuntu-latest + steps: + - name: Clone repository + uses: actions/checkout@v2 + + - name: Run unit tests + uses: puppets-epic-show-theatre/action-pdk-test-unit@v1 + with: + puppet-version: "8" + # [optional] A string indicating the Puppet version to validate against, such as "5.4.2" or "5.5". + # pe-version: "" + # [optional] A string indicating the PE version to validate against, such as "2017.3.5" or "2018.1". diff --git a/.gitignore b/.gitignore index e6122c7..3f15512 100644 --- a/.gitignore +++ b/.gitignore @@ -1,31 +1,28 @@ -# Default .gitignore for Ruby -*.gem -*.rbc -.bundle -.config -coverage -InstalledFiles -lib/bundler/man -pkg -rdoc -spec/reports -test/tmp -test/version_tmp -tmp - -# YARD artifacts +.git/ +.*.sw[op] +.metadata .yardoc -_yardoc -doc/ - -# Vim -*.swp - -# OS X +.yardwarns +*.iml +/.bundle/ +/.idea/ +/.vagrant/ +/coverage/ +/bin/ +/doc/ +/Gemfile.local +/Gemfile.lock +/junit/ +/log/ +/pkg/ +/spec/fixtures/manifests/ +/spec/fixtures/modules/* +/tmp/ +/vendor/ +/convert_report.txt +/update_report.txt .DS_Store - -# Puppet -coverage/ -spec/fixtures/modules/* -spec/fixtures/manifests/* -Gemfile.lock +.project +.envrc +/inventory.yaml +/spec/fixtures/litmus_inventory.yaml diff --git a/.pdkignore b/.pdkignore new file mode 100644 index 0000000..584438f --- /dev/null +++ b/.pdkignore @@ -0,0 +1,43 @@ +.git/ +.*.sw[op] +.metadata +.yardoc +.yardwarns +*.iml +/.bundle/ +/.idea/ +/.vagrant/ +/coverage/ +/bin/ +/doc/ +/Gemfile.local +/Gemfile.lock +/junit/ +/log/ +/pkg/ +/spec/fixtures/manifests/ +/spec/fixtures/modules/* +/tmp/ +/vendor/ +/convert_report.txt +/update_report.txt +.DS_Store +.project +.envrc +/inventory.yaml +/spec/fixtures/litmus_inventory.yaml +/.fixtures.yml +/Gemfile +/.gitattributes +/.gitignore +/.pdkignore +/.puppet-lint.rc +/Rakefile +/rakelib/ +/.rspec +/..yml +/.yardopts +/spec/ +/.vscode/ +/.sync.yml +/.devcontainer/ diff --git a/.puppet-lint.rc b/.puppet-lint.rc new file mode 100644 index 0000000..cc96ece --- /dev/null +++ b/.puppet-lint.rc @@ -0,0 +1 @@ +--relative diff --git a/.rspec b/.rspec new file mode 100644 index 0000000..16f9cdb --- /dev/null +++ b/.rspec @@ -0,0 +1,2 @@ +--color +--format documentation diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..5be1f9f --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,723 @@ +--- +require: +- rubocop-performance +- rubocop-rspec +AllCops: + DisplayCopNames: true + TargetRubyVersion: '2.6' + Include: + - "**/*.rb" + Exclude: + - bin/* + - ".vendor/**/*" + - "**/Gemfile" + - "**/Rakefile" + - pkg/**/* + - spec/fixtures/**/* + - vendor/**/* + - "**/Puppetfile" + - "**/Vagrantfile" + - "**/Guardfile" +Layout/LineLength: + Description: People have wide screens, use them. + Max: 200 +RSpec/BeforeAfterAll: + Description: Beware of using after(:all) as it may cause state to leak between tests. + A necessary evil in acceptance testing. + Exclude: + - spec/acceptance/**/*.rb +RSpec/HookArgument: + Description: Prefer explicit :each argument, matching existing module's style + EnforcedStyle: each +RSpec/DescribeSymbol: + Exclude: + - spec/unit/facter/**/*.rb +Style/BlockDelimiters: + Description: Prefer braces for chaining. Mostly an aesthetical choice. Better to + be consistent then. + EnforcedStyle: braces_for_chaining +Style/ClassAndModuleChildren: + Description: Compact style reduces the required amount of indentation. + EnforcedStyle: compact +Style/EmptyElse: + Description: Enforce against empty else clauses, but allow `nil` for clarity. + EnforcedStyle: empty +Style/FormatString: + Description: Following the main puppet project's style, prefer the % format format. + EnforcedStyle: percent +Style/FormatStringToken: + Description: Following the main puppet project's style, prefer the simpler template + tokens over annotated ones. + EnforcedStyle: template +Style/Lambda: + Description: Prefer the keyword for easier discoverability. + EnforcedStyle: literal +Style/RegexpLiteral: + Description: Community preference. See https://github.com/voxpupuli/modulesync_config/issues/168 + EnforcedStyle: percent_r +Style/TernaryParentheses: + Description: Checks for use of parentheses around ternary conditions. Enforce parentheses + on complex expressions for better readability, but seriously consider breaking + it up. + EnforcedStyle: require_parentheses_when_complex +Style/TrailingCommaInArguments: + Description: Prefer always trailing comma on multiline argument lists. This makes + diffs, and re-ordering nicer. + EnforcedStyleForMultiline: comma +Style/TrailingCommaInArrayLiteral: + Description: Prefer always trailing comma on multiline literals. This makes diffs, + and re-ordering nicer. + EnforcedStyleForMultiline: comma +Style/SymbolArray: + Description: Using percent style obscures symbolic intent of array's contents. + EnforcedStyle: brackets +RSpec/MessageSpies: + EnforcedStyle: receive +Style/Documentation: + Exclude: + - lib/puppet/parser/functions/**/* + - spec/**/* +Style/WordArray: + EnforcedStyle: brackets +Performance/AncestorsInclude: + Enabled: true +Performance/BigDecimalWithNumericArgument: + Enabled: true +Performance/BlockGivenWithExplicitBlock: + Enabled: true +Performance/CaseWhenSplat: + Enabled: true +Performance/ConstantRegexp: + Enabled: true +Performance/MethodObjectAsBlock: + Enabled: true +Performance/RedundantSortBlock: + Enabled: true +Performance/RedundantStringChars: + Enabled: true +Performance/ReverseFirst: + Enabled: true +Performance/SortReverse: + Enabled: true +Performance/Squeeze: + Enabled: true +Performance/StringInclude: + Enabled: true +Performance/Sum: + Enabled: true +Style/CollectionMethods: + Enabled: true +Style/MethodCalledOnDoEndBlock: + Enabled: true +Style/StringMethods: + Enabled: true +Bundler/GemFilename: + Enabled: false +Bundler/InsecureProtocolSource: + Enabled: false +Capybara/CurrentPathExpectation: + Enabled: false +Capybara/VisibilityMatcher: + Enabled: false +Gemspec/DuplicatedAssignment: + Enabled: false +Gemspec/OrderedDependencies: + Enabled: false +Gemspec/RequiredRubyVersion: + Enabled: false +Gemspec/RubyVersionGlobalsUsage: + Enabled: false +Layout/ArgumentAlignment: + Enabled: false +Layout/BeginEndAlignment: + Enabled: false +Layout/ClosingHeredocIndentation: + Enabled: false +Layout/EmptyComment: + Enabled: false +Layout/EmptyLineAfterGuardClause: + Enabled: false +Layout/EmptyLinesAroundArguments: + Enabled: false +Layout/EmptyLinesAroundAttributeAccessor: + Enabled: false +Layout/EndOfLine: + Enabled: false +Layout/FirstArgumentIndentation: + Enabled: false +Layout/HashAlignment: + Enabled: false +Layout/HeredocIndentation: + Enabled: false +Layout/LeadingEmptyLines: + Enabled: false +Layout/SpaceAroundMethodCallOperator: + Enabled: false +Layout/SpaceInsideArrayLiteralBrackets: + Enabled: false +Layout/SpaceInsideReferenceBrackets: + Enabled: false +Lint/BigDecimalNew: + Enabled: false +Lint/BooleanSymbol: + Enabled: false +Lint/ConstantDefinitionInBlock: + Enabled: false +Lint/DeprecatedOpenSSLConstant: + Enabled: false +Lint/DisjunctiveAssignmentInConstructor: + Enabled: false +Lint/DuplicateElsifCondition: + Enabled: false +Lint/DuplicateRequire: + Enabled: false +Lint/DuplicateRescueException: + Enabled: false +Lint/EmptyConditionalBody: + Enabled: false +Lint/EmptyFile: + Enabled: false +Lint/ErbNewArguments: + Enabled: false +Lint/FloatComparison: + Enabled: false +Lint/HashCompareByIdentity: + Enabled: false +Lint/IdentityComparison: + Enabled: false +Lint/InterpolationCheck: + Enabled: false +Lint/MissingCopEnableDirective: + Enabled: false +Lint/MixedRegexpCaptureTypes: + Enabled: false +Lint/NestedPercentLiteral: + Enabled: false +Lint/NonDeterministicRequireOrder: + Enabled: false +Lint/OrderedMagicComments: + Enabled: false +Lint/OutOfRangeRegexpRef: + Enabled: false +Lint/RaiseException: + Enabled: false +Lint/RedundantCopEnableDirective: + Enabled: false +Lint/RedundantRequireStatement: + Enabled: false +Lint/RedundantSafeNavigation: + Enabled: false +Lint/RedundantWithIndex: + Enabled: false +Lint/RedundantWithObject: + Enabled: false +Lint/RegexpAsCondition: + Enabled: false +Lint/ReturnInVoidContext: + Enabled: false +Lint/SafeNavigationConsistency: + Enabled: false +Lint/SafeNavigationWithEmpty: + Enabled: false +Lint/SelfAssignment: + Enabled: false +Lint/SendWithMixinArgument: + Enabled: false +Lint/ShadowedArgument: + Enabled: false +Lint/StructNewOverride: + Enabled: false +Lint/ToJSON: + Enabled: false +Lint/TopLevelReturnWithArgument: + Enabled: false +Lint/TrailingCommaInAttributeDeclaration: + Enabled: false +Lint/UnreachableLoop: + Enabled: false +Lint/UriEscapeUnescape: + Enabled: false +Lint/UriRegexp: + Enabled: false +Lint/UselessMethodDefinition: + Enabled: false +Lint/UselessTimes: + Enabled: false +Metrics/AbcSize: + Enabled: false +Metrics/BlockLength: + Enabled: false +Metrics/BlockNesting: + Enabled: false +Metrics/ClassLength: + Enabled: false +Metrics/CyclomaticComplexity: + Enabled: false +Metrics/MethodLength: + Enabled: false +Metrics/ModuleLength: + Enabled: false +Metrics/ParameterLists: + Enabled: false +Metrics/PerceivedComplexity: + Enabled: false +Migration/DepartmentName: + Enabled: false +Naming/AccessorMethodName: + Enabled: false +Naming/BlockParameterName: + Enabled: false +Naming/HeredocDelimiterCase: + Enabled: false +Naming/HeredocDelimiterNaming: + Enabled: false +Naming/MemoizedInstanceVariableName: + Enabled: false +Naming/MethodParameterName: + Enabled: false +Naming/RescuedExceptionsVariableName: + Enabled: false +Naming/VariableNumber: + Enabled: false +Performance/BindCall: + Enabled: false +Performance/DeletePrefix: + Enabled: false +Performance/DeleteSuffix: + Enabled: false +Performance/InefficientHashSearch: + Enabled: false +Performance/UnfreezeString: + Enabled: false +Performance/UriDefaultParser: + Enabled: false +RSpec/Be: + Enabled: false +RSpec/Capybara/FeatureMethods: + Enabled: false +RSpec/ContainExactly: + Enabled: false +RSpec/ContextMethod: + Enabled: false +RSpec/ContextWording: + Enabled: false +RSpec/DescribeClass: + Enabled: false +RSpec/EmptyHook: + Enabled: false +RSpec/EmptyLineAfterExample: + Enabled: false +RSpec/EmptyLineAfterExampleGroup: + Enabled: false +RSpec/EmptyLineAfterHook: + Enabled: false +RSpec/ExampleLength: + Enabled: false +RSpec/ExampleWithoutDescription: + Enabled: false +RSpec/ExpectChange: + Enabled: false +RSpec/ExpectInHook: + Enabled: false +RSpec/FactoryBot/AttributeDefinedStatically: + Enabled: false +RSpec/FactoryBot/CreateList: + Enabled: false +RSpec/FactoryBot/FactoryClassName: + Enabled: false +RSpec/HooksBeforeExamples: + Enabled: false +RSpec/ImplicitBlockExpectation: + Enabled: false +RSpec/ImplicitSubject: + Enabled: false +RSpec/LeakyConstantDeclaration: + Enabled: false +RSpec/LetBeforeExamples: + Enabled: false +RSpec/MatchArray: + Enabled: false +RSpec/MissingExampleGroupArgument: + Enabled: false +RSpec/MultipleExpectations: + Enabled: false +RSpec/MultipleMemoizedHelpers: + Enabled: false +RSpec/MultipleSubjects: + Enabled: false +RSpec/NestedGroups: + Enabled: false +RSpec/PredicateMatcher: + Enabled: false +RSpec/ReceiveCounts: + Enabled: false +RSpec/ReceiveNever: + Enabled: false +RSpec/RepeatedExampleGroupBody: + Enabled: false +RSpec/RepeatedExampleGroupDescription: + Enabled: false +RSpec/RepeatedIncludeExample: + Enabled: false +RSpec/ReturnFromStub: + Enabled: false +RSpec/SharedExamples: + Enabled: false +RSpec/StubbedMock: + Enabled: false +RSpec/UnspecifiedException: + Enabled: false +RSpec/VariableDefinition: + Enabled: false +RSpec/VoidExpect: + Enabled: false +RSpec/Yield: + Enabled: false +Security/Open: + Enabled: false +Style/AccessModifierDeclarations: + Enabled: false +Style/AccessorGrouping: + Enabled: false +Style/BisectedAttrAccessor: + Enabled: false +Style/CaseLikeIf: + Enabled: false +Style/ClassEqualityComparison: + Enabled: false +Style/ColonMethodDefinition: + Enabled: false +Style/CombinableLoops: + Enabled: false +Style/CommentedKeyword: + Enabled: false +Style/Dir: + Enabled: false +Style/DoubleCopDisableDirective: + Enabled: false +Style/EmptyBlockParameter: + Enabled: false +Style/EmptyLambdaParameter: + Enabled: false +Style/Encoding: + Enabled: false +Style/EvalWithLocation: + Enabled: false +Style/ExpandPathArguments: + Enabled: false +Style/ExplicitBlockArgument: + Enabled: false +Style/ExponentialNotation: + Enabled: false +Style/FloatDivision: + Enabled: false +Style/FrozenStringLiteralComment: + Enabled: false +Style/GlobalStdStream: + Enabled: false +Style/HashAsLastArrayItem: + Enabled: false +Style/HashLikeCase: + Enabled: false +Style/HashTransformKeys: + Enabled: false +Style/HashTransformValues: + Enabled: false +Style/IfUnlessModifier: + Enabled: false +Style/KeywordParametersOrder: + Enabled: false +Style/MinMax: + Enabled: false +Style/MixinUsage: + Enabled: false +Style/MultilineWhenThen: + Enabled: false +Style/NegatedUnless: + Enabled: false +Style/NumericPredicate: + Enabled: false +Style/OptionalBooleanParameter: + Enabled: false +Style/OrAssignment: + Enabled: false +Style/RandomWithOffset: + Enabled: false +Style/RedundantAssignment: + Enabled: false +Style/RedundantCondition: + Enabled: false +Style/RedundantConditional: + Enabled: false +Style/RedundantFetchBlock: + Enabled: false +Style/RedundantFileExtensionInRequire: + Enabled: false +Style/RedundantRegexpCharacterClass: + Enabled: false +Style/RedundantRegexpEscape: + Enabled: false +Style/RedundantSelfAssignment: + Enabled: false +Style/RedundantSort: + Enabled: false +Style/RescueStandardError: + Enabled: false +Style/SingleArgumentDig: + Enabled: false +Style/SlicingWithRange: + Enabled: false +Style/SoleNestedConditional: + Enabled: false +Style/StderrPuts: + Enabled: false +Style/StringConcatenation: + Enabled: false +Style/Strip: + Enabled: false +Style/SymbolProc: + Enabled: false +Style/TrailingBodyOnClass: + Enabled: false +Style/TrailingBodyOnMethodDefinition: + Enabled: false +Style/TrailingBodyOnModule: + Enabled: false +Style/TrailingCommaInHashLiteral: + Enabled: false +Style/TrailingMethodEndStatement: + Enabled: false +Style/UnpackFirst: + Enabled: false +Capybara/MatchStyle: + Enabled: false +Capybara/NegationMatcher: + Enabled: false +Capybara/SpecificActions: + Enabled: false +Capybara/SpecificFinders: + Enabled: false +Capybara/SpecificMatcher: + Enabled: false +Gemspec/DeprecatedAttributeAssignment: + Enabled: false +Gemspec/DevelopmentDependencies: + Enabled: false +Gemspec/RequireMFA: + Enabled: false +Layout/LineContinuationLeadingSpace: + Enabled: false +Layout/LineContinuationSpacing: + Enabled: false +Layout/LineEndStringConcatenationIndentation: + Enabled: false +Layout/SpaceBeforeBrackets: + Enabled: false +Lint/AmbiguousAssignment: + Enabled: false +Lint/AmbiguousOperatorPrecedence: + Enabled: false +Lint/AmbiguousRange: + Enabled: false +Lint/ConstantOverwrittenInRescue: + Enabled: false +Lint/DeprecatedConstants: + Enabled: false +Lint/DuplicateBranch: + Enabled: false +Lint/DuplicateMagicComment: + Enabled: false +Lint/DuplicateRegexpCharacterClassElement: + Enabled: false +Lint/EmptyBlock: + Enabled: false +Lint/EmptyClass: + Enabled: false +Lint/EmptyInPattern: + Enabled: false +Lint/IncompatibleIoSelectWithFiberScheduler: + Enabled: false +Lint/LambdaWithoutLiteralBlock: + Enabled: false +Lint/NoReturnInBeginEndBlocks: + Enabled: false +Lint/NonAtomicFileOperation: + Enabled: false +Lint/NumberedParameterAssignment: + Enabled: false +Lint/OrAssignmentToConstant: + Enabled: false +Lint/RedundantDirGlobSort: + Enabled: false +Lint/RefinementImportMethods: + Enabled: false +Lint/RequireRangeParentheses: + Enabled: false +Lint/RequireRelativeSelfPath: + Enabled: false +Lint/SymbolConversion: + Enabled: false +Lint/ToEnumArguments: + Enabled: false +Lint/TripleQuotes: + Enabled: false +Lint/UnexpectedBlockArity: + Enabled: false +Lint/UnmodifiedReduceAccumulator: + Enabled: false +Lint/UselessRescue: + Enabled: false +Lint/UselessRuby2Keywords: + Enabled: false +Metrics/CollectionLiteralLength: + Enabled: false +Naming/BlockForwarding: + Enabled: false +Performance/CollectionLiteralInLoop: + Enabled: false +Performance/ConcurrentMonotonicTime: + Enabled: false +Performance/MapCompact: + Enabled: false +Performance/RedundantEqualityComparisonBlock: + Enabled: false +Performance/RedundantSplitRegexpArgument: + Enabled: false +Performance/StringIdentifierArgument: + Enabled: false +RSpec/BeEq: + Enabled: false +RSpec/BeNil: + Enabled: false +RSpec/ChangeByZero: + Enabled: false +RSpec/ClassCheck: + Enabled: false +RSpec/DuplicatedMetadata: + Enabled: false +RSpec/ExcessiveDocstringSpacing: + Enabled: false +RSpec/FactoryBot/ConsistentParenthesesStyle: + Enabled: false +RSpec/FactoryBot/FactoryNameStyle: + Enabled: false +RSpec/FactoryBot/SyntaxMethods: + Enabled: false +RSpec/IdenticalEqualityAssertion: + Enabled: false +RSpec/NoExpectationExample: + Enabled: false +RSpec/PendingWithoutReason: + Enabled: false +RSpec/Rails/AvoidSetupHook: + Enabled: false +RSpec/Rails/HaveHttpStatus: + Enabled: false +RSpec/Rails/InferredSpecType: + Enabled: false +RSpec/Rails/MinitestAssertions: + Enabled: false +RSpec/Rails/TravelAround: + Enabled: false +RSpec/RedundantAround: + Enabled: false +RSpec/SkipBlockInsideExample: + Enabled: false +RSpec/SortMetadata: + Enabled: false +RSpec/SubjectDeclaration: + Enabled: false +RSpec/VerifiedDoubleReference: + Enabled: false +Security/CompoundHash: + Enabled: false +Security/IoMethods: + Enabled: false +Style/ArgumentsForwarding: + Enabled: false +Style/ArrayIntersect: + Enabled: false +Style/CollectionCompact: + Enabled: false +Style/ComparableClamp: + Enabled: false +Style/ConcatArrayLiterals: + Enabled: false +Style/DirEmpty: + Enabled: false +Style/DocumentDynamicEvalDefinition: + Enabled: false +Style/EmptyHeredoc: + Enabled: false +Style/EndlessMethod: + Enabled: false +Style/EnvHome: + Enabled: false +Style/FetchEnvVar: + Enabled: false +Style/FileEmpty: + Enabled: false +Style/FileRead: + Enabled: false +Style/FileWrite: + Enabled: false +Style/HashConversion: + Enabled: false +Style/HashExcept: + Enabled: false +Style/IfWithBooleanLiteralBranches: + Enabled: false +Style/InPatternThen: + Enabled: false +Style/MagicCommentFormat: + Enabled: false +Style/MapCompactWithConditionalBlock: + Enabled: false +Style/MapToHash: + Enabled: false +Style/MapToSet: + Enabled: false +Style/MinMaxComparison: + Enabled: false +Style/MultilineInPatternThen: + Enabled: false +Style/NegatedIfElseCondition: + Enabled: false +Style/NestedFileDirname: + Enabled: false +Style/NilLambda: + Enabled: false +Style/NumberedParameters: + Enabled: false +Style/NumberedParametersLimit: + Enabled: false +Style/ObjectThen: + Enabled: false +Style/OpenStructUse: + Enabled: false +Style/OperatorMethodCall: + Enabled: false +Style/QuotedSymbols: + Enabled: false +Style/RedundantArgument: + Enabled: false +Style/RedundantConstantBase: + Enabled: false +Style/RedundantDoubleSplatHashBraces: + Enabled: false +Style/RedundantEach: + Enabled: false +Style/RedundantHeredocDelimiterQuotes: + Enabled: false +Style/RedundantInitialize: + Enabled: false +Style/RedundantSelfAssignmentBranch: + Enabled: false +Style/RedundantStringEscape: + Enabled: false +Style/SelectByRegexp: + Enabled: false +Style/StringChars: + Enabled: false +Style/SwapValues: + Enabled: false diff --git a/.sync.yml b/.sync.yml new file mode 100644 index 0000000..8379b4f --- /dev/null +++ b/.sync.yml @@ -0,0 +1,12 @@ +# This file can be used to customize the files managed by PDK. +# +# See https://github.com/puppetlabs/pdk-templates/blob/main/README.md +# for more information. +# +# See https://github.com/puppetlabs/pdk-templates/blob/main/config_defaults.yml +# for the default values. +--- +spec/spec_helper.rb: + coverage_report: true + minimum_code_coverage_percentage: 100 + diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..2f1e4f7 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,6 @@ +{ + "recommendations": [ + "puppet.puppet-vscode", + "rebornix.Ruby" + ] +} diff --git a/.yardopts b/.yardopts new file mode 100644 index 0000000..29c933b --- /dev/null +++ b/.yardopts @@ -0,0 +1 @@ +--markup markdown diff --git a/Gemfile b/Gemfile index 3c5d4a3..add1873 100644 --- a/Gemfile +++ b/Gemfile @@ -1,38 +1,73 @@ source ENV['GEM_SOURCE'] || 'https://rubygems.org' -if puppetversion = ENV['PUPPET_GEM_VERSION'] - gem 'puppet', puppetversion, :require => false -else - gem 'puppet', :require => false +def location_for(place_or_version, fake_version = nil) + git_url_regex = %r{\A(?(https?|git)[:@][^#]*)(#(?.*))?} + file_url_regex = %r{\Afile:\/\/(?.*)} + + if place_or_version && (git_url = place_or_version.match(git_url_regex)) + [fake_version, { git: git_url[:url], branch: git_url[:branch], require: false }].compact + elsif place_or_version && (file_url = place_or_version.match(file_url_regex)) + ['>= 0', { path: File.expand_path(file_url[:path]), require: false }] + else + [place_or_version, { require: false }] + end +end + +group :development do + gem "json", '= 2.1.0', require: false if Gem::Requirement.create(['>= 2.5.0', '< 2.7.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) + gem "json", '= 2.3.0', require: false if Gem::Requirement.create(['>= 2.7.0', '< 3.0.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) + gem "json", '= 2.5.1', require: false if Gem::Requirement.create(['>= 3.0.0', '< 3.0.5']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) + gem "json", '= 2.6.1', require: false if Gem::Requirement.create(['>= 3.1.0', '< 3.1.3']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) + gem "json", '= 2.6.3', require: false if Gem::Requirement.create(['>= 3.2.0', '< 4.0.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) + gem "racc", '~> 1.4.0', require: false if Gem::Requirement.create(['>= 2.7.0', '< 3.0.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) + gem "voxpupuli-puppet-lint-plugins", '~> 5.0', require: false + gem "facterdb", '~> 1.18', require: false + gem "metadata-json-lint", '~> 3.0', require: false + gem "puppetlabs_spec_helper", '~> 6.0', require: false + gem "rspec-puppet-facts", '~> 2.0', require: false + gem "codecov", '~> 0.2', require: false + gem "dependency_checker", '~> 1.0.0', require: false + gem "parallel_tests", '= 3.12.1', require: false + gem "pry", '~> 0.10', require: false + gem "simplecov-console", '~> 0.5', require: false + gem "puppet-debugger", '~> 1.0', require: false + gem "rubocop", '= 1.48.1', require: false + gem "rubocop-performance", '= 1.16.0', require: false + gem "rubocop-rspec", '= 2.19.0', require: false + gem "rb-readline", '= 0.5.5', require: false, platforms: [:mswin, :mingw, :x64_mingw] +end +group :system_tests do + gem "puppet_litmus", '~> 1.0', require: false, platforms: [:ruby, :x64_mingw] + gem "serverspec", '~> 2.41', require: false +end + +puppet_version = ENV['PUPPET_GEM_VERSION'] +facter_version = ENV['FACTER_GEM_VERSION'] +hiera_version = ENV['HIERA_GEM_VERSION'] + +gems = {} + +gems['puppet'] = location_for(puppet_version) + +# If facter or hiera versions have been specified via the environment +# variables + +gems['facter'] = location_for(facter_version) if facter_version +gems['hiera'] = location_for(hiera_version) if hiera_version + +gems.each do |gem_name, gem_params| + gem gem_name, *gem_params end -gem 'activesupport', '~> 4.0', :require => false if RUBY_VERSION < '2.2' -gem 'facter', '>= 2.0', :require => false -gem 'hiera', :require => false -gem 'metadata-json-lint', :require => false -gem 'puppet-lint', '~> 2.0', :require => false -gem 'puppet-lint-absolute_classname-check', :require => false -gem 'puppet-lint-alias-check', :require => false -gem 'puppet-lint-classes_and_types_beginning_with_digits-check', :require => false -gem 'puppet-lint-empty_string-check', :require => false -gem 'puppet-lint-file_ensure-check', :require => false -gem 'puppet-lint-file_source_rights-check', :require => false -gem 'puppet-lint-leading_zero-check', :require => false -gem 'puppet-lint-resource_reference_syntax', :require => false -gem 'puppet-lint-spaceship_operator_without_tag-check', :require => false -gem 'puppet-lint-trailing_comma-check', :require => false -gem 'puppet-lint-undef_in_function-check', :require => false -gem 'puppet-lint-unquoted_string-check', :require => false -gem 'puppet-lint-variable_contains_upcase', :require => false -gem 'puppet-lint-version_comparison-check', :require => false -gem 'puppetlabs_spec_helper', '>= 1.2.0', :require => false -gem 'rspec-puppet', :require => false -gem 'rspec-puppet-facts', :require => false - -# Rack is a dependency of github_changelog_generator -gem 'github_changelog_generator', require: false -if RUBY_VERSION <= '2.2.2' - gem 'rack', '~> 1.0', :require => false -else - gem 'rack', :require => false +# Evaluate Gemfile.local and ~/.gemfile if they exist +extra_gemfiles = [ + "#{__FILE__}.local", + File.join(Dir.home, '.gemfile'), +] + +extra_gemfiles.each do |gemfile| + if File.file?(gemfile) && File.readable?(gemfile) + eval(File.read(gemfile), binding) + end end +# vim: syntax=ruby diff --git a/Rakefile b/Rakefile index fc6faf4..74415a9 100644 --- a/Rakefile +++ b/Rakefile @@ -1,29 +1,88 @@ +# frozen_string_literal: true + +require 'bundler' +require 'puppet_litmus/rake_tasks' if Gem.loaded_specs.key? 'puppet_litmus' require 'puppetlabs_spec_helper/rake_tasks' -require 'puppet-lint/tasks/puppet-lint' -require 'github_changelog_generator/task' - -GitHubChangelogGenerator::RakeTask.new :changelog do |config| - config.user = 'ghoneycutt' - config.project = 'puppet-module-puppet' - config.issues = false - config.token = ENV['GITHUB_CHANGELOG_TOKEN'] +require 'puppet-syntax/tasks/puppet-syntax' +require 'github_changelog_generator/task' if Gem.loaded_specs.key? 'github_changelog_generator' +require 'puppet-strings/tasks' if Gem.loaded_specs.key? 'puppet-strings' + +def changelog_user + return unless Rake.application.top_level_tasks.include? "changelog" + returnVal = nil || JSON.load(File.read('metadata.json'))['author'] + raise "unable to find the changelog_user in .sync.yml, or the author in metadata.json" if returnVal.nil? + puts "GitHubChangelogGenerator user:#{returnVal}" + returnVal end -PuppetLint.configuration.send('disable_80chars') -PuppetLint.configuration.send('disable_140chars') -PuppetLint.configuration.relative = true -PuppetLint.configuration.ignore_paths = ['spec/**/*.pp', 'pkg/**/*.pp'] +def changelog_project + return unless Rake.application.top_level_tasks.include? "changelog" + + returnVal = nil + returnVal ||= begin + metadata_source = JSON.load(File.read('metadata.json'))['source'] + metadata_source_match = metadata_source && metadata_source.match(%r{.*\/([^\/]*?)(?:\.git)?\Z}) -desc 'Validate manifests, templates, and ruby files' -task :validate do - Dir['spec/**/*.rb', 'lib/**/*.rb'].each do |ruby_file| - sh "ruby -c #{ruby_file}" unless ruby_file =~ %r{spec/fixtures} + metadata_source_match && metadata_source_match[1] end + + raise "unable to find the changelog_project in .sync.yml or calculate it from the source in metadata.json" if returnVal.nil? + + puts "GitHubChangelogGenerator project:#{returnVal}" + returnVal end -desc 'Run tests for CI' -task :test do - [:lint, :validate, :spec].each do |test| - Rake::Task[test].invoke +def changelog_future_release + return unless Rake.application.top_level_tasks.include? "changelog" + returnVal = "v%s" % JSON.load(File.read('metadata.json'))['version'] + raise "unable to find the future_release (version) in metadata.json" if returnVal.nil? + puts "GitHubChangelogGenerator future_release:#{returnVal}" + returnVal +end + +PuppetLint.configuration.send('disable_relative') + + +if Gem.loaded_specs.key? 'github_changelog_generator' + GitHubChangelogGenerator::RakeTask.new :changelog do |config| + raise "Set CHANGELOG_GITHUB_TOKEN environment variable eg 'export CHANGELOG_GITHUB_TOKEN=valid_token_here'" if Rake.application.top_level_tasks.include? "changelog" and ENV['CHANGELOG_GITHUB_TOKEN'].nil? + config.user = "#{changelog_user}" + config.project = "#{changelog_project}" + config.future_release = "#{changelog_future_release}" + config.exclude_labels = ['maintenance'] + config.header = "# Change log\n\nAll notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org)." + config.add_pr_wo_labels = true + config.issues = false + config.merge_prefix = "### UNCATEGORIZED PRS; LABEL THEM ON GITHUB" + config.configure_sections = { + "Changed" => { + "prefix" => "### Changed", + "labels" => ["backwards-incompatible"], + }, + "Added" => { + "prefix" => "### Added", + "labels" => ["enhancement", "feature"], + }, + "Fixed" => { + "prefix" => "### Fixed", + "labels" => ["bug", "documentation", "bugfix"], + }, + } + end +else + desc 'Generate a Changelog from GitHub' + task :changelog do + raise < 1.15' + condition: "Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.3.0')" +EOM end end + diff --git a/data/common.yaml b/data/common.yaml new file mode 100644 index 0000000..2fbf0ff --- /dev/null +++ b/data/common.yaml @@ -0,0 +1 @@ +--- {} diff --git a/hiera.yaml b/hiera.yaml new file mode 100644 index 0000000..545fff3 --- /dev/null +++ b/hiera.yaml @@ -0,0 +1,21 @@ +--- +version: 5 + +defaults: # Used for any hierarchy level that omits these keys. + datadir: data # This path is relative to hiera.yaml's directory. + data_hash: yaml_data # Use the built-in YAML backend. + +hierarchy: + - name: "osfamily/major release" + paths: + # Used to distinguish between Debian and Ubuntu + - "os/%{facts.os.name}/%{facts.os.release.major}.yaml" + - "os/%{facts.os.family}/%{facts.os.release.major}.yaml" + # Used for Solaris + - "os/%{facts.os.family}/%{facts.kernelrelease}.yaml" + - name: "osfamily" + paths: + - "os/%{facts.os.name}.yaml" + - "os/%{facts.os.family}.yaml" + - name: 'common' + path: 'common.yaml' diff --git a/manifests/init.pp b/manifests/init.pp index b51b697..45fde48 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -2,58 +2,83 @@ # # Manages puppet agent # +# @param agent_sysconfig_path +# The absolute path to the puppet agent sysconfig file. +# +# @param ca_server +# The name of the puppet CA server. +# +# @param certname +# The certificate name for the client. +# +# @param config_path +# The absolute path to the puppet config file. +# +# @param cron_command +# Command that will be run from cron for the puppet agent. +# +# @param custom_settings +# A hash that allows you to define and set any settings in puppet.conf. +# For each setting use a nested hash and provide the section and the name +# and value of the setting. +# +# Example: +# ``` +# $custom_settings = { +# 'name' => { 'section' => 'master', 'setting' => 'codedir', 'value' => '/specific/path' }, +# 'other' => { 'section' => 'agent', 'setting' => 'server', 'value' => 'specific.server.local' }, +# } +# ``` +# +# @param env +# Value of environment option in puppet.conf which defaults to the +# environment of the current puppet run. By setting this parameter, you +# can specify an environment on the command line (`puppet agent -t +# --environment foo`) and it will not trigger a change to the puppet.conf. +# +# @param graph +# Value of the graph option in puppet.conf. +# +# @param run_at_boot +# Determine if a cron job should present that will run the puppet agent at +# boot time. +# +# @param run_every_thirty +# Determines if a cron job to run the puppet agent every thirty minutes +# should be present. +# +# @param run_in_noop +# Determines if the puppet agent should run in noop mode. This is done by +# appending '--noop' to the `cron_command` parameter. +# +# @param server +# The name of the puppet server. +# class puppet ( - String $certname = $::fqdn, - Variant[Enum['true', 'false'], Boolean] $run_every_thirty = true, #lint:ignore:quoted_booleans - Variant[Enum['true', 'false'], Boolean] $run_in_noop = true, #lint:ignore:quoted_booleans - String $cron_command = '/opt/puppetlabs/bin/puppet agent --onetime --no-daemonize --no-usecacheonfailure --detailed-exitcodes --no-splay', - Variant[Enum['true', 'false'], Boolean] $run_at_boot = true, #lint:ignore:quoted_booleans - String $config_path = '/etc/puppetlabs/puppet/puppet.conf', - String $server = 'puppet', - String $ca_server = 'puppet', - String $env = $environment, - Variant[Enum['true', 'false'], Boolean] $graph = false, #lint:ignore:quoted_booleans - String $agent_sysconfig_path = '/etc/sysconfig/puppet', - Hash $custom_settings = {}, + String $certname = $facts['networking']['fqdn'], + Boolean $run_every_thirty = true, + Boolean $run_in_noop = true, + String $cron_command = '/opt/puppetlabs/bin/puppet agent --onetime --no-daemonize --no-usecacheonfailure --detailed-exitcodes --no-splay', #lint:ignore:140chars + Boolean $run_at_boot = true, + Stdlib::Absolutepath $config_path = '/etc/puppetlabs/puppet/puppet.conf', + String $server = 'puppet', + String $ca_server = 'puppet', + String $env = $environment, + Boolean $graph = false, + Stdlib::Absolutepath $agent_sysconfig_path = '/etc/sysconfig/puppet', + Hash $custom_settings = {}, ) { - - if $config_path != undef { - validate_absolute_path($config_path) - } - - if $agent_sysconfig_path != undef { - validate_absolute_path($agent_sysconfig_path) - } - - if is_string($run_every_thirty) == true { - $run_every_thirty_bool = str2bool($run_every_thirty) - } else { - $run_every_thirty_bool = $run_every_thirty - } - - if is_string($run_in_noop) == true { - $run_in_noop_bool = str2bool($run_in_noop) - } else { - $run_in_noop_bool = $run_in_noop - } - - if is_string($run_at_boot) == true { - $run_at_boot_bool = str2bool($run_at_boot) - } else { - $run_at_boot_bool = $run_at_boot - } - - if $run_every_thirty_bool == true { + if $run_every_thirty == true { $cron_run_one = fqdn_rand(30) $cron_run_two = fqdn_rand(30) + 30 - $cron_minute = [ $cron_run_one, $cron_run_two] + $cron_minute = [$cron_run_one, $cron_run_two] $cron_ensure = 'present' } else { $cron_ensure = 'absent' $cron_minute = undef } - if $run_in_noop_bool == true { + if $run_in_noop == true { $cron_command_real = "${cron_command} --noop" } else { $cron_command_real = $cron_command @@ -67,7 +92,7 @@ minute => $cron_minute, } - if $run_at_boot_bool == true { + if $run_at_boot == true { $at_boot_ensure = 'present' } else { $at_boot_ensure = 'absent' @@ -82,18 +107,18 @@ $ini_defaults = { ensure => 'present', - path => $::puppet::config_path, + path => $puppet::config_path, section => 'main', require => File['puppet_config'], } $ini_settings = { - 'server' => { setting => 'server', value => $server,}, - 'ca_server' => { setting => 'ca_server', value => $ca_server,}, - 'certname' => { setting => 'certname', value => $certname,}, - 'environment' => { setting => 'environment', value => $env,}, - 'trusted_node_data' => { setting => 'trusted_node_data', value => true,}, - 'graph' => { setting => 'graph', value => $graph,}, + 'server' => { setting => 'server', value => $server }, + 'ca_server' => { setting => 'ca_server', value => $ca_server }, + 'certname' => { setting => 'certname', value => $certname }, + 'environment' => { setting => 'environment', value => $env }, + 'trusted_node_data' => { setting => 'trusted_node_data', value => true }, + 'graph' => { setting => 'graph', value => $graph }, } create_resources('ini_setting', $ini_settings, $ini_defaults) create_resources('ini_setting', $custom_settings, $ini_defaults) diff --git a/manifests/server.pp b/manifests/server.pp index 3104ad1..54c118e 100644 --- a/manifests/server.pp +++ b/manifests/server.pp @@ -2,43 +2,57 @@ # # Manages puppetserver # -class puppet::server( - Variant[Enum['true', 'false'], Boolean] $ca = false, #lint:ignore:quoted_booleans - Variant[Array[String, 1], Undef] $autosign_entries = undef, - String $sysconfig_path = '/etc/sysconfig/puppetserver', - String $memory_size = '2g', # only m and g are appropriate for unit - Optional[String] $enc = undef, - Optional[String] $dns_alt_names = undef, +# @param autosign_entries +# Optional array of entries that will be autosigned. +# +# @param ca +# Determines if the system is a puppet CA (certificate authority). +# There should be only one CA per cluster of puppet masters. +# +# @param dns_alt_names +# Value of the dns_alt_names option in puppet.conf. +# +# @param enc +# The absolute path to an ENC. If this is set, it will be the value +# for the external_nodes option in puppet.conf and the node_terminus +# option will be set to 'exec'. +# +# @param memory_size +# The amount of memory allocated to the puppetserver. This is passed +# to the Xms and Xmx arguments for java. It must be a whole number +# followed by the unit 'm' for MB or 'g' for GB. +# +# @param sysconfig_path +# The absolute path to the puppetserver sysconfig file. +# +class puppet::server ( + Boolean $ca = false, + Variant[Array[String, 1], Undef] $autosign_entries = undef, + Stdlib::Absolutepath $sysconfig_path = '/etc/sysconfig/puppetserver', + Pattern[/^\d+(m|g)$/] $memory_size = '2g', # only m and g are appropriate for unit + Optional[Stdlib::Absolutepath] $enc = undef, + Optional[String] $dns_alt_names = undef, ) { - - include ::puppet - - if $sysconfig_path != undef { - validate_absolute_path($sysconfig_path) - } - - validate_re($memory_size, '^\d+(m|g)$', - "puppet::memory_size is <${memory_size}> and must be an integer following by the unit 'm' or 'g'.") + include puppet $ini_defaults = { ensure => 'present', - path => $::puppet::config_path, + path => $puppet::config_path, section => 'master', require => File['puppet_config'], notify => Service['puppetserver'], } $non_conditional_ini_settings = { - 'vardir' => { setting => 'vardir', value => '/opt/puppetlabs/server/data/puppetserver',}, - 'logdir' => { setting => 'logdir', value => '/var/log/puppetlabs/puppetserver',}, - 'rundir' => { setting => 'rundir', value => '/var/run/puppetlabs/puppetserver',}, - 'pidfile' => { setting => 'pidfile', value => '/var/run/puppetlabs/puppetserver/puppetserver.pid',}, - 'codedir' => { setting => 'codedir', value =>'/etc/puppetlabs/code',}, - 'ca' => { setting => 'ca', value => $ca,}, + 'vardir' => { setting => 'vardir', value => '/opt/puppetlabs/server/data/puppetserver' }, + 'logdir' => { setting => 'logdir', value => '/var/log/puppetlabs/puppetserver' }, + 'rundir' => { setting => 'rundir', value => '/var/run/puppetlabs/puppetserver' }, + 'pidfile' => { setting => 'pidfile', value => '/var/run/puppetlabs/puppetserver/puppetserver.pid' }, + 'codedir' => { setting => 'codedir', value => '/etc/puppetlabs/code' }, + 'ca' => { setting => 'ca', value => $ca }, } if $enc != undef { - validate_absolute_path($enc) $ini_enc_settings = { 'node_terminus' => { setting => 'node_terminus', value => 'exec' }, 'external_nodes' => { setting => 'external_nodes', value => $enc }, diff --git a/metadata.json b/metadata.json index d6134dd..05c4a15 100644 --- a/metadata.json +++ b/metadata.json @@ -3,15 +3,22 @@ "version": "3.3.0", "author": "ghoneycutt", "summary": "Manages Puppet agent and puppetserver", - "description": "Manages Puppet agent and puppetserver.", "license": "Apache-2.0", "source": "git://github.com/ghoneycutt/puppet-module-puppet.git", "project_page": "https://github.com/ghoneycutt/puppet-module-puppet", "issues_url": "https://github.com/ghoneycutt/puppet-module-puppet/issues", - "requirements": [ + "dependencies": [ { - "name": "puppet", - "version_requirement": ">= 4.7.0 < 7.0.0" + "name": "puppetlabs/cron_core", + "version_requirement": ">= 1.0.0 <2.0.0" + }, + { + "name": "puppetlabs/inifile", + "version_requirement": ">= 1.6.0 < 7.0.0" + }, + { + "name": "puppetlabs/stdlib", + "version_requirement": ">= 5.0.0 < 10.0.0" } ], "operatingsystem_support": [ @@ -40,9 +47,14 @@ ] } ], - "dependencies": [ - {"name":"puppetlabs/cron_core","version_requirement":">= 1.0.0 <2.0.0"}, - {"name":"puppetlabs/inifile","version_requirement":">= 1.6.0 < 2.0.0"}, - {"name":"puppetlabs/stdlib","version_requirement":">= 4.6.0 < 6.0.0"} - ] + "requirements": [ + { + "name": "puppet", + "version_requirement": ">= 4.7.0 < 9.0.0" + } + ], + "description": "Manages Puppet agent and puppetserver.", + "pdk-version": "3.0.0", + "template-url": "pdk-default#3.0.0", + "template-ref": "tags/3.0.0-0-g056e50d" } diff --git a/spec/classes/init_spec.rb b/spec/classes/init_spec.rb index 3259751..042005a 100644 --- a/spec/classes/init_spec.rb +++ b/spec/classes/init_spec.rb @@ -4,7 +4,7 @@ minute = [2, 32] # Filter out duplicate platforms - platforms = on_supported_os.select { |k, _v| !k.to_s.match(/^(RedHat|Scientific|OracleLinux)/i) } + platforms = on_supported_os.reject { |k, _v| k.to_s.match(%r{^(RedHat|Scientific|OracleLinux)}i) } platforms.each do |os, facts| context "on #{os} with default values for parameters" do @@ -13,30 +13,34 @@ end it { is_expected.to compile.with_all_deps } - it { should contain_class('puppet') } + it { is_expected.to contain_class('puppet') } - it { should_not contain_file('puppetserver_sysconfig') } - it { should_not contain_service('puppetserver') } - it { should_not contain_class('puppet::server') } + it { is_expected.not_to contain_file('puppetserver_sysconfig') } + it { is_expected.not_to contain_service('puppetserver') } + it { is_expected.not_to contain_class('puppet::server') } it do - should contain_cron('puppet_agent_every_thirty').with({ - :ensure => 'present', - :command => '/opt/puppetlabs/bin/puppet agent --onetime --no-daemonize --no-usecacheonfailure --detailed-exitcodes --no-splay --noop', - :user => 'root', - :hour => '*', - #:minute => [16,46], - :minute => minute, - }) + is_expected.to contain_cron('puppet_agent_every_thirty').with( + { + ensure: 'present', + command: '/opt/puppetlabs/bin/puppet agent --onetime --no-daemonize --no-usecacheonfailure --detailed-exitcodes --no-splay --noop', + user: 'root', + hour: '*', + # minute: [16,46], + minute: minute, + }, + ) end it do - should contain_cron('puppet_agent_once_at_boot').with({ - :ensure => 'present', - :command => '/opt/puppetlabs/bin/puppet agent --onetime --no-daemonize --no-usecacheonfailure --detailed-exitcodes --no-splay --noop', - :user => 'root', - :special => 'reboot', - }) + is_expected.to contain_cron('puppet_agent_once_at_boot').with( + { + ensure: 'present', + command: '/opt/puppetlabs/bin/puppet agent --onetime --no-daemonize --no-usecacheonfailure --detailed-exitcodes --no-splay --noop', + user: 'root', + special: 'reboot', + }, + ) end ini_settings = { @@ -50,61 +54,69 @@ ini_settings.each do |setting, value| it do - should contain_ini_setting(setting).with({ - :ensure => 'present', - :setting => setting, - :value => value, - :path => '/etc/puppetlabs/puppet/puppet.conf', - :section => 'main', - :require => 'File[puppet_config]', - }) + is_expected.to contain_ini_setting(setting).with( + { + ensure: 'present', + setting: setting, + value: value, + path: '/etc/puppetlabs/puppet/puppet.conf', + section: 'main', + require: 'File[puppet_config]', + }, + ) end end it do - should contain_file('puppet_config').with({ - :ensure => 'file', - :path => '/etc/puppetlabs/puppet/puppet.conf', - :owner => 'root', - :group => 'root', - :mode => '0644', - }) + is_expected.to contain_file('puppet_config').with( + { + ensure: 'file', + path: '/etc/puppetlabs/puppet/puppet.conf', + owner: 'root', + group: 'root', + mode: '0644', + }, + ) end puppet_agent_sysconfig = File.read(fixtures('puppet_agent_sysconfig')) it do - should contain_file('puppet_agent_sysconfig').with({ - :ensure => 'file', - :path => '/etc/sysconfig/puppet', - :content => puppet_agent_sysconfig, - :owner => 'root', - :group => 'root', - :mode => '0644', - }) + is_expected.to contain_file('puppet_agent_sysconfig').with( + { + ensure: 'file', + path: '/etc/sysconfig/puppet', + content: puppet_agent_sysconfig, + owner: 'root', + group: 'root', + mode: '0644', + }, + ) end it do - should contain_service('puppet_agent_daemon').with({ - :ensure => 'stopped', - :name => 'puppet', - :enable => false, - }) + is_expected.to contain_service('puppet_agent_daemon').with( + { + ensure: 'stopped', + name: 'puppet', + enable: false, + }, + ) end end end describe 'with run_every_thirty' do - [true, 'true', false, 'false'].each do |value| - [true, 'true', false, 'false'].each do |noop_value| + [true, false].each do |value| + [true, false].each do |noop_value| context "set to #{value} (as #{value.class}) and run_in_noop set to #{noop_value} (as #{noop_value.class})" do let(:params) do { - :run_every_thirty => value, - :run_in_noop => noop_value, + run_every_thirty: value, + run_in_noop: noop_value, } end - if [true, 'true'].include?(value) + if value == true cron_ensure = 'present' cron_minute = minute else @@ -112,20 +124,22 @@ cron_minute = nil end - cron_command = if [true, 'true'].include?(noop_value) + cron_command = if noop_value == true '/opt/puppetlabs/bin/puppet agent --onetime --no-daemonize --no-usecacheonfailure --detailed-exitcodes --no-splay --noop' else '/opt/puppetlabs/bin/puppet agent --onetime --no-daemonize --no-usecacheonfailure --detailed-exitcodes --no-splay' end it do - should contain_cron('puppet_agent_every_thirty').with({ - :ensure => cron_ensure, - :command => cron_command, - :user => 'root', - :hour => '*', - :minute => cron_minute, - }) + is_expected.to contain_cron('puppet_agent_every_thirty').with( + { + ensure: cron_ensure, + command: cron_command, + user: 'root', + hour: '*', + minute: cron_minute, + }, + ) end end end @@ -136,177 +150,205 @@ context 'and run_in_noop set to true' do let(:params) do { - :run_in_noop => true, - :cron_command => '/some/command' + run_in_noop: true, + cron_command: '/some/command' } end - it { should contain_cron('puppet_agent_every_thirty').with_command('/some/command --noop') } - it { should contain_cron('puppet_agent_once_at_boot').with_command('/some/command --noop') } + it { is_expected.to contain_cron('puppet_agent_every_thirty').with_command('/some/command --noop') } + it { is_expected.to contain_cron('puppet_agent_once_at_boot').with_command('/some/command --noop') } end context 'and run_in_noop set to false' do let(:params) do { - :run_in_noop => false, - :cron_command => '/some/command' + run_in_noop: false, + cron_command: '/some/command' } end - it { should contain_cron('puppet_agent_every_thirty').with_command('/some/command') } - it { should contain_cron('puppet_agent_once_at_boot').with_command('/some/command') } + it { is_expected.to contain_cron('puppet_agent_every_thirty').with_command('/some/command') } + it { is_expected.to contain_cron('puppet_agent_once_at_boot').with_command('/some/command') } end end describe 'with run_at_boot' do - [true, 'true', false, 'false'].each do |value| + [true, false].each do |value| context "set to #{value} (as #{value.class})" do - let(:params) { { :run_at_boot => value } } + let(:params) { { run_at_boot: value } } - foo = if [true, 'true'].include?(value) + foo = if value == true 'present' else 'absent' end - it { should contain_cron('puppet_agent_once_at_boot').with_ensure(foo) } + it { is_expected.to contain_cron('puppet_agent_once_at_boot').with_ensure(foo) } end end end describe 'with config_path specified' do - let(:params) { { :config_path => '/path/to/puppet.conf' } } + let(:params) { { config_path: '/path/to/puppet.conf' } } - it { should contain_file('puppet_config').with_path('/path/to/puppet.conf') } + it { is_expected.to contain_file('puppet_config').with_path('/path/to/puppet.conf') } - ini_settings = %w(server ca_server certname environment trusted_node_data graph) + ini_settings = ['server', 'ca_server', 'certname', 'environment', 'trusted_node_data', 'graph'] ini_settings.each do |setting| - it { should contain_ini_setting(setting).with_path('/path/to/puppet.conf') } + it { is_expected.to contain_ini_setting(setting).with_path('/path/to/puppet.conf') } end end describe 'with puppet.conf ini setting' do - %w(server ca_server certname graph).each do |setting| + ['server', 'ca_server', 'certname'].each do |setting| context "#{setting} set to a valid entry" do - # 'true' is used because it is acceptable to all of the above - # parameters. Some of the settings are strings and some are boolean and - # stringified booleans. - let(:params) { { setting => 'true' } } + let(:params) { { setting => 'testing' } } it do - should contain_ini_setting(setting).with({ - :ensure => 'present', - :setting => setting, - :value => 'true', - :path => '/etc/puppetlabs/puppet/puppet.conf', - :section => 'main', - :require => 'File[puppet_config]', - }) + is_expected.to contain_ini_setting(setting).with( + { + ensure: 'present', + setting: setting, + value: 'testing', + path: '/etc/puppetlabs/puppet/puppet.conf', + section: 'main', + require: 'File[puppet_config]', + }, + ) end end end end + context 'with graph set to a valid entry' do + let(:params) { { graph: true } } + + it do + is_expected.to contain_ini_setting('graph').with( + { + ensure: 'present', + setting: 'graph', + value: 'true', + path: '/etc/puppetlabs/puppet/puppet.conf', + section: 'main', + require: 'File[puppet_config]', + }, + ) + end + end + describe 'with env specified' do - let(:params) { { :env => 'myenv' } } + let(:params) { { env: 'myenv' } } it do - should contain_ini_setting('environment').with({ - :ensure => 'present', - :setting => 'environment', - :value => 'myenv', - :path => '/etc/puppetlabs/puppet/puppet.conf', - :section => 'main', - :require => 'File[puppet_config]', - }) + is_expected.to contain_ini_setting('environment').with( + { + ensure: 'present', + setting: 'environment', + value: 'myenv', + path: '/etc/puppetlabs/puppet/puppet.conf', + section: 'main', + require: 'File[puppet_config]', + }, + ) end end describe 'without env specified' do it do - should contain_ini_setting('environment').with({ - :ensure => 'present', - :setting => 'environment', - :value => 'rp_env', - :path => '/etc/puppetlabs/puppet/puppet.conf', - :section => 'main', - :require => 'File[puppet_config]', - }) + is_expected.to contain_ini_setting('environment').with( + { + ensure: 'present', + setting: 'environment', + value: 'rp_env', + path: '/etc/puppetlabs/puppet/puppet.conf', + section: 'main', + require: 'File[puppet_config]', + }, + ) end end describe 'with server specified' do - let(:params) { { :server => 'foo' } } + let(:params) { { server: 'foo' } } it do - should contain_ini_setting('server').with({ - :ensure => 'present', - :setting => 'server', - :value => 'foo', - :path => '/etc/puppetlabs/puppet/puppet.conf', - :section => 'main', - :require => 'File[puppet_config]', - }) + is_expected.to contain_ini_setting('server').with( + { + ensure: 'present', + setting: 'server', + value: 'foo', + path: '/etc/puppetlabs/puppet/puppet.conf', + section: 'main', + require: 'File[puppet_config]', + }, + ) end end describe 'with custom_settings specified' do - let(:params) { { - :custom_settings => { - 'codedir' => { 'section' => 'master', 'setting' => 'codedir', 'value' => '/spec/testing' }, - 'testing' => { 'section' => 'agent', 'setting' => 'server', 'value' => 'spec.test.ing' }, + let(:params) do + { + custom_settings: { + 'codedir' => { 'section' => 'master', 'setting' => 'codedir', 'value' => '/spec/testing' }, + 'testing' => { 'section' => 'agent', 'setting' => 'server', 'value' => 'spec.test.ing' }, + } } - } } + end it do - should contain_ini_setting('codedir').with({ - :ensure => 'present', - :path => '/etc/puppetlabs/puppet/puppet.conf', - :section => 'master', - :setting => 'codedir', - :value => '/spec/testing', - :require => 'File[puppet_config]', - }) + is_expected.to contain_ini_setting('codedir').with( + { + ensure: 'present', + path: '/etc/puppetlabs/puppet/puppet.conf', + section: 'master', + setting: 'codedir', + value: '/spec/testing', + require: 'File[puppet_config]', + }, + ) end it do - should contain_ini_setting('testing').with({ - :ensure => 'present', - :path => '/etc/puppetlabs/puppet/puppet.conf', - :section => 'agent', - :setting => 'server', - :value => 'spec.test.ing', - :require => 'File[puppet_config]', - }) + is_expected.to contain_ini_setting('testing').with( + { + ensure: 'present', + path: '/etc/puppetlabs/puppet/puppet.conf', + section: 'agent', + setting: 'server', + value: 'spec.test.ing', + require: 'File[puppet_config]', + }, + ) end end describe 'parameter type and content validations' do validations = { - 'absolute paths' => { - :name => %w(config_path agent_sysconfig_path), - :valid => ['/absolute/path'], - :invalid => ['not/an/absolute/path'], - :message => 'is not an absolute path', + 'Stdlib::Absolutepath' => { + name: ['config_path', 'agent_sysconfig_path'], + valid: ['/absolute/path'], + invalid: ['not/an/absolute/path', ['array'], { 'ha' => 'sh' }, 3, 2.42, false], + message: 'expects a Stdlib::Absolutepath', }, - 'booleans' => { - :name => %w(run_every_thirty run_in_noop run_at_boot graph), - :valid => [true, 'true', false, 'false'], - :invalid => ['string', %w(array), { 'ha' => 'sh' }, 3, 2.42], - :message => 'Error while evaluating a Resource Statement', + 'Boolean' => { + name: ['run_every_thirty', 'run_in_noop', 'run_at_boot', 'graph'], + valid: [true, false], + invalid: ['string', ['array'], { 'ha' => 'sh' }, 3, 2.42], + message: 'expects a Boolean', }, 'hash' => { - :name => %w(custom_settings), - :valid => [], # valid hashes are to complex to block test them here - :invalid => ['string', %w(array), 3, 2.42, true, nil], - :message => 'expects a Hash value', + name: ['custom_settings'], + valid: [], # valid hashes are to complex to block test them here + invalid: ['string', ['array'], 3, 2.42, false, nil], + message: 'expects a Hash value', }, 'strings' => { - :name => %w(certname cron_command server ca_server env), - :valid => ['string'], - :invalid => [true, %w(array), { 'ha' => 'sh' }, 3, 2.42], - :message => 'Error while evaluating a Resource Statement', + name: ['certname', 'cron_command', 'server', 'ca_server', 'env'], + valid: ['string'], + invalid: [true, ['array'], { 'ha' => 'sh' }, 3, 2.42, false], + message: 'Error while evaluating a Resource Statement', }, } @@ -315,16 +357,18 @@ var[:params] = {} if var[:params].nil? var[:valid].each do |valid| context "when #{var_name} (#{type}) is set to valid #{valid} (as #{valid.class})" do - let(:params) { [var[:params], { :"#{var_name}" => valid, }].reduce(:merge) } - it { should compile } + let(:params) { [var[:params], { "#{var_name}": valid, }].reduce(:merge) } + + it { is_expected.to compile } end end var[:invalid].each do |invalid| context "when #{var_name} (#{type}) is set to invalid #{invalid} (as #{invalid.class})" do - let(:params) { [var[:params], { :"#{var_name}" => invalid, }].reduce(:merge) } - it 'should fail' do - expect { should contain_class(subject) }.to raise_error(Puppet::Error, /#{var[:message]}/) + let(:params) { [var[:params], { "#{var_name}": invalid, }].reduce(:merge) } + + it 'fails' do + expect { is_expected.to contain_class(:subject) }.to raise_error(Puppet::Error, %r{#{var[:message]}}) end end end diff --git a/spec/classes/server_spec.rb b/spec/classes/server_spec.rb index 5f06b1e..89f46ce 100644 --- a/spec/classes/server_spec.rb +++ b/spec/classes/server_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe 'puppet::server' do # Filter out duplicate platforms - platforms = on_supported_os.select { |k, _v| !k.to_s.match(/^(RedHat|Scientific|OracleLinux)/i) } + platforms = on_supported_os.reject { |k, _v| k.to_s.match(%r{^(RedHat|Scientific|OracleLinux)}i) } platforms.each do |os, facts| context "on #{os} with default values for parameters" do @@ -10,8 +10,8 @@ end it { is_expected.to compile.with_all_deps } - it { should contain_class('puppet') } - it { should contain_class('puppet::server') } + it { is_expected.to contain_class('puppet') } + it { is_expected.to contain_class('puppet::server') } non_conditional_ini_settings = { 'vardir' => '/opt/puppetlabs/server/data/puppetserver', @@ -24,79 +24,89 @@ non_conditional_ini_settings.each do |setting, value| it do - should contain_ini_setting(setting).with({ - :ensure => 'present', - :setting => setting, - :value => value, - :path => '/etc/puppetlabs/puppet/puppet.conf', - :section => 'master', - :require => 'File[puppet_config]', - :notify => 'Service[puppetserver]', - }) + is_expected.to contain_ini_setting(setting).with( + { + ensure: 'present', + setting: setting, + value: value, + path: '/etc/puppetlabs/puppet/puppet.conf', + section: 'master', + require: 'File[puppet_config]', + notify: 'Service[puppetserver]', + }, + ) end end - %w(node_terminus external_nodes dns_alt_names).each do |setting| - it { should_not contain_ini_setting(setting) } + ['node_terminus', 'external_nodes', 'dns_alt_names'].each do |setting| + it { is_expected.not_to contain_ini_setting(setting) } end - empty_autosign_content = <<-END.gsub(/^\s+\|/, '') + empty_autosign_content = <<-END.gsub(%r{^\s+\|}, '') |# This file is being maintained by Puppet. |# DO NOT EDIT END it do - should contain_file('autosign_config').with({ - :ensure => 'file', - :path => '/etc/puppetlabs/puppet/autosign.conf', - :content => empty_autosign_content, - :owner => 'root', - :group => 'root', - :mode => '0644', - :notify => 'Service[puppetserver]', - }) + is_expected.to contain_file('autosign_config').with( + { + ensure: 'file', + path: '/etc/puppetlabs/puppet/autosign.conf', + content: empty_autosign_content, + owner: 'root', + group: 'root', + mode: '0644', + notify: 'Service[puppetserver]', + }, + ) end puppetserver_sysconfig = File.read(fixtures('puppetserver_sysconfig')) it do - should contain_file('puppetserver_sysconfig').with({ - :ensure => 'file', - :path => '/etc/sysconfig/puppetserver', - :content => puppetserver_sysconfig, - :owner => 'root', - :group => 'root', - :mode => '0644', - }) + is_expected.to contain_file('puppetserver_sysconfig').with( + { + ensure: 'file', + path: '/etc/sysconfig/puppetserver', + content: puppetserver_sysconfig, + owner: 'root', + group: 'root', + mode: '0644', + }, + ) end it do - should contain_service('puppetserver').with({ - :ensure => 'running', - :enable => true, - :subscribe => [ - 'File[puppet_config]', - 'File[puppetserver_sysconfig]', - ], - }) + is_expected.to contain_service('puppetserver').with( + { + ensure: 'running', + enable: true, + subscribe: [ + 'File[puppet_config]', + 'File[puppetserver_sysconfig]', + ], + }, + ) end end end describe 'with ca' do - [true, 'true', false, 'false'].each do |value| + [true, false].each do |value| context "set to #{value} (as #{value.class})" do - let(:params) { { :ca => value } } + let(:params) { { ca: value } } it do - should contain_ini_setting('ca').with({ - :ensure => 'present', - :setting => 'ca', - :value => value, - :path => '/etc/puppetlabs/puppet/puppet.conf', - :section => 'master', - :require => 'File[puppet_config]', - :notify => 'Service[puppetserver]', - }) + is_expected.to contain_ini_setting('ca').with( + { + ensure: 'present', + setting: 'ca', + value: value, + path: '/etc/puppetlabs/puppet/puppet.conf', + section: 'master', + require: 'File[puppet_config]', + notify: 'Service[puppetserver]', + }, + ) end end end @@ -104,98 +114,104 @@ describe 'with enc' do context 'set to a valid path' do - let(:params) { { :enc => '/path/to/enc' } } + let(:params) { { enc: '/path/to/enc' } } it do - should contain_ini_setting('external_nodes').with({ - :ensure => 'present', - :setting => 'external_nodes', - :value => '/path/to/enc', - :path => '/etc/puppetlabs/puppet/puppet.conf', - :section => 'master', - :require => 'File[puppet_config]', - :notify => 'Service[puppetserver]', - }) + is_expected.to contain_ini_setting('external_nodes').with( + { + ensure: 'present', + setting: 'external_nodes', + value: '/path/to/enc', + path: '/etc/puppetlabs/puppet/puppet.conf', + section: 'master', + require: 'File[puppet_config]', + notify: 'Service[puppetserver]', + }, + ) end it do - should contain_ini_setting('node_terminus').with({ - :ensure => 'present', - :setting => 'node_terminus', - :value => 'exec', - :path => '/etc/puppetlabs/puppet/puppet.conf', - :section => 'master', - :require => 'File[puppet_config]', - :notify => 'Service[puppetserver]', - }) + is_expected.to contain_ini_setting('node_terminus').with( + { + ensure: 'present', + setting: 'node_terminus', + value: 'exec', + path: '/etc/puppetlabs/puppet/puppet.conf', + section: 'master', + require: 'File[puppet_config]', + notify: 'Service[puppetserver]', + }, + ) end end end describe 'with dns_alt_names' do context 'set to a valid path' do - let(:params) { { :dns_alt_names => 'foo,foo1,foo1.example.com,foo.example.com' } } + let(:params) { { dns_alt_names: 'foo,foo1,foo1.example.com,foo.example.com' } } it do - should contain_ini_setting('dns_alt_names').with({ - :ensure => 'present', - :setting => 'dns_alt_names', - :value => 'foo,foo1,foo1.example.com,foo.example.com', - :path => '/etc/puppetlabs/puppet/puppet.conf', - :section => 'master', - :require => 'File[puppet_config]', - :notify => 'Service[puppetserver]', - }) + is_expected.to contain_ini_setting('dns_alt_names').with( + { + ensure: 'present', + setting: 'dns_alt_names', + value: 'foo,foo1,foo1.example.com,foo.example.com', + path: '/etc/puppetlabs/puppet/puppet.conf', + section: 'master', + require: 'File[puppet_config]', + notify: 'Service[puppetserver]', + }, + ) end end end describe 'with autosign_entries' do context 'set to a valid array of strings' do - let(:params) { { :autosign_entries => ['*.example.org', '*.dev.example.org'] } } + let(:params) { { autosign_entries: ['*.example.org', '*.dev.example.org'] } } - autosign_conf_content = <<-END.gsub(/^\s+\|/, '') + autosign_conf_content = <<-END.gsub(%r{^\s+\|}, '') |# This file is being maintained by Puppet. |# DO NOT EDIT |*.example.org |*.dev.example.org END - it { should contain_file('autosign_config').with_content(autosign_conf_content) } + it { is_expected.to contain_file('autosign_config').with_content(autosign_conf_content) } end end describe 'parameter type and content validations' do validations = { - 'absolute paths' => { - :name => %w(sysconfig_path enc), - :valid => ['/absolute/path'], - :invalid => ['not/an/absolute/path'], - :message => 'is not an absolute path', + 'Stdlib::Absolutepath' => { + name: ['sysconfig_path', 'enc'], + valid: ['/absolute/path'], + invalid: ['not/an/absolute/path'], + message: 'expects a Stdlib::Absolutepath', }, - 'booleans' => { - :name => %w(ca), - :valid => [true, 'true', false, 'false'], - :invalid => ['string', %w(array), { 'ha' => 'sh' }, 3, 2.42], - :message => 'Error while evaluating a Resource Statement', + 'Boolean' => { + name: ['ca'], + valid: [true, false], + invalid: ['string', ['array'], { 'ha' => 'sh' }, 3, 2.42], + message: 'expects a Boolean', }, 'strings' => { - :name => %w(dns_alt_names), - :valid => ['string'], - :invalid => [true, %w(array), { 'ha' => 'sh' }, 3, 2.42], - :message => 'Error while evaluating a Resource Statement', + name: ['dns_alt_names'], + valid: ['string'], + invalid: [true, ['array'], { 'ha' => 'sh' }, 3, 2.42], + message: 'Error while evaluating a Resource Statement', }, 'non-empty array of strings' => { - :name => %w(autosign_entries), - :valid => [['array with one string'], %w(array with many strings)], - :invalid => [%w(), [1, 'not_all', 'string'], true, 'string', { 'ha' => 'sh' }, 3, 2.42], - :message => 'Error while evaluating a Resource Statement', + name: ['autosign_entries'], + valid: [['array with one string'], ['array', 'with', 'many', 'strings']], + invalid: [[], [1, 'not_all', 'string'], true, 'string', { 'ha' => 'sh' }, 3, 2.42], + message: 'Error while evaluating a Resource Statement', }, - 'memory size regex' => { - :name => %w(memory_size), - :valid => %w(1g 1m 1500m 3g), - :invalid => ['1g1', 'm', '1k', '2t', 'g3', '1.2g'], - :message => 'must be an integer following by the unit', + 'Pattern[/^\d+(m|g)$/]' => { + name: ['memory_size'], + valid: ['1g', '1m', '1500m', '3g'], + invalid: ['1g1', 'm', '1k', '2t', 'g3', '1.2g'], + message: 'expects a match for Pattern', }, } @@ -204,16 +220,18 @@ var[:params] = {} if var[:params].nil? var[:valid].each do |valid| context "when #{var_name} (#{type}) is set to valid #{valid} (as #{valid.class})" do - let(:params) { [var[:params], { :"#{var_name}" => valid, }].reduce(:merge) } - it { should compile } + let(:params) { [var[:params], { "#{var_name}": valid, }].reduce(:merge) } + + it { is_expected.to compile } end end var[:invalid].each do |invalid| context "when #{var_name} (#{type}) is set to invalid #{invalid} (as #{invalid.class})" do - let(:params) { [var[:params], { :"#{var_name}" => invalid, }].reduce(:merge) } - it 'should fail' do - expect { should contain_class(subject) }.to raise_error(Puppet::Error, /#{var[:message]}/) + let(:params) { [var[:params], { "#{var_name}": invalid, }].reduce(:merge) } + + it 'is_expected.to fail' do + expect { is_expected.to contain_class(:subject) }.to raise_error(Puppet::Error, %r{#{var[:message]}}) end end end diff --git a/spec/default_facts.yml b/spec/default_facts.yml new file mode 100644 index 0000000..f777abf --- /dev/null +++ b/spec/default_facts.yml @@ -0,0 +1,8 @@ +# Use default_module_facts.yml for module specific facts. +# +# Facts specified here will override the values provided by rspec-puppet-facts. +--- +ipaddress: "172.16.254.254" +ipaddress6: "FE80:0000:0000:0000:AAAA:AAAA:AAAA" +is_pe: false +macaddress: "AA:AA:AA:AA:AA:AA" diff --git a/spec/default_module_facts.yml b/spec/default_module_facts.yml new file mode 100644 index 0000000..7f16806 --- /dev/null +++ b/spec/default_module_facts.yml @@ -0,0 +1,6 @@ +--- +# ensure fqdn matches when using rspec-puppet-facts so that fqdn_rand() +# gives consistent output +fqdn: "puppet.example.com" +networking: + fqdn: "puppet.example.com" diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 9d61fa6..61df294 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,27 +1,74 @@ +# frozen_string_literal: true + RSpec.configure do |c| c.mock_with :rspec end require 'puppetlabs_spec_helper/module_spec_helper' require 'rspec-puppet-facts' + +require 'spec_helper_local' if File.file?(File.join(File.dirname(__FILE__), 'spec_helper_local.rb')) + include RspecPuppetFacts -RSpec.configure do |config| - config.hiera_config = 'spec/fixtures/hiera/hiera.yaml' - config.before :each do - # Ensure that we don't accidentally cache facts and environment between - # test cases. This requires each example group to explicitly load the - # facts being exercised with something like - # Facter.collection.loader.load(:ipaddress) - Facter.clear - Facter.clear_messages +default_facts = { + puppetversion: Puppet.version, + facterversion: Facter.version, +} + +default_fact_files = [ + File.expand_path(File.join(File.dirname(__FILE__), 'default_facts.yml')), + File.expand_path(File.join(File.dirname(__FILE__), 'default_module_facts.yml')), +] + +default_fact_files.each do |f| + next unless File.exist?(f) && File.readable?(f) && File.size?(f) + + begin + default_facts.merge!(YAML.safe_load(File.read(f), permitted_classes: [], permitted_symbols: [], aliases: true)) + rescue StandardError => e + RSpec.configuration.reporter.message "WARNING: Unable to load #{f}: #{e}" + end +end + +# read default_facts and merge them over what is provided by facterdb +default_facts.each do |fact, value| + add_custom_fact fact, value +end + +RSpec.configure do |c| + c.default_facts = default_facts + c.before :each do + # set to strictest setting for testing + # by default Puppet runs at warning level + Puppet.settings[:strict] = :warning + Puppet.settings[:strict_variables] = true + end + c.filter_run_excluding(bolt: true) unless ENV['GEM_BOLT'] + c.after(:suite) do + RSpec::Puppet::Coverage.report!(100) + end + + # Filter backtrace noise + backtrace_exclusion_patterns = [ + %r{spec_helper}, + %r{gems}, + ] + + if c.respond_to?(:backtrace_exclusion_patterns) + c.backtrace_exclusion_patterns = backtrace_exclusion_patterns + elsif c.respond_to?(:backtrace_clean_patterns) + c.backtrace_clean_patterns = backtrace_exclusion_patterns + end +end + +# Ensures that a module is defined +# @param module_name Name of the module +def ensure_module_defined(module_name) + module_name.split('::').reduce(Object) do |last_module, next_module| + last_module.const_set(next_module, Module.new) unless last_module.const_defined?(next_module, false) + last_module.const_get(next_module, false) end - config.default_facts = { - :environment => 'rp_env', - :fqdn => 'puppet.example.com', - } end -# ensure fqdn matches when using rspec-puppet-facts so that fqdn_rand() gives -# consistent output -add_custom_fact :fqdn, 'puppet.example.com' +# 'spec_overrides' from sync.yml will appear below this line