├── .fixtures.yml ├── .gitattributes ├── .github └── workflows │ ├── release.yml │ └── release_prep.yml ├── .gitignore ├── .gitlab-ci.yml ├── .pdkignore ├── .puppet-lint.rc ├── .rspec ├── .rubocop.yml ├── .sync.yml ├── .travis.yml ├── .vscode └── extensions.json ├── .yardopts ├── CHANGELOG.md ├── CODEOWNERS ├── Gemfile ├── LICENSE ├── NOTICE ├── README.md ├── Rakefile ├── data ├── common.yaml └── os │ ├── Debian.yaml │ ├── FreeBSD.yaml │ ├── RedHat.yaml │ ├── RedHat │ ├── 8.yaml │ └── 9.yaml │ └── Suse.yaml ├── examples ├── init.pp ├── repo.pp └── server_with_motd.pp ├── files ├── defaults └── motd ├── hiera.yaml ├── locales └── config.yaml ├── manifests ├── get.pp ├── init.pp ├── put.pp ├── repo.pp ├── server.pp └── server │ └── module.pp ├── metadata.json ├── spec ├── classes │ └── server_spec.rb ├── default_facts.yml ├── defines │ ├── get_spec.rb │ ├── put_spec.rb │ └── server_module_spec.rb └── spec_helper.rb └── templates ├── header.erb └── module.erb /.fixtures.yml: -------------------------------------------------------------------------------- 1 | fixtures: 2 | repositories: 3 | xinetd: 'https://github.com/puppetlabs/puppetlabs-xinetd.git' 4 | concat: 'https://github.com/puppetlabs/puppetlabs-concat.git' 5 | stdlib: 'https://github.com/puppetlabs/puppetlabs-stdlib.git' 6 | symlinks: 7 | "rsync": "#{source_dir}" 8 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.rb eol=lf 2 | *.erb eol=lf 3 | *.pp eol=lf 4 | *.sh eol=lf 5 | *.epp eol=lf 6 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: "Publish module" 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | release: 8 | uses: "puppetlabs/cat-github-actions/.github/workflows/module_release.yml@main" 9 | secrets: "inherit" 10 | -------------------------------------------------------------------------------- /.github/workflows/release_prep.yml: -------------------------------------------------------------------------------- 1 | name: "Release Prep" 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | version: 7 | description: "Module version to be released. Must be a valid semver string. (1.2.3)" 8 | required: true 9 | 10 | jobs: 11 | release_prep: 12 | uses: "puppetlabs/cat-github-actions/.github/workflows/module_release_prep.yml@main" 13 | with: 14 | version: "${{ github.event.inputs.version }}" 15 | secrets: "inherit" 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .git/ 2 | .*.sw[op] 3 | .metadata 4 | .yardoc 5 | .yardwarns 6 | *.iml 7 | /.bundle/ 8 | /.idea/ 9 | /.vagrant/ 10 | /coverage/ 11 | /bin/ 12 | /doc/ 13 | /Gemfile.local 14 | /Gemfile.lock 15 | /junit/ 16 | /log/ 17 | /pkg/ 18 | /spec/fixtures/manifests/ 19 | /spec/fixtures/modules/* 20 | /tmp/ 21 | /vendor/ 22 | /convert_report.txt 23 | /update_report.txt 24 | .DS_Store 25 | .project 26 | .envrc 27 | /inventory.yaml 28 | /spec/fixtures/litmus_inventory.yaml 29 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | --- 2 | stages: 3 | - syntax 4 | - unit 5 | 6 | cache: 7 | paths: 8 | - vendor/bundle 9 | 10 | before_script: 11 | - bundle -v 12 | - rm Gemfile.lock || true 13 | - "# Update system gems if requested. This is useful to temporarily workaround troubles in the test runner" 14 | - "# Set `rubygems_version` in the .sync.yml to set a value" 15 | - "# Ignore exit code of SIGPIPE'd yes to not fail with shell's pipefail set" 16 | - '[ -z "$RUBYGEMS_VERSION" ] || (yes || true) | gem update --system $RUBYGEMS_VERSION' 17 | - gem --version 18 | - bundle -v 19 | - bundle install --without system_tests --path vendor/bundle --jobs $(nproc) 20 | 21 | syntax lint metadata_lint check:symlinks check:git_ignore check:dot_underscore check:test_file rubocop-Ruby 2.5.7-Puppet ~> 6: 22 | stage: syntax 23 | image: ruby:2.5.7 24 | script: 25 | - bundle exec rake syntax lint metadata_lint check:symlinks check:git_ignore check:dot_underscore check:test_file rubocop 26 | variables: 27 | PUPPET_GEM_VERSION: '~> 6' 28 | 29 | parallel_spec-Ruby 2.5.7-Puppet ~> 6: 30 | stage: unit 31 | image: ruby:2.5.7 32 | script: 33 | - bundle exec rake parallel_spec 34 | variables: 35 | PUPPET_GEM_VERSION: '~> 6' 36 | 37 | parallel_spec-Ruby 2.4.5-Puppet ~> 5: 38 | stage: unit 39 | image: ruby:2.4.5 40 | script: 41 | - bundle exec rake parallel_spec 42 | variables: 43 | PUPPET_GEM_VERSION: '~> 5' 44 | 45 | -------------------------------------------------------------------------------- /.pdkignore: -------------------------------------------------------------------------------- 1 | .git/ 2 | .*.sw[op] 3 | .metadata 4 | .yardoc 5 | .yardwarns 6 | *.iml 7 | /.bundle/ 8 | /.idea/ 9 | /.vagrant/ 10 | /coverage/ 11 | /bin/ 12 | /doc/ 13 | /Gemfile.local 14 | /Gemfile.lock 15 | /junit/ 16 | /log/ 17 | /pkg/ 18 | /spec/fixtures/manifests/ 19 | /spec/fixtures/modules/* 20 | /tmp/ 21 | /vendor/ 22 | /convert_report.txt 23 | /update_report.txt 24 | .DS_Store 25 | .project 26 | .envrc 27 | /inventory.yaml 28 | /spec/fixtures/litmus_inventory.yaml 29 | /.fixtures.yml 30 | /Gemfile 31 | /.gitattributes 32 | /.github/ 33 | /.gitignore 34 | /.pdkignore 35 | /.puppet-lint.rc 36 | /Rakefile 37 | /rakelib/ 38 | /.rspec 39 | /..yml 40 | /.yardopts 41 | /spec/ 42 | /.vscode/ 43 | /.sync.yml 44 | /.devcontainer/ 45 | -------------------------------------------------------------------------------- /.puppet-lint.rc: -------------------------------------------------------------------------------- 1 | --relative 2 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --format documentation 3 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | --- 2 | require: 3 | - rubocop-performance 4 | - rubocop-rspec 5 | AllCops: 6 | DisplayCopNames: true 7 | TargetRubyVersion: '2.6' 8 | Include: 9 | - "**/*.rb" 10 | Exclude: 11 | - bin/* 12 | - ".vendor/**/*" 13 | - "**/Gemfile" 14 | - "**/Rakefile" 15 | - pkg/**/* 16 | - spec/fixtures/**/* 17 | - vendor/**/* 18 | - "**/Puppetfile" 19 | - "**/Vagrantfile" 20 | - "**/Guardfile" 21 | Layout/LineLength: 22 | Description: People have wide screens, use them. 23 | Max: 200 24 | RSpec/BeforeAfterAll: 25 | Description: Beware of using after(:all) as it may cause state to leak between tests. 26 | A necessary evil in acceptance testing. 27 | Exclude: 28 | - spec/acceptance/**/*.rb 29 | RSpec/HookArgument: 30 | Description: Prefer explicit :each argument, matching existing module's style 31 | EnforcedStyle: each 32 | RSpec/DescribeSymbol: 33 | Exclude: 34 | - spec/unit/facter/**/*.rb 35 | Style/BlockDelimiters: 36 | Description: Prefer braces for chaining. Mostly an aesthetical choice. Better to 37 | be consistent then. 38 | EnforcedStyle: braces_for_chaining 39 | Style/ClassAndModuleChildren: 40 | Description: Compact style reduces the required amount of indentation. 41 | EnforcedStyle: compact 42 | Style/EmptyElse: 43 | Description: Enforce against empty else clauses, but allow `nil` for clarity. 44 | EnforcedStyle: empty 45 | Style/FormatString: 46 | Description: Following the main puppet project's style, prefer the % format format. 47 | EnforcedStyle: percent 48 | Style/FormatStringToken: 49 | Description: Following the main puppet project's style, prefer the simpler template 50 | tokens over annotated ones. 51 | EnforcedStyle: template 52 | Style/Lambda: 53 | Description: Prefer the keyword for easier discoverability. 54 | EnforcedStyle: literal 55 | Style/RegexpLiteral: 56 | Description: Community preference. See https://github.com/voxpupuli/modulesync_config/issues/168 57 | EnforcedStyle: percent_r 58 | Style/TernaryParentheses: 59 | Description: Checks for use of parentheses around ternary conditions. Enforce parentheses 60 | on complex expressions for better readability, but seriously consider breaking 61 | it up. 62 | EnforcedStyle: require_parentheses_when_complex 63 | Style/TrailingCommaInArguments: 64 | Description: Prefer always trailing comma on multiline argument lists. This makes 65 | diffs, and re-ordering nicer. 66 | EnforcedStyleForMultiline: comma 67 | Style/TrailingCommaInArrayLiteral: 68 | Description: Prefer always trailing comma on multiline literals. This makes diffs, 69 | and re-ordering nicer. 70 | EnforcedStyleForMultiline: comma 71 | Style/SymbolArray: 72 | Description: Using percent style obscures symbolic intent of array's contents. 73 | EnforcedStyle: brackets 74 | RSpec/MessageSpies: 75 | EnforcedStyle: receive 76 | Style/Documentation: 77 | Exclude: 78 | - lib/puppet/parser/functions/**/* 79 | - spec/**/* 80 | Style/WordArray: 81 | EnforcedStyle: brackets 82 | Performance/AncestorsInclude: 83 | Enabled: true 84 | Performance/BigDecimalWithNumericArgument: 85 | Enabled: true 86 | Performance/BlockGivenWithExplicitBlock: 87 | Enabled: true 88 | Performance/CaseWhenSplat: 89 | Enabled: true 90 | Performance/ConstantRegexp: 91 | Enabled: true 92 | Performance/MethodObjectAsBlock: 93 | Enabled: true 94 | Performance/RedundantSortBlock: 95 | Enabled: true 96 | Performance/RedundantStringChars: 97 | Enabled: true 98 | Performance/ReverseFirst: 99 | Enabled: true 100 | Performance/SortReverse: 101 | Enabled: true 102 | Performance/Squeeze: 103 | Enabled: true 104 | Performance/StringInclude: 105 | Enabled: true 106 | Performance/Sum: 107 | Enabled: true 108 | Style/CollectionMethods: 109 | Enabled: true 110 | Style/MethodCalledOnDoEndBlock: 111 | Enabled: true 112 | Style/StringMethods: 113 | Enabled: true 114 | Bundler/GemFilename: 115 | Enabled: false 116 | Bundler/InsecureProtocolSource: 117 | Enabled: false 118 | Capybara/CurrentPathExpectation: 119 | Enabled: false 120 | Capybara/VisibilityMatcher: 121 | Enabled: false 122 | Gemspec/DuplicatedAssignment: 123 | Enabled: false 124 | Gemspec/OrderedDependencies: 125 | Enabled: false 126 | Gemspec/RequiredRubyVersion: 127 | Enabled: false 128 | Gemspec/RubyVersionGlobalsUsage: 129 | Enabled: false 130 | Layout/ArgumentAlignment: 131 | Enabled: false 132 | Layout/BeginEndAlignment: 133 | Enabled: false 134 | Layout/ClosingHeredocIndentation: 135 | Enabled: false 136 | Layout/EmptyComment: 137 | Enabled: false 138 | Layout/EmptyLineAfterGuardClause: 139 | Enabled: false 140 | Layout/EmptyLinesAroundArguments: 141 | Enabled: false 142 | Layout/EmptyLinesAroundAttributeAccessor: 143 | Enabled: false 144 | Layout/EndOfLine: 145 | Enabled: false 146 | Layout/FirstArgumentIndentation: 147 | Enabled: false 148 | Layout/HashAlignment: 149 | Enabled: false 150 | Layout/HeredocIndentation: 151 | Enabled: false 152 | Layout/LeadingEmptyLines: 153 | Enabled: false 154 | Layout/SpaceAroundMethodCallOperator: 155 | Enabled: false 156 | Layout/SpaceInsideArrayLiteralBrackets: 157 | Enabled: false 158 | Layout/SpaceInsideReferenceBrackets: 159 | Enabled: false 160 | Lint/BigDecimalNew: 161 | Enabled: false 162 | Lint/BooleanSymbol: 163 | Enabled: false 164 | Lint/ConstantDefinitionInBlock: 165 | Enabled: false 166 | Lint/DeprecatedOpenSSLConstant: 167 | Enabled: false 168 | Lint/DisjunctiveAssignmentInConstructor: 169 | Enabled: false 170 | Lint/DuplicateElsifCondition: 171 | Enabled: false 172 | Lint/DuplicateRequire: 173 | Enabled: false 174 | Lint/DuplicateRescueException: 175 | Enabled: false 176 | Lint/EmptyConditionalBody: 177 | Enabled: false 178 | Lint/EmptyFile: 179 | Enabled: false 180 | Lint/ErbNewArguments: 181 | Enabled: false 182 | Lint/FloatComparison: 183 | Enabled: false 184 | Lint/HashCompareByIdentity: 185 | Enabled: false 186 | Lint/IdentityComparison: 187 | Enabled: false 188 | Lint/InterpolationCheck: 189 | Enabled: false 190 | Lint/MissingCopEnableDirective: 191 | Enabled: false 192 | Lint/MixedRegexpCaptureTypes: 193 | Enabled: false 194 | Lint/NestedPercentLiteral: 195 | Enabled: false 196 | Lint/NonDeterministicRequireOrder: 197 | Enabled: false 198 | Lint/OrderedMagicComments: 199 | Enabled: false 200 | Lint/OutOfRangeRegexpRef: 201 | Enabled: false 202 | Lint/RaiseException: 203 | Enabled: false 204 | Lint/RedundantCopEnableDirective: 205 | Enabled: false 206 | Lint/RedundantRequireStatement: 207 | Enabled: false 208 | Lint/RedundantSafeNavigation: 209 | Enabled: false 210 | Lint/RedundantWithIndex: 211 | Enabled: false 212 | Lint/RedundantWithObject: 213 | Enabled: false 214 | Lint/RegexpAsCondition: 215 | Enabled: false 216 | Lint/ReturnInVoidContext: 217 | Enabled: false 218 | Lint/SafeNavigationConsistency: 219 | Enabled: false 220 | Lint/SafeNavigationWithEmpty: 221 | Enabled: false 222 | Lint/SelfAssignment: 223 | Enabled: false 224 | Lint/SendWithMixinArgument: 225 | Enabled: false 226 | Lint/ShadowedArgument: 227 | Enabled: false 228 | Lint/StructNewOverride: 229 | Enabled: false 230 | Lint/ToJSON: 231 | Enabled: false 232 | Lint/TopLevelReturnWithArgument: 233 | Enabled: false 234 | Lint/TrailingCommaInAttributeDeclaration: 235 | Enabled: false 236 | Lint/UnreachableLoop: 237 | Enabled: false 238 | Lint/UriEscapeUnescape: 239 | Enabled: false 240 | Lint/UriRegexp: 241 | Enabled: false 242 | Lint/UselessMethodDefinition: 243 | Enabled: false 244 | Lint/UselessTimes: 245 | Enabled: false 246 | Metrics/AbcSize: 247 | Enabled: false 248 | Metrics/BlockLength: 249 | Enabled: false 250 | Metrics/BlockNesting: 251 | Enabled: false 252 | Metrics/ClassLength: 253 | Enabled: false 254 | Metrics/CyclomaticComplexity: 255 | Enabled: false 256 | Metrics/MethodLength: 257 | Enabled: false 258 | Metrics/ModuleLength: 259 | Enabled: false 260 | Metrics/ParameterLists: 261 | Enabled: false 262 | Metrics/PerceivedComplexity: 263 | Enabled: false 264 | Migration/DepartmentName: 265 | Enabled: false 266 | Naming/AccessorMethodName: 267 | Enabled: false 268 | Naming/BlockParameterName: 269 | Enabled: false 270 | Naming/HeredocDelimiterCase: 271 | Enabled: false 272 | Naming/HeredocDelimiterNaming: 273 | Enabled: false 274 | Naming/MemoizedInstanceVariableName: 275 | Enabled: false 276 | Naming/MethodParameterName: 277 | Enabled: false 278 | Naming/RescuedExceptionsVariableName: 279 | Enabled: false 280 | Naming/VariableNumber: 281 | Enabled: false 282 | Performance/BindCall: 283 | Enabled: false 284 | Performance/DeletePrefix: 285 | Enabled: false 286 | Performance/DeleteSuffix: 287 | Enabled: false 288 | Performance/InefficientHashSearch: 289 | Enabled: false 290 | Performance/UnfreezeString: 291 | Enabled: false 292 | Performance/UriDefaultParser: 293 | Enabled: false 294 | RSpec/Be: 295 | Enabled: false 296 | RSpec/Capybara/FeatureMethods: 297 | Enabled: false 298 | RSpec/ContainExactly: 299 | Enabled: false 300 | RSpec/ContextMethod: 301 | Enabled: false 302 | RSpec/ContextWording: 303 | Enabled: false 304 | RSpec/DescribeClass: 305 | Enabled: false 306 | RSpec/EmptyHook: 307 | Enabled: false 308 | RSpec/EmptyLineAfterExample: 309 | Enabled: false 310 | RSpec/EmptyLineAfterExampleGroup: 311 | Enabled: false 312 | RSpec/EmptyLineAfterHook: 313 | Enabled: false 314 | RSpec/ExampleLength: 315 | Enabled: false 316 | RSpec/ExampleWithoutDescription: 317 | Enabled: false 318 | RSpec/ExpectChange: 319 | Enabled: false 320 | RSpec/ExpectInHook: 321 | Enabled: false 322 | RSpec/FactoryBot/AttributeDefinedStatically: 323 | Enabled: false 324 | RSpec/FactoryBot/CreateList: 325 | Enabled: false 326 | RSpec/FactoryBot/FactoryClassName: 327 | Enabled: false 328 | RSpec/HooksBeforeExamples: 329 | Enabled: false 330 | RSpec/ImplicitBlockExpectation: 331 | Enabled: false 332 | RSpec/ImplicitSubject: 333 | Enabled: false 334 | RSpec/LeakyConstantDeclaration: 335 | Enabled: false 336 | RSpec/LetBeforeExamples: 337 | Enabled: false 338 | RSpec/MatchArray: 339 | Enabled: false 340 | RSpec/MissingExampleGroupArgument: 341 | Enabled: false 342 | RSpec/MultipleExpectations: 343 | Enabled: false 344 | RSpec/MultipleMemoizedHelpers: 345 | Enabled: false 346 | RSpec/MultipleSubjects: 347 | Enabled: false 348 | RSpec/NestedGroups: 349 | Enabled: false 350 | RSpec/PredicateMatcher: 351 | Enabled: false 352 | RSpec/ReceiveCounts: 353 | Enabled: false 354 | RSpec/ReceiveNever: 355 | Enabled: false 356 | RSpec/RepeatedExampleGroupBody: 357 | Enabled: false 358 | RSpec/RepeatedExampleGroupDescription: 359 | Enabled: false 360 | RSpec/RepeatedIncludeExample: 361 | Enabled: false 362 | RSpec/ReturnFromStub: 363 | Enabled: false 364 | RSpec/SharedExamples: 365 | Enabled: false 366 | RSpec/StubbedMock: 367 | Enabled: false 368 | RSpec/UnspecifiedException: 369 | Enabled: false 370 | RSpec/VariableDefinition: 371 | Enabled: false 372 | RSpec/VoidExpect: 373 | Enabled: false 374 | RSpec/Yield: 375 | Enabled: false 376 | Security/Open: 377 | Enabled: false 378 | Style/AccessModifierDeclarations: 379 | Enabled: false 380 | Style/AccessorGrouping: 381 | Enabled: false 382 | Style/BisectedAttrAccessor: 383 | Enabled: false 384 | Style/CaseLikeIf: 385 | Enabled: false 386 | Style/ClassEqualityComparison: 387 | Enabled: false 388 | Style/ColonMethodDefinition: 389 | Enabled: false 390 | Style/CombinableLoops: 391 | Enabled: false 392 | Style/CommentedKeyword: 393 | Enabled: false 394 | Style/Dir: 395 | Enabled: false 396 | Style/DoubleCopDisableDirective: 397 | Enabled: false 398 | Style/EmptyBlockParameter: 399 | Enabled: false 400 | Style/EmptyLambdaParameter: 401 | Enabled: false 402 | Style/Encoding: 403 | Enabled: false 404 | Style/EvalWithLocation: 405 | Enabled: false 406 | Style/ExpandPathArguments: 407 | Enabled: false 408 | Style/ExplicitBlockArgument: 409 | Enabled: false 410 | Style/ExponentialNotation: 411 | Enabled: false 412 | Style/FloatDivision: 413 | Enabled: false 414 | Style/FrozenStringLiteralComment: 415 | Enabled: false 416 | Style/GlobalStdStream: 417 | Enabled: false 418 | Style/HashAsLastArrayItem: 419 | Enabled: false 420 | Style/HashLikeCase: 421 | Enabled: false 422 | Style/HashTransformKeys: 423 | Enabled: false 424 | Style/HashTransformValues: 425 | Enabled: false 426 | Style/IfUnlessModifier: 427 | Enabled: false 428 | Style/KeywordParametersOrder: 429 | Enabled: false 430 | Style/MinMax: 431 | Enabled: false 432 | Style/MixinUsage: 433 | Enabled: false 434 | Style/MultilineWhenThen: 435 | Enabled: false 436 | Style/NegatedUnless: 437 | Enabled: false 438 | Style/NumericPredicate: 439 | Enabled: false 440 | Style/OptionalBooleanParameter: 441 | Enabled: false 442 | Style/OrAssignment: 443 | Enabled: false 444 | Style/RandomWithOffset: 445 | Enabled: false 446 | Style/RedundantAssignment: 447 | Enabled: false 448 | Style/RedundantCondition: 449 | Enabled: false 450 | Style/RedundantConditional: 451 | Enabled: false 452 | Style/RedundantFetchBlock: 453 | Enabled: false 454 | Style/RedundantFileExtensionInRequire: 455 | Enabled: false 456 | Style/RedundantRegexpCharacterClass: 457 | Enabled: false 458 | Style/RedundantRegexpEscape: 459 | Enabled: false 460 | Style/RedundantSelfAssignment: 461 | Enabled: false 462 | Style/RedundantSort: 463 | Enabled: false 464 | Style/RescueStandardError: 465 | Enabled: false 466 | Style/SingleArgumentDig: 467 | Enabled: false 468 | Style/SlicingWithRange: 469 | Enabled: false 470 | Style/SoleNestedConditional: 471 | Enabled: false 472 | Style/StderrPuts: 473 | Enabled: false 474 | Style/StringConcatenation: 475 | Enabled: false 476 | Style/Strip: 477 | Enabled: false 478 | Style/SymbolProc: 479 | Enabled: false 480 | Style/TrailingBodyOnClass: 481 | Enabled: false 482 | Style/TrailingBodyOnMethodDefinition: 483 | Enabled: false 484 | Style/TrailingBodyOnModule: 485 | Enabled: false 486 | Style/TrailingCommaInHashLiteral: 487 | Enabled: false 488 | Style/TrailingMethodEndStatement: 489 | Enabled: false 490 | Style/UnpackFirst: 491 | Enabled: false 492 | Capybara/MatchStyle: 493 | Enabled: false 494 | Capybara/NegationMatcher: 495 | Enabled: false 496 | Capybara/SpecificActions: 497 | Enabled: false 498 | Capybara/SpecificFinders: 499 | Enabled: false 500 | Capybara/SpecificMatcher: 501 | Enabled: false 502 | Gemspec/DeprecatedAttributeAssignment: 503 | Enabled: false 504 | Gemspec/DevelopmentDependencies: 505 | Enabled: false 506 | Gemspec/RequireMFA: 507 | Enabled: false 508 | Layout/LineContinuationLeadingSpace: 509 | Enabled: false 510 | Layout/LineContinuationSpacing: 511 | Enabled: false 512 | Layout/LineEndStringConcatenationIndentation: 513 | Enabled: false 514 | Layout/SpaceBeforeBrackets: 515 | Enabled: false 516 | Lint/AmbiguousAssignment: 517 | Enabled: false 518 | Lint/AmbiguousOperatorPrecedence: 519 | Enabled: false 520 | Lint/AmbiguousRange: 521 | Enabled: false 522 | Lint/ConstantOverwrittenInRescue: 523 | Enabled: false 524 | Lint/DeprecatedConstants: 525 | Enabled: false 526 | Lint/DuplicateBranch: 527 | Enabled: false 528 | Lint/DuplicateMagicComment: 529 | Enabled: false 530 | Lint/DuplicateRegexpCharacterClassElement: 531 | Enabled: false 532 | Lint/EmptyBlock: 533 | Enabled: false 534 | Lint/EmptyClass: 535 | Enabled: false 536 | Lint/EmptyInPattern: 537 | Enabled: false 538 | Lint/IncompatibleIoSelectWithFiberScheduler: 539 | Enabled: false 540 | Lint/LambdaWithoutLiteralBlock: 541 | Enabled: false 542 | Lint/NoReturnInBeginEndBlocks: 543 | Enabled: false 544 | Lint/NonAtomicFileOperation: 545 | Enabled: false 546 | Lint/NumberedParameterAssignment: 547 | Enabled: false 548 | Lint/OrAssignmentToConstant: 549 | Enabled: false 550 | Lint/RedundantDirGlobSort: 551 | Enabled: false 552 | Lint/RefinementImportMethods: 553 | Enabled: false 554 | Lint/RequireRangeParentheses: 555 | Enabled: false 556 | Lint/RequireRelativeSelfPath: 557 | Enabled: false 558 | Lint/SymbolConversion: 559 | Enabled: false 560 | Lint/ToEnumArguments: 561 | Enabled: false 562 | Lint/TripleQuotes: 563 | Enabled: false 564 | Lint/UnexpectedBlockArity: 565 | Enabled: false 566 | Lint/UnmodifiedReduceAccumulator: 567 | Enabled: false 568 | Lint/UselessRescue: 569 | Enabled: false 570 | Lint/UselessRuby2Keywords: 571 | Enabled: false 572 | Metrics/CollectionLiteralLength: 573 | Enabled: false 574 | Naming/BlockForwarding: 575 | Enabled: false 576 | Performance/CollectionLiteralInLoop: 577 | Enabled: false 578 | Performance/ConcurrentMonotonicTime: 579 | Enabled: false 580 | Performance/MapCompact: 581 | Enabled: false 582 | Performance/RedundantEqualityComparisonBlock: 583 | Enabled: false 584 | Performance/RedundantSplitRegexpArgument: 585 | Enabled: false 586 | Performance/StringIdentifierArgument: 587 | Enabled: false 588 | RSpec/BeEq: 589 | Enabled: false 590 | RSpec/BeNil: 591 | Enabled: false 592 | RSpec/ChangeByZero: 593 | Enabled: false 594 | RSpec/ClassCheck: 595 | Enabled: false 596 | RSpec/DuplicatedMetadata: 597 | Enabled: false 598 | RSpec/ExcessiveDocstringSpacing: 599 | Enabled: false 600 | RSpec/FactoryBot/ConsistentParenthesesStyle: 601 | Enabled: false 602 | RSpec/FactoryBot/FactoryNameStyle: 603 | Enabled: false 604 | RSpec/FactoryBot/SyntaxMethods: 605 | Enabled: false 606 | RSpec/IdenticalEqualityAssertion: 607 | Enabled: false 608 | RSpec/NoExpectationExample: 609 | Enabled: false 610 | RSpec/PendingWithoutReason: 611 | Enabled: false 612 | RSpec/Rails/AvoidSetupHook: 613 | Enabled: false 614 | RSpec/Rails/HaveHttpStatus: 615 | Enabled: false 616 | RSpec/Rails/InferredSpecType: 617 | Enabled: false 618 | RSpec/Rails/MinitestAssertions: 619 | Enabled: false 620 | RSpec/Rails/TravelAround: 621 | Enabled: false 622 | RSpec/RedundantAround: 623 | Enabled: false 624 | RSpec/SkipBlockInsideExample: 625 | Enabled: false 626 | RSpec/SortMetadata: 627 | Enabled: false 628 | RSpec/SubjectDeclaration: 629 | Enabled: false 630 | RSpec/VerifiedDoubleReference: 631 | Enabled: false 632 | Security/CompoundHash: 633 | Enabled: false 634 | Security/IoMethods: 635 | Enabled: false 636 | Style/ArgumentsForwarding: 637 | Enabled: false 638 | Style/ArrayIntersect: 639 | Enabled: false 640 | Style/CollectionCompact: 641 | Enabled: false 642 | Style/ComparableClamp: 643 | Enabled: false 644 | Style/ConcatArrayLiterals: 645 | Enabled: false 646 | Style/DirEmpty: 647 | Enabled: false 648 | Style/DocumentDynamicEvalDefinition: 649 | Enabled: false 650 | Style/EmptyHeredoc: 651 | Enabled: false 652 | Style/EndlessMethod: 653 | Enabled: false 654 | Style/EnvHome: 655 | Enabled: false 656 | Style/FetchEnvVar: 657 | Enabled: false 658 | Style/FileEmpty: 659 | Enabled: false 660 | Style/FileRead: 661 | Enabled: false 662 | Style/FileWrite: 663 | Enabled: false 664 | Style/HashConversion: 665 | Enabled: false 666 | Style/HashExcept: 667 | Enabled: false 668 | Style/IfWithBooleanLiteralBranches: 669 | Enabled: false 670 | Style/InPatternThen: 671 | Enabled: false 672 | Style/MagicCommentFormat: 673 | Enabled: false 674 | Style/MapCompactWithConditionalBlock: 675 | Enabled: false 676 | Style/MapToHash: 677 | Enabled: false 678 | Style/MapToSet: 679 | Enabled: false 680 | Style/MinMaxComparison: 681 | Enabled: false 682 | Style/MultilineInPatternThen: 683 | Enabled: false 684 | Style/NegatedIfElseCondition: 685 | Enabled: false 686 | Style/NestedFileDirname: 687 | Enabled: false 688 | Style/NilLambda: 689 | Enabled: false 690 | Style/NumberedParameters: 691 | Enabled: false 692 | Style/NumberedParametersLimit: 693 | Enabled: false 694 | Style/ObjectThen: 695 | Enabled: false 696 | Style/OpenStructUse: 697 | Enabled: false 698 | Style/OperatorMethodCall: 699 | Enabled: false 700 | Style/QuotedSymbols: 701 | Enabled: false 702 | Style/RedundantArgument: 703 | Enabled: false 704 | Style/RedundantConstantBase: 705 | Enabled: false 706 | Style/RedundantDoubleSplatHashBraces: 707 | Enabled: false 708 | Style/RedundantEach: 709 | Enabled: false 710 | Style/RedundantHeredocDelimiterQuotes: 711 | Enabled: false 712 | Style/RedundantInitialize: 713 | Enabled: false 714 | Style/RedundantSelfAssignmentBranch: 715 | Enabled: false 716 | Style/RedundantStringEscape: 717 | Enabled: false 718 | Style/SelectByRegexp: 719 | Enabled: false 720 | Style/StringChars: 721 | Enabled: false 722 | Style/SwapValues: 723 | Enabled: false 724 | -------------------------------------------------------------------------------- /.sync.yml: -------------------------------------------------------------------------------- 1 | --- 2 | appveyor.yml: 3 | delete: true 4 | 5 | .github/workflows/release_prep.yml: 6 | unmanaged: false 7 | .github/workflows/release.yml: 8 | unmanaged: false 9 | 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | os: linux 3 | dist: xenial 4 | language: ruby 5 | cache: bundler 6 | before_install: 7 | - bundle -v 8 | - rm -f Gemfile.lock 9 | - "# Update system gems if requested. This is useful to temporarily workaround troubles in the test runner" 10 | - "# See https://github.com/puppetlabs/pdk-templates/commit/705154d5c437796b821691b707156e1b056d244f for an example of how this was used" 11 | - "# Ignore exit code of SIGPIPE'd yes to not fail with shell's pipefail set" 12 | - '[ -z "$RUBYGEMS_VERSION" ] || (yes || true) | gem update --system $RUBYGEMS_VERSION' 13 | - gem --version 14 | - bundle -v 15 | script: 16 | - 'bundle exec rake $CHECK' 17 | bundler_args: --without system_tests 18 | rvm: 19 | - 2.5.7 20 | stages: 21 | - static 22 | - spec 23 | - acceptance 24 | - 25 | if: tag =~ ^v\d 26 | name: deploy 27 | jobs: 28 | fast_finish: true 29 | include: 30 | - 31 | env: CHECK="check:symlinks check:git_ignore check:dot_underscore check:test_file rubocop syntax lint metadata_lint" 32 | stage: static 33 | - 34 | env: PUPPET_GEM_VERSION="~> 5.0" CHECK=parallel_spec 35 | rvm: 2.4.5 36 | stage: spec 37 | - 38 | env: PUPPET_GEM_VERSION="~> 6.0" CHECK=parallel_spec 39 | rvm: 2.5.7 40 | stage: spec 41 | - 42 | env: DEPLOY_TO_FORGE=yes 43 | stage: deploy 44 | branches: 45 | only: 46 | - main 47 | - /^v\d/ 48 | notifications: 49 | email: false 50 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "puppet.puppet-vscode", 4 | "rebornix.Ruby" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /.yardopts: -------------------------------------------------------------------------------- 1 | --markup markdown 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## Unsupported Release 1.2.0 2 | ### Summary 3 | 4 | This minor release is a roll up of bug fixes and features 5 | 6 | #### Added 7 | - Add support for CentOS8 8 | - `pid_file` parameter to customize the pid file setting 9 | 10 | #### Fixed 11 | - rsync-daemon package is now automatically installed in CentOS8 when xinetd is disabled. 12 | 13 | ## Unsupported Release 1.1.1 14 | ### Summary 15 | 16 | This minor release is to roll out a bug fix. 17 | 18 | #### Fixed 19 | 20 | - Duplicate line removed from template. 21 | - Small documentation fix. 22 | 23 | ## Unsupported Release 1.1.0 24 | ### Summary 25 | 26 | This minor release is a roll up of bug fixes and features. 27 | 28 | #### Added 29 | - migrate to `rspec-puppet-facts`. 30 | - Add support for module `log file`. 31 | - Added module options that are currently missing. 32 | 33 | #### Fixed 34 | - Change redirects during fixtures download. 35 | - Add upper version boundary for `xinted` dependency. 36 | - Replace legacy facts with new $facts hash. 37 | 38 | ## Unsupported Release 1.0.0 39 | ### Summary 40 | This is a major release that drops Puppet 3 support. 41 | 42 | #### Added 43 | - `transfer_logging` and `log_format` parameters 44 | - Now optional management of rsync install with new `manage_package` parameter 45 | - Support for configuration via Hiera 46 | - FreeBSD, RedHat family compatibility 47 | - Make rsync::get compatible with `strict_variables` ([MODULES-3515](https://tickets.puppet.com/browse/MODULES-3515)) 48 | - `ignore_nonreadable` parameter 49 | - Support for changing exclude/include order 50 | - `chmod` and `logfile` parameters 51 | - `.sync.yml` added for modulesync compatibility 52 | 53 | #### Changed 54 | - Bumps puppetlabs-stdlib dependency up to 4.2.0 55 | 56 | #### Fixed 57 | - Replace .to_a with Kernel#Array ([MODULES-1858](https://tickets.puppet.com/browse/MODULES-1858)) 58 | 59 | 60 | ## 2015-01-20 - Release 0.4.0 61 | ### Summary 62 | 63 | This release includes several new parameters and improvements. 64 | 65 | #### Features 66 | - Update `$include` and `$exclude` to support arrays 67 | - Updated to use puppetlabs/concat instead of execs to build file! 68 | - New parameters 69 | - rsync::get 70 | - `$options` 71 | - `$onlyif` 72 | - rsync::put 73 | - `$include` 74 | - `$options` 75 | - rsync::server::module 76 | - `$order` 77 | - `$refuse_options` 78 | 79 | #### Bugfixes 80 | - Fix auto-chmod of incoming and outgoing files when `incoming_chmod` or `outgoing_chmod` is set to false 81 | 82 | ## 2014-07-15 - Release 0.3.1 83 | ### Summary 84 | 85 | This release merely updates metadata.json so the module can be uninstalled and 86 | upgraded via the puppet module command. 87 | 88 | ## 2014-06-18 - Release 0.3.0 89 | #### Features 90 | - Added rsync::put defined type. 91 | - Added `recursive`, `links`, `hardlinks`, `copylinks`, `times` and `include` 92 | parameters to rsync::get. 93 | - Added `uid` and `gid` parameters to rsync::server 94 | - Improved support for Debian 95 | - Added `exclude` parameter to rsync::server::module 96 | 97 | #### Bugfixes 98 | - Added /usr/local/bin to path for the rsync command exec. 99 | 100 | 101 | ## 2013-01-31 - Release 0.2.0 102 | - Added use_chroot parameter. 103 | - Ensure rsync package is installed. 104 | - Compatibility changes for Ruby 2.0. 105 | - Added execuser parameter to run command as specified user. 106 | - Various typo and bug fixes. 107 | 108 | ## 2012-06-07 - Release 0.1.0 109 | - Initial release 110 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @puppetlabs/open-source-stewards @kajinamit 2 | 3 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source ENV['GEM_SOURCE'] || 'https://rubygems.org' 2 | 3 | def location_for(place_or_version, fake_version = nil) 4 | git_url_regex = %r{\A(?(https?|git)[:@][^#]*)(#(?.*))?} 5 | file_url_regex = %r{\Afile:\/\/(?.*)} 6 | 7 | if place_or_version && (git_url = place_or_version.match(git_url_regex)) 8 | [fake_version, { git: git_url[:url], branch: git_url[:branch], require: false }].compact 9 | elsif place_or_version && (file_url = place_or_version.match(file_url_regex)) 10 | ['>= 0', { path: File.expand_path(file_url[:path]), require: false }] 11 | else 12 | [place_or_version, { require: false }] 13 | end 14 | end 15 | 16 | group :development do 17 | 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)) 18 | 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)) 19 | 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)) 20 | 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)) 21 | 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)) 22 | 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)) 23 | gem "voxpupuli-puppet-lint-plugins", '~> 5.0', require: false 24 | gem "facterdb", '~> 1.18', require: false 25 | gem "metadata-json-lint", '~> 3.0', require: false 26 | gem "puppetlabs_spec_helper", '~> 6.0', require: false 27 | gem "rspec-puppet-facts", '~> 2.0', require: false 28 | gem "codecov", '~> 0.2', require: false 29 | gem "dependency_checker", '~> 1.0.0', require: false 30 | gem "parallel_tests", '= 3.12.1', require: false 31 | gem "pry", '~> 0.10', require: false 32 | gem "simplecov-console", '~> 0.5', require: false 33 | gem "puppet-debugger", '~> 1.0', require: false 34 | gem "rubocop", '= 1.48.1', require: false 35 | gem "rubocop-performance", '= 1.16.0', require: false 36 | gem "rubocop-rspec", '= 2.19.0', require: false 37 | gem "puppet-strings", '~> 4.0', require: false 38 | gem "rb-readline", '= 0.5.5', require: false, platforms: [:mswin, :mingw, :x64_mingw] 39 | end 40 | group :system_tests do 41 | gem "puppet_litmus", '~> 1.0', require: false, platforms: [:ruby, :x64_mingw] 42 | gem "serverspec", '~> 2.41', require: false 43 | end 44 | group :release_prep do 45 | gem "puppet-strings", '~> 4.0', require: false 46 | gem "puppetlabs_spec_helper", '~> 6.0', require: false 47 | end 48 | 49 | puppet_version = ENV['PUPPET_GEM_VERSION'] 50 | facter_version = ENV['FACTER_GEM_VERSION'] 51 | hiera_version = ENV['HIERA_GEM_VERSION'] 52 | 53 | gems = {} 54 | 55 | gems['puppet'] = location_for(puppet_version) 56 | 57 | # If facter or hiera versions have been specified via the environment 58 | # variables 59 | 60 | gems['facter'] = location_for(facter_version) if facter_version 61 | gems['hiera'] = location_for(hiera_version) if hiera_version 62 | 63 | gems.each do |gem_name, gem_params| 64 | gem gem_name, *gem_params 65 | end 66 | 67 | # Evaluate Gemfile.local and ~/.gemfile if they exist 68 | extra_gemfiles = [ 69 | "#{__FILE__}.local", 70 | File.join(Dir.home, '.gemfile'), 71 | ] 72 | 73 | extra_gemfiles.each do |gemfile| 74 | if File.file?(gemfile) && File.readable?(gemfile) 75 | eval(File.read(gemfile), binding) 76 | end 77 | end 78 | # vim: syntax=ruby 79 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Puppet Module - puppetlabs-rsync 2 | 3 | Copyright 2017 Puppet, Inc. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # puppetlabs-rsync # 2 | 3 | > [!NOTE] 4 | > This module is supported by the Puppet community. We expect it to be of the same high 5 | > quality as our own Supported modules, but it does not qualify for Puppet Support plans. 6 | > See the `CODEOWNERS` file for usernames of the maintainers. 7 | 8 | #### Table of Contents 9 | 10 | 1. [Module Description - What does the module do?](#module-description) 11 | 3. [Usage - Configuration options and additional functionality](#usage) 12 | 4. [Reference - An under-the-hood peek at what the module is doing and how](#reference) 13 | * [Classes](#classes) 14 | * [Defined Types](#defined-types) 15 | 5. [Limitations - OS compatibility, etc.](#limitations) 16 | 17 | ## Module description 18 | 19 | puppetlabs-rsync manages rsync clients, repositories, and servers as well as 20 | providing defines to easily grab data via rsync. 21 | 22 | ## Usage 23 | 24 | Install the latest version of rsync 25 | ~~~puppet 26 | class { 'rsync': 27 | package_ensure => 'latest' 28 | } 29 | ~~~ 30 | 31 | Get file 'foo' via rsync 32 | ~~~puppet 33 | rsync::get { '/foo': 34 | source => "rsync://${rsyncServer}/repo/foo/", 35 | require => File['/foo'], 36 | } 37 | ~~~ 38 | 39 | Put file 'foo' on 'rsyncDestHost' 40 | ~~~puppet 41 | rsync::put { '${rsyncDestHost}:/repo/foo': 42 | user => 'user', 43 | source => "/repo/foo/", 44 | } 45 | ~~~ 46 | 47 | Setup default rsync repository 48 | ~~~puppet 49 | rsync::server::module{ 'repo': 50 | path => $base, 51 | require => File[$base], 52 | } 53 | ~~~ 54 | 55 | To disable default values for `incoming_chmod` and `outgoing_chmod`, and 56 | do not add empty values to the resulting config, set both values to `false` 57 | 58 | ~~~puppet 59 | rsync::server::module { 'repo': 60 | path => $base, 61 | incoming_chmod => false, 62 | outgoing_chmod => false, 63 | require => File[$base], 64 | } 65 | ~~~ 66 | 67 | #### Configuring via Hiera 68 | `rsync::put`, `rsync::get`, and `rsync::server::module` resources can be 69 | configured using Hiera hashes. For example: 70 | 71 | ~~~yaml 72 | rsync::server::modules: 73 | myrepo: 74 | path: /mypath 75 | incoming_chmod: false 76 | outgoing_chmod: false 77 | myotherrepo: 78 | path: /otherpath 79 | read_only: false 80 | ~~~ 81 | 82 | ## Reference 83 | 84 | **Classes:** 85 | * [rsync](#rsync) 86 | 87 | **Defined Types:** 88 | * [rsync::get](#rsyncget) 89 | * [rsync::put](#rsyncput) 90 | * [rsync::server::module](#rsyncservermodule) 91 | 92 | 93 | ### Classes 94 | 95 | #### rsync 96 | 97 | Manage the rsync package. 98 | 99 | ##### `package_ensure` 100 | 101 | Ensure the for the rsync package. Any of the valid values for the package resource (present, absent, purged, held, latest) are acceptable. 102 | 103 | Default value: 'installed' 104 | 105 | ##### `manage_package` 106 | 107 | Setting this to false stops the rsync package resource from being managed. 108 | 109 | Default value: `true` 110 | 111 | ### Defined Types 112 | 113 | #### rsync::get 114 | 115 | get files via rsync 116 | 117 | ##### `source` 118 | **Required** 119 | 120 | Source to copy from. 121 | 122 | ##### `path` 123 | 124 | Path to copy to. 125 | 126 | Default value: `$name` 127 | 128 | ##### `user` 129 | 130 | Username on remote system 131 | 132 | ##### `purge` 133 | 134 | If set, rsync will use '--delete' 135 | 136 | ##### `recursive` 137 | 138 | If set, rsync will use '-r' 139 | 140 | ##### `links` 141 | 142 | If set, rsync will use '--links' 143 | 144 | ##### `hardlinks` 145 | 146 | If set, rsync will use '--hard-links' 147 | 148 | ##### `copylinks` 149 | 150 | If set, rsync will use '--copy-links' 151 | 152 | ##### `times` 153 | 154 | If set, rsync will use '--times' 155 | 156 | ##### `exclude` 157 | 158 | String (or array of strings) paths for files to be excluded. 159 | 160 | ##### `include` 161 | 162 | String (or array of strings) paths for files to be explicitly included. 163 | 164 | ##### `exclude_first` 165 | 166 | If `true`, exclude first and then include; the other way around if `false`. 167 | 168 | Default value: `true` 169 | 170 | ##### `keyfile` 171 | 172 | SSH key used to connect to remote host. 173 | 174 | ##### `timeout` 175 | 176 | Timeout in seconds. 177 | 178 | Default value: 900 179 | 180 | ##### `execuser` 181 | 182 | User to run the command (passed to exec). 183 | 184 | ##### `options` 185 | 186 | Default options to pass to rsync (-a). 187 | 188 | ##### `chown` 189 | 190 | USER:GROUP simple username/groupname mapping. 191 | 192 | ##### `chmod` 193 | 194 | File and/or directory permissions. 195 | 196 | ##### `logfile` 197 | 198 | Log file name. 199 | 200 | ##### `onlyif` 201 | 202 | Condition to run the rsync command. 203 | 204 | #### rsync::put 205 | 206 | put files via rsync 207 | 208 | ##### `source` 209 | **Required** 210 | 211 | Source to copy from. 212 | 213 | ##### `path` 214 | 215 | Path to copy to. 216 | 217 | Default value: `$name` 218 | 219 | ##### `user` 220 | 221 | Username on target remote system. 222 | 223 | ##### `purge` 224 | 225 | If set, rsync will use '--delete' 226 | 227 | ##### `exclude` 228 | 229 | String (or array of strings) paths for files to be excluded. 230 | 231 | ##### `include` 232 | 233 | String (or array of strings) paths for files to be explicitly included. 234 | 235 | ##### `exclude_first` 236 | 237 | If `true`, exclude first and then include; the other way around if `false`. 238 | 239 | Default value: `true` 240 | 241 | ##### `keyfile` 242 | 243 | Path to SSH key used to connect to remote host. 244 | 245 | Default value: '/home/${user}/.ssh/id_rsa' 246 | 247 | ##### `timeout` 248 | 249 | Timeout in seconds. 250 | 251 | Default value: 900 252 | 253 | ##### `options` 254 | 255 | Default options to pass to rsync (-a) 256 | 257 | #### rsync::server::module 258 | 259 | Sets up a rsync server 260 | 261 | ##### `path` 262 | _Required_ 263 | 264 | Path to data. 265 | 266 | ##### `comment` 267 | 268 | Rsync comment. 269 | 270 | ##### `motd` 271 | 272 | File containing motd info. 273 | 274 | ##### `pid_file` 275 | 276 | PID file. Defaults to /var/run/rsyncd.pid. The pid file parameter won't be applied if set to "UNSET"; rsyncd will not use a PID file in this case. 277 | 278 | ##### `read_only` 279 | 280 | yes||no 281 | 282 | Default value: 'yes' 283 | 284 | ##### `write_only` 285 | 286 | yes||no 287 | 288 | Default value: 'no' 289 | 290 | ##### `list` 291 | 292 | yes||no 293 | 294 | Default value: 'no' 295 | 296 | ##### `uid` 297 | 298 | uid of rsync server 299 | 300 | Default value: 0 301 | 302 | ##### `gid` 303 | 304 | gid of rsync server 305 | 306 | Default value: 0 307 | 308 | ##### `incoming_chmod` 309 | 310 | Incoming file mode 311 | 312 | Default value: '644' 313 | 314 | ##### `outgoing_chmod` 315 | 316 | Outgoing file mode 317 | 318 | Default value: '644' 319 | 320 | ##### `max_connections` 321 | 322 | Maximum number of simultaneous connections allowed 323 | 324 | Default value: 0 325 | 326 | ##### `lock_file` 327 | 328 | File used to support the max connections parameter. Only needed if max_connections > 0. 329 | 330 | Default value: '/var/run/rsyncd.lock' 331 | 332 | ##### `secrets_file` 333 | 334 | Path to the file that contains the username:password pairs used for authenticating this module. 335 | 336 | ##### `auth_users` 337 | 338 | List of usernames that will be allowed to connect to this module (must be undef or an array). 339 | 340 | ##### `hosts_allow` 341 | 342 | List of patterns allowed to connect to this module ([rsyncd.conf man page] for details, must be undef or an array). 343 | 344 | ##### `hosts_deny` 345 | 346 | List of patterns allowed to connect to this module ([rsyncd.conf man page] for details, must be undef or an array). 347 | 348 | ##### `transfer_logging` 349 | 350 | Parameter enables per-file logging of downloads and uploads in a format somewhat similar to that used by ftp daemons. 351 | 352 | ##### `log_format` 353 | 354 | This parameter allows you to specify the format used for logging file transfers when transfer logging is enabled. See the [rsyncd.conf man page] for more details. 355 | 356 | ##### `refuse_options` 357 | 358 | List of rsync command line options that will be refused by your rsync daemon. 359 | 360 | ##### `ignore_nonreadable` 361 | 362 | This tells the rsync daemon to completely ignore files that are not readable by the user. 363 | ======= 364 | ## Parameters: ## 365 | $source - source to copy from 366 | $path - path to copy to, defaults to $name 367 | $user - username on remote system 368 | $purge - if set, rsync will use '--delete' 369 | $exclude - string (or array) to be excluded 370 | $include - string (or array) to be included 371 | $exclude_first - if 'true' (default) then first exclude and then include; the other way around if 'false' 372 | $keyfile - path to ssh key used to connect to remote host, defaults to /home/${user}/.ssh/id_rsa 373 | $timeout - timeout in seconds, defaults to 900 374 | $options - default options to pass to rsync (-a) 375 | 376 | ## Actions: ## 377 | put files via rsync 378 | 379 | ## Requires: ## 380 | $source must be set 381 | 382 | ## Sample Usage: ## 383 | rsync::put { '${rsyncDestHost}:/repo/foo': 384 | user => 'user', 385 | source => "/repo/foo/", 386 | } 387 | 388 | # Definition: rsync::server::module # 389 | 390 | sets up a rsync server 391 | 392 | ## Parameters: ## 393 | $path - path to data 394 | $comment - rsync comment 395 | $use_chroot - yes||no, defaults to yes 396 | $motd - file containing motd info 397 | $read_only - yes||no, defaults to yes 398 | $write_only - yes||no, defaults to no 399 | $list - yes||no, defaults to no 400 | $uid - uid of rsync server, defaults to 0 401 | $gid - gid of rsync server, defaults to 0 402 | $numeric_ids - don't resolve uids to usernames, defaults to yes 403 | $incoming_chmod - incoming file mode, defaults to 644 404 | $outgoing_chmod - outgoing file mode, defaults to 644 405 | $max_connections - maximum number of simultaneous connections allowed, defaults to 0 406 | $timeout - disconnect client after X seconds of inactivity, defaults to 0 407 | $lock_file - file used to support the max connections parameter, defaults to /var/run/rsyncd.lock only needed if max_connections > 0 408 | $secrets_file - path to the file that contains the username:password pairs used for authenticating this module 409 | $auth_users - list of usernames that will be allowed to connect to this module (must be undef or an array) 410 | $hosts_allow - list of patterns allowed to connect to this module (man 5 rsyncd.conf for details, must be undef or an array) 411 | $hosts_deny - list of patterns allowed to connect to this module (man 5 rsyncd.conf for details, must be undef or an array) 412 | $transfer_logging - parameter enables per-file logging of downloads and uploads in a format somewhat similar to that used by ftp daemons. 413 | $log_file - log messages to the indicated file rather than using syslog 414 | $log_format - This parameter allows you to specify the format used for logging file transfers when transfer logging is enabled. See the rsyncd.conf documentation for more details. 415 | $refuse_options - list of rsync command line options that will be refused by your rsync daemon. 416 | $include - list of files to include 417 | $include_from - file containing a list of files to include 418 | $exclude - list of files to exclude 419 | $exclude_from - file containing a list of files to exclude 420 | $dont_compress - disable compression on matching files 421 | $ignore_nonreadable - This tells the rsync daemon to completely ignore files that are not readable by the user. 422 | 423 | ## Actions: ## 424 | sets up an rsync server 425 | 426 | ## Requires: ## 427 | $path must be set 428 | 429 | ## Sample Usage: ## 430 | # setup default rsync repository 431 | rsync::server::module{ 'repo': 432 | path => $base, 433 | require => File[$base], 434 | } 435 | 436 | To disable default values for ``incoming_chmod`` and ``outgoing_chmod``, and 437 | do not add empty values to the resulting config, set both values to ``false`` 438 | 439 | rsync::server::module { 'repo': 440 | path => $base, 441 | incoming_chmod => false, 442 | outgoing_chmod => false, 443 | require => File[$base], 444 | } 445 | 446 | # Configuring via Hiera # 447 | ``rsync::put``, ``rsync::get``, and ``rsync::server::module`` resources can be 448 | configured using Hiera hashes. For example: 449 | 450 | [rsyncd.conf man page]:https://download.samba.org/pub/rsync/rsyncd.conf.html 451 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'bundler' 4 | require 'puppet_litmus/rake_tasks' if Gem.loaded_specs.key? 'puppet_litmus' 5 | require 'puppetlabs_spec_helper/rake_tasks' 6 | require 'puppet-syntax/tasks/puppet-syntax' 7 | require 'puppet-strings/tasks' if Gem.loaded_specs.key? 'puppet-strings' 8 | 9 | PuppetLint.configuration.send('disable_relative') 10 | -------------------------------------------------------------------------------- /data/common.yaml: -------------------------------------------------------------------------------- 1 | --- {} 2 | -------------------------------------------------------------------------------- /data/os/Debian.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | rsync::server::conf_file: '/etc/rsyncd.conf' 4 | -------------------------------------------------------------------------------- /data/os/FreeBSD.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | rsync::server::conf_file: '/usr/local/etc/rsync/rsyncd.conf' 4 | rsync::server::servicename: 'rsyncd' 5 | -------------------------------------------------------------------------------- /data/os/RedHat.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | rsync::server::conf_file: '/etc/rsyncd.conf' 4 | rsync::server::servicename: 'rsyncd' 5 | -------------------------------------------------------------------------------- /data/os/RedHat/8.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # RHEL8 and newer have a separate package for the rsync daemon. 4 | rsync::server::package_name: rsync-daemon 5 | -------------------------------------------------------------------------------- /data/os/RedHat/9.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # RHEL8 and newer have a separate package for the rsync daemon. 4 | rsync::server::package_name: rsync-daemon 5 | -------------------------------------------------------------------------------- /data/os/Suse.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | rsync::server::conf_file: '/etc/rsyncd.conf' 4 | rsync::server::servicename: 'rsyncd' 5 | -------------------------------------------------------------------------------- /examples/init.pp: -------------------------------------------------------------------------------- 1 | include rsync 2 | -------------------------------------------------------------------------------- /examples/repo.pp: -------------------------------------------------------------------------------- 1 | include rsync::repo 2 | -------------------------------------------------------------------------------- /examples/server_with_motd.pp: -------------------------------------------------------------------------------- 1 | class { 'rsync::server': 2 | motd_file => '/etc/rsync-motd', 3 | } 4 | -------------------------------------------------------------------------------- /files/defaults: -------------------------------------------------------------------------------- 1 | # Debian defaults file for rsync daemon mode. 2 | #### This file is being maintained by Puppet. 3 | #### DO NOT EDIT! 4 | 5 | # start rsync in daemon mode from init.d script? 6 | # only allowed values are "true", "false", and "inetd" 7 | # Use "inetd" if you want to start the rsyncd from inetd, 8 | # all this does is prevent the init.d script from printing a message 9 | # about not starting rsyncd (you still need to modify inetd's config yourself). 10 | RSYNC_ENABLE=true 11 | 12 | # which file should be used as the configuration file for rsync. 13 | # This file is used instead of the default /etc/rsyncd.conf 14 | # Warning: This option has no effect if the daemon is accessed 15 | # using a remote shell. When using a different file for 16 | # rsync you might want to symlink /etc/rsyncd.conf to 17 | # that file. 18 | # RSYNC_CONFIG_FILE= 19 | 20 | # what extra options to give rsync --daemon? 21 | # that excludes the --daemon; that's always done in the init.d script 22 | # Possibilities are: 23 | # --address=123.45.67.89 (bind to a specific IP address) 24 | # --port=8730 (bind to specified port; default 873) 25 | RSYNC_OPTS='' 26 | 27 | # run rsyncd at a nice level? 28 | # the rsync daemon can impact performance due to much I/O and CPU usage, 29 | # so you may want to run it at a nicer priority than the default priority. 30 | # Allowed values are 0 - 19 inclusive; 10 is a reasonable value. 31 | RSYNC_NICE='' 32 | 33 | # run rsyncd with ionice? 34 | # "ionice" does for IO load what "nice" does for CPU load. 35 | # As rsync is often used for backups which aren't all that time-critical, 36 | # reducing the rsync IO priority will benefit the rest of the system. 37 | # See the manpage for ionice for allowed options. 38 | # -c3 is recommended, this will run rsync IO at "idle" priority. Uncomment 39 | # the next line to activate this. 40 | # RSYNC_IONICE='-c3' 41 | 42 | # Don't forget to create an appropriate config file, 43 | # else the daemon will not start. 44 | -------------------------------------------------------------------------------- /files/motd: -------------------------------------------------------------------------------- 1 | __________________ 2 | < I <3 Puppet Labs > 3 | ------------------ 4 | \ ^__^ 5 | \ (oo)\_______ 6 | (__)\ )\/\ 7 | ||----w | 8 | || || 9 | 10 | -------------------------------------------------------------------------------- /hiera.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 5 3 | 4 | defaults: # Used for any hierarchy level that omits these keys. 5 | datadir: data # This path is relative to hiera.yaml's directory. 6 | data_hash: yaml_data # Use the built-in YAML backend. 7 | 8 | hierarchy: 9 | - name: "osfamily/major release" 10 | paths: 11 | # Used to distinguish between Debian and Ubuntu 12 | - "os/%{facts.os.name}/%{facts.os.release.major}.yaml" 13 | - "os/%{facts.os.family}/%{facts.os.release.major}.yaml" 14 | # Used for Solaris 15 | - "os/%{facts.os.family}/%{facts.kernelrelease}.yaml" 16 | - name: "osfamily" 17 | paths: 18 | - "os/%{facts.os.name}.yaml" 19 | - "os/%{facts.os.family}.yaml" 20 | - name: 'common' 21 | path: 'common.yaml' 22 | -------------------------------------------------------------------------------- /locales/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # This is the project-specific configuration file for setting up 3 | # fast_gettext for your project. 4 | gettext: 5 | # This is used for the name of the .pot and .po files; they will be 6 | # called .pot? 7 | project_name: puppetlabs-rsync 8 | # This is used in comments in the .pot and .po files to indicate what 9 | # project the files belong to and should bea little more desctiptive than 10 | # 11 | package_name: puppetlabs-rsync 12 | # The locale that the default messages in the .pot file are in 13 | default_locale: en 14 | # The email used for sending bug reports. 15 | bugs_address: docs@puppet.com 16 | # The holder of the copyright. 17 | copyright_holder: Puppet, Inc. 18 | # This determines which comments in code should be eligible for translation. 19 | # Any comments that start with this string will be externalized. (Leave 20 | # empty to include all.) 21 | comments_tag: TRANSLATOR 22 | # Patterns for +Dir.glob+ used to find all files that might contain 23 | # translatable content, relative to the project root directory 24 | source_files: 25 | 26 | -------------------------------------------------------------------------------- /manifests/get.pp: -------------------------------------------------------------------------------- 1 | # Definition: rsync::get 2 | # 3 | # get files via rsync 4 | # 5 | # Parameters: 6 | # $source - source to copy from 7 | # $path - path to copy to, defaults to $name 8 | # $user - username on remote system 9 | # $purge - if set, rsync will use '--delete' 10 | # $exlude - string (or array) to be excluded 11 | # $include - string (or array) to be included 12 | # $exclude_first - if 'true' (default) then first exclude and then include; the other way around if 'false' 13 | # $keyfile - path to ssh key used to connect to remote host, defaults to /home/${user}/.ssh/id_rsa 14 | # $timeout - timeout in seconds, defaults to 900 15 | # $options - default options to pass to rsync (-a) 16 | # $chown - ownership to pass to rsync (optional; requires rsync 3.1.0+) 17 | # $chmod - permissions to pass to rsync (optional) 18 | # $logfile - logname to pass to rsync (optional) 19 | # $onlyif - Condition to run the rsync command 20 | # 21 | # Actions: 22 | # get files via rsync 23 | # 24 | # Requires: 25 | # $source must be set 26 | # 27 | # Sample Usage: 28 | # 29 | # rsync::get { '/foo': 30 | # source => "rsync://${rsyncServer}/repo/foo/", 31 | # require => File['/foo'], 32 | # } # rsync 33 | # 34 | define rsync::get ( 35 | $source, 36 | $path = $name, 37 | $user = undef, 38 | $purge = undef, 39 | $recursive = undef, 40 | $links = undef, 41 | $hardlinks = undef, 42 | $copylinks = undef, 43 | $times = undef, 44 | $include = undef, 45 | $exclude = undef, 46 | $exclude_first = true, 47 | $keyfile = undef, 48 | $timeout = '900', 49 | $execuser = 'root', 50 | $options = '-a', 51 | $chown = undef, 52 | $chmod = undef, 53 | $logfile = undef, 54 | $onlyif = undef, 55 | ) { 56 | if $keyfile { 57 | $mykeyfile = $keyfile 58 | } else { 59 | $mykeyfile = "/home/${user}/.ssh/id_rsa" 60 | } 61 | 62 | if $user { 63 | $myuser = "-e 'ssh -i ${mykeyfile} -l ${user}' ${user}@" 64 | } else { 65 | $myuser = undef 66 | } 67 | 68 | if $purge { 69 | $mypurge = '--delete' 70 | } else { 71 | $mypurge = undef 72 | } 73 | 74 | if $exclude { 75 | $myexclude = join(prefix(flatten([$exclude]), '--exclude='), ' ') 76 | } else { 77 | $myexclude = undef 78 | } 79 | 80 | if $include { 81 | $myinclude = join(prefix(flatten([$include]), '--include='), ' ') 82 | } else { 83 | $myinclude = undef 84 | } 85 | 86 | if $recursive { 87 | $myrecursive = '-r' 88 | } else { 89 | $myrecursive = undef 90 | } 91 | 92 | if $links { 93 | $mylinks = '--links' 94 | } else { 95 | $mylinks = undef 96 | } 97 | 98 | if $hardlinks { 99 | $myhardlinks = '--hard-links' 100 | } else { 101 | $myhardlinks = undef 102 | } 103 | 104 | if $copylinks { 105 | $mycopylinks = '--copy-links' 106 | } else { 107 | $mycopylinks = undef 108 | } 109 | 110 | if $times { 111 | $mytimes = '--times' 112 | } else { 113 | $mytimes = undef 114 | } 115 | 116 | if $chown { 117 | $mychown = "--chown=${chown}" 118 | } else { 119 | $mychown = undef 120 | } 121 | 122 | if $chmod { 123 | $mychmod = "--chmod=${chmod}" 124 | } else { 125 | $mychmod = undef 126 | } 127 | 128 | if $logfile { 129 | $mylogfile = "--log-file=${logfile}" 130 | } else { 131 | $mylogfile = undef 132 | } 133 | 134 | if $include or $exclude { 135 | if $exclude_first { 136 | $excludeandinclude = join(delete_undef_values([$myexclude, $myinclude]), ' ') 137 | } else { 138 | $excludeandinclude = join(delete_undef_values([$myinclude, $myexclude]), ' ') 139 | } 140 | } else { 141 | $excludeandinclude = undef 142 | } 143 | 144 | $rsync_options = join( 145 | delete_undef_values([$options, $mypurge, $excludeandinclude, $mylinks, $myhardlinks, $mycopylinks, $mytimes, 146 | $myrecursive, $mychown, $mychmod, $mylogfile, "${myuser}${source}", $path]), ' ') 147 | 148 | if !$onlyif { 149 | $onlyif_real = "test `rsync --dry-run --itemize-changes ${rsync_options} | wc -l` -gt 0" 150 | } else { 151 | $onlyif_real = $onlyif 152 | } 153 | 154 | 155 | exec { "rsync ${name}": 156 | command => "rsync -q ${rsync_options}", 157 | path => ['/bin', '/usr/bin', '/usr/local/bin'], 158 | user => $execuser, 159 | # perform a dry-run to determine if anything needs to be updated 160 | # this ensures that we only actually create a Puppet event if something needs to 161 | # be updated 162 | # TODO - it may make senes to do an actual run here (instead of a dry run) 163 | # and relace the command with an echo statement or something to ensure 164 | # that we only actually run rsync once 165 | onlyif => $onlyif_real, 166 | timeout => $timeout, 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /manifests/init.pp: -------------------------------------------------------------------------------- 1 | # Class: rsync 2 | # 3 | # This module manages rsync 4 | # 5 | class rsync ( 6 | $package_ensure = 'installed', 7 | $manage_package = true, 8 | $puts = {}, 9 | $gets = {}, 10 | ) { 11 | if $manage_package { 12 | package { 'rsync': 13 | ensure => $package_ensure, 14 | } -> Rsync::Get<| |> 15 | } 16 | 17 | create_resources(rsync::put, $puts) 18 | create_resources(rsync::get, $gets) 19 | } 20 | -------------------------------------------------------------------------------- /manifests/put.pp: -------------------------------------------------------------------------------- 1 | # Definition: rsync::put 2 | # 3 | # put files via rsync 4 | # 5 | # Parameters: 6 | # $source - source to copy from 7 | # $path - path to copy to, defaults to $name 8 | # $user - username on remote system 9 | # $purge - if set, rsync will use '--delete' 10 | # $exlude - string (or array) to be excluded 11 | # $include - string (or array) to be included 12 | # $exclude_first - if 'true' then first exclude and then include; the other way around if 'false' 13 | # $keyfile - path to ssh key used to connect to remote host, defaults to /home/${user}/.ssh/id_rsa 14 | # $timeout - timeout in seconds, defaults to 900 15 | # 16 | # Actions: 17 | # put files via rsync 18 | # 19 | # Requires: 20 | # $source must be set 21 | # 22 | # Sample Usage: 23 | # 24 | # rsync::put { '${rsyncDestHost}:/repo/foo': 25 | # user => 'user', 26 | # source => "/repo/foo/", 27 | # } # rsync 28 | # 29 | define rsync::put ( 30 | $source, 31 | $path = undef, 32 | $user = undef, 33 | $purge = undef, 34 | $exclude = undef, 35 | $include = undef, 36 | $exclude_first = true, 37 | $keyfile = undef, 38 | $timeout = '900', 39 | $options = '-a' 40 | ) { 41 | if $keyfile { 42 | $mykeyfile = $keyfile 43 | } else { 44 | $mykeyfile = "/home/${user}/.ssh/id_rsa" 45 | } 46 | 47 | if $user { 48 | $myuseropt = "-e 'ssh -i ${mykeyfile} -l ${user}'" 49 | $myuser = "${user}@" 50 | } else { 51 | $myuseropt = undef 52 | $myuser = undef 53 | } 54 | 55 | if $purge { 56 | $mypurge = '--delete' 57 | } else { 58 | $mypurge = undef 59 | } 60 | 61 | if $exclude { 62 | $myexclude = join(prefix(flatten([$exclude]), '--exclude='), ' ') 63 | } else { 64 | $myexclude = undef 65 | } 66 | 67 | if $include { 68 | $myinclude = join(prefix(flatten([$include]), '--include='), ' ') 69 | } else { 70 | $myinclude = undef 71 | } 72 | 73 | if $include or $exclude { 74 | if $exclude_first { 75 | $excludeandinclude = join(delete_undef_values([$myexclude, $myinclude]), ' ') 76 | } else { 77 | $excludeandinclude = join(delete_undef_values([$myinclude, $myexclude]), ' ') 78 | } 79 | } else { 80 | $excludeandinclude = undef 81 | } 82 | 83 | if $path { 84 | $mypath = $path 85 | } else { 86 | $mypath = $name 87 | } 88 | 89 | $rsync_options = join( 90 | delete_undef_values([$options, $mypurge, $excludeandinclude, $myuseropt, $source, "${myuser}${mypath}"]), ' ') 91 | 92 | exec { "rsync ${name}": 93 | command => "rsync -q ${rsync_options}", 94 | path => ['/bin', '/usr/bin'], 95 | # perform a dry-run to determine if anything needs to be updated 96 | # this ensures that we only actually create a Puppet event if something needs to 97 | # be updated 98 | # TODO - it may make senes to do an actual run here (instead of a dry run) 99 | # and relace the command with an echo statement or something to ensure 100 | # that we only actually run rsync once 101 | onlyif => "test `rsync --dry-run --itemize-changes ${rsync_options} | wc -l` -gt 0", 102 | timeout => $timeout, 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /manifests/repo.pp: -------------------------------------------------------------------------------- 1 | # Class: rsync::repo 2 | # 3 | # This module creates a rsync repository 4 | # 5 | # Requires: 6 | # class rsync::server 7 | # 8 | class rsync::repo { 9 | 10 | include rsync::server 11 | 12 | $base = '/data/rsync' 13 | 14 | file { $base: 15 | ensure => directory, 16 | } 17 | 18 | # setup default rsync repository 19 | rsync::server::module { 'repo': 20 | path => $base, 21 | require => File[$base], 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /manifests/server.pp: -------------------------------------------------------------------------------- 1 | # Class: rsync::server 2 | # 3 | # The rsync server. Supports both standard rsync as well as rsync over ssh 4 | # 5 | # Requires: 6 | # class xinetd if use_xinetd is set to true 7 | # class rsync 8 | # 9 | class rsync::server ( 10 | Boolean $use_xinetd = true, 11 | $address = '0.0.0.0', 12 | $motd_file = 'UNSET', 13 | Variant[Enum['UNSET'], Stdlib::Absolutepath] $pid_file = '/var/run/rsyncd.pid', 14 | $use_chroot = 'yes', 15 | $uid = 'nobody', 16 | $gid = 'nobody', 17 | $modules = {}, 18 | Optional[String[1]] $package_name = undef, 19 | String[1] $conf_file = '/etc/rsync.conf', 20 | String[1] $servicename = 'rsync', 21 | Stdlib::Ensure::Service $service_ensure = 'running', 22 | Variant[Boolean, Enum['mask']] $service_enable = true, 23 | Boolean $manage_package = $rsync::manage_package, 24 | ) inherits rsync { 25 | if $use_xinetd { 26 | include xinetd 27 | xinetd::service { 'rsync': 28 | bind => $address, 29 | port => '873', 30 | server => '/usr/bin/rsync', 31 | server_args => "--daemon --config ${conf_file}", 32 | require => Package['rsync'], 33 | } 34 | } else { 35 | # Manage the installation of the rsyncd package? 36 | if $manage_package { 37 | # RHEL8 and newer (and their variants) have a separate package for rsyncd daemon. If the $package_name 38 | # variable is defined (the variable is defined in the hiera hierarchy), then install the package. 39 | if $package_name { 40 | package { $package_name: 41 | ensure => $rsync::package_ensure, 42 | notify => Service[$servicename], 43 | } 44 | } 45 | } 46 | 47 | service { $servicename: 48 | ensure => $service_ensure, 49 | enable => $service_enable, 50 | hasstatus => true, 51 | hasrestart => true, 52 | subscribe => Concat[$conf_file], 53 | } 54 | 55 | if ( $facts['os']['family'] == 'Debian' ) { 56 | file { '/etc/default/rsync': 57 | source => 'puppet:///modules/rsync/defaults', 58 | notify => Service['rsync'], 59 | } 60 | } 61 | } 62 | 63 | if $motd_file != 'UNSET' { 64 | file { '/etc/rsync-motd': 65 | source => 'puppet:///modules/rsync/motd', 66 | } 67 | } 68 | 69 | concat { $conf_file: } 70 | 71 | # Template uses: 72 | # - $use_chroot 73 | # - $address 74 | # - $motd_file 75 | concat::fragment { 'rsyncd_conf_header': 76 | target => $conf_file, 77 | content => template('rsync/header.erb'), 78 | order => '00_header', 79 | } 80 | 81 | create_resources(rsync::server::module, $modules) 82 | 83 | } 84 | -------------------------------------------------------------------------------- /manifests/server/module.pp: -------------------------------------------------------------------------------- 1 | # Definition: rsync::server::module 2 | # 3 | # sets up a rsync server 4 | # 5 | # Parameters: 6 | # $path - path to data 7 | # $comment - rsync comment 8 | # $use_chroot - yes||no, defaults to undef 9 | # $read_only - yes||no, defaults to yes 10 | # $write_only - yes||no, defaults to no 11 | # $list - yes||no, defaults to yes 12 | # $uid - uid of rsync server 13 | # $gid - gid of rsync server 14 | # $numeric_ids - yes||no, don't resolve uids to usernames, defaults to undef 15 | # $ignore_nonreadable - do not display files the daemon cannot read, defaults to yes 16 | # $incoming_chmod - incoming file mode 17 | # $outgoing_chmod - outgoing file mode 18 | # $max_connections - maximum number of simultaneous connections allowed, defaults to 0 19 | # $lock_file - file used to support the max connections parameter, defaults to /var/run/rsyncd.lock 20 | # only needed if max_connections > 0 21 | # $secrets_file - path to the file that contains the username:password pairs used for authenticating this module 22 | # $auth_users - list of usernames that will be allowed to connect to this module (must be undef or an array) 23 | # $hosts_allow - list of patterns allowed to connect to this module (man 5 rsyncd.conf for details, must be undef or an array) 24 | # $hosts_deny - list of patterns allowed to connect to this module (man 5 rsyncd.conf for details, must be undef or an array) 25 | # $timeout - disconnect client after X seconds of inactivity, defaults to 0 26 | # $transfer_logging - parameter enables per-file logging of downloads and 27 | # uploads in a format somewhat similar to that used by ftp daemons. 28 | # $log_format - This parameter allows you to specify the format used 29 | # for logging file transfers when transfer logging is enabled. See the 30 | # rsyncd.conf documentation for more details. 31 | # $log_file - log messages to the indicated file rather than using syslog 32 | # $refuse_options - list of rsync command line options that will be refused by your rsync daemon. 33 | # $include - list of files to include 34 | # $include_from - file containing a list of files to include 35 | # $exclude - list of files to exclude 36 | # $exclude_from - file containing a list of files to exclude 37 | # $dont_compress - disable compression on matching files 38 | # 39 | # sets up an rsync server 40 | # 41 | # Requires: 42 | # $path must be set 43 | # 44 | # Sample Usage: 45 | # # setup default rsync repository 46 | # rsync::server::module { 'repo': 47 | # path => $base, 48 | # require => File[$base], 49 | # } 50 | # 51 | define rsync::server::module ( 52 | $path, 53 | $order = "10_${name}", 54 | $comment = undef, 55 | $use_chroot = undef, 56 | $read_only = 'yes', 57 | $write_only = 'no', 58 | $list = 'yes', 59 | $uid = undef, 60 | $gid = undef, 61 | $numeric_ids = undef, 62 | $incoming_chmod = undef, 63 | $outgoing_chmod = undef, 64 | $max_connections = '0', 65 | $timeout = '0', 66 | $lock_file = '/var/run/rsyncd.lock', 67 | $secrets_file = undef, 68 | $auth_users = undef, 69 | $hosts_allow = undef, 70 | $hosts_deny = undef, 71 | $transfer_logging = undef, 72 | $log_file = undef, 73 | $log_format = undef, 74 | $refuse_options = undef, 75 | $include = undef, 76 | $include_from = undef, 77 | $exclude = undef, 78 | $exclude_from = undef, 79 | $dont_compress = undef, 80 | $ignore_nonreadable = undef) { 81 | 82 | concat::fragment { "frag-${name}": 83 | content => template('rsync/module.erb'), 84 | target => $rsync::server::conf_file, 85 | order => $order, 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "puppetlabs-rsync", 3 | "version": "1.2.0", 4 | "author": "puppetlabs", 5 | "summary": "Manages rsync clients, repositories, and servers, & providies defines to easily grab data via rsync.", 6 | "license": "Apache-2.0", 7 | "source": "https://github.com/puppetlabs/puppetlabs-rsync", 8 | "project_page": "https://github.com/puppetlabs/puppetlabs-rsync", 9 | "issues_url": "https://tickets.puppetlabs.com/browse/MODULES", 10 | "dependencies": [ 11 | { 12 | "name": "puppetlabs/stdlib", 13 | "version_requirement": ">= 4.2.0 < 10.0.0" 14 | }, 15 | { 16 | "name": "puppetlabs/xinetd", 17 | "version_requirement": ">=1.1.0 < 4.0.0" 18 | }, 19 | { 20 | "name": "puppetlabs/concat", 21 | "version_requirement": ">= 1.1.1 < 10.0.0" 22 | } 23 | ], 24 | "operatingsystem_support": [ 25 | { 26 | "operatingsystem": "CentOS", 27 | "operatingsystemrelease": [ 28 | "6.0", 29 | "7.0", 30 | "8.0" 31 | ] 32 | }, 33 | { 34 | "operatingsystem": "Debian", 35 | "operatingsystemrelease": [ 36 | "8.0", 37 | "9.0" 38 | ] 39 | }, 40 | { 41 | "operatingsystem": "Ubuntu", 42 | "operatingsystemrelease": [ 43 | "14.04", 44 | "16.04" 45 | ] 46 | }, 47 | { 48 | "operatingsystem": "FreeBSD", 49 | "operatingsystemrelease": [ 50 | "10.0", 51 | "11.0" 52 | ] 53 | }, 54 | { 55 | "operatingsystem": "SLES", 56 | "operatingsystemrelease": [ 57 | "10", 58 | "11", 59 | "12" 60 | ] 61 | } 62 | ], 63 | "requirements": [ 64 | { 65 | "name": "puppet", 66 | "version_requirement": ">= 6.0.0 < 8.0.0" 67 | } 68 | ], 69 | "pdk-version": "3.0.1", 70 | "template-url": "https://github.com/puppetlabs/pdk-templates#main", 71 | "template-ref": "heads/main-0-g909fd77" 72 | } 73 | -------------------------------------------------------------------------------- /spec/classes/server_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | describe 'rsync::server', type: :class do 3 | on_supported_os.each do |os, facts| 4 | context "on #{os} " do 5 | let :facts do 6 | facts 7 | end 8 | 9 | describe 'when using default params' do 10 | it { 11 | is_expected.to contain_class('xinetd') 12 | is_expected.to contain_xinetd__service('rsync').with(bind: '0.0.0.0') 13 | is_expected.not_to contain_service('rsync') 14 | is_expected.not_to contain_file('/etc/rsync-motd') 15 | is_expected.to contain_concat__fragment('rsyncd_conf_header').with(order: '00_header') 16 | is_expected.to contain_concat__fragment('rsyncd_conf_header').with_content(%r{^use chroot\s*=\s*yes$}) 17 | is_expected.to contain_concat__fragment('rsyncd_conf_header').with_content(%r{^address\s*=\s*0.0.0.0$}) 18 | is_expected.to contain_concat__fragment('rsyncd_conf_header').with_content(%r{^pid file\s*=\s*/var/run/rsyncd.pid$}) 19 | } 20 | end 21 | 22 | describe 'when disabling xinetd' do 23 | let :params do 24 | { use_xinetd: false } 25 | end 26 | 27 | it { 28 | is_expected.not_to contain_class('xinetd') 29 | is_expected.not_to contain_xinetd__service('rsync') 30 | } 31 | servicename = case facts[:os]['family'] 32 | when 'RedHat', 'Suse', 'FreeBSD' 33 | 'rsyncd' 34 | else 35 | 'rsync' 36 | end 37 | it { is_expected.to contain_service(servicename) } 38 | if facts[:os][:family] == 'RedHat' && Integer(facts[:os][:release][:major]) >= 8 39 | it { is_expected.to contain_package('rsync-daemon') } 40 | end 41 | end 42 | 43 | describe 'when setting an motd' do 44 | let :params do 45 | { motd_file: true } 46 | end 47 | 48 | it { 49 | is_expected.to contain_file('/etc/rsync-motd') 50 | } 51 | end 52 | 53 | describe 'when unsetting pid file' do 54 | let :params do 55 | { pid_file: 'UNSET' } 56 | end 57 | 58 | it { 59 | is_expected.not_to contain_concat__fragment('rsyncd_conf_header').with_content(%r{^pid file\s*=}) 60 | } 61 | end 62 | 63 | describe 'when overriding use_chroot' do 64 | let :params do 65 | { use_chroot: 'no' } 66 | end 67 | 68 | it { 69 | is_expected.to contain_concat__fragment('rsyncd_conf_header').with_content(%r{^use chroot\s*=\s*no$}) 70 | } 71 | end 72 | 73 | describe 'when overriding address' do 74 | let :params do 75 | { address: '10.0.0.42' } 76 | end 77 | 78 | it { 79 | is_expected.to contain_concat__fragment('rsyncd_conf_header').with_content(%r{^address\s*=\s*10.0.0.42$}) 80 | } 81 | end 82 | 83 | describe 'when overriding uid' do 84 | let :params do 85 | { uid: 'testuser' } 86 | end 87 | 88 | it { 89 | is_expected.to contain_concat__fragment('rsyncd_conf_header').with_content(%r{^uid\s*=\s*testuser$}) 90 | } 91 | end 92 | 93 | describe 'when overriding gid' do 94 | let :params do 95 | { gid: 'testgroup' } 96 | end 97 | 98 | it { 99 | is_expected.to contain_concat__fragment('rsyncd_conf_header').with_content(%r{^gid\s*=\s*testgroup$}) 100 | } 101 | end 102 | end 103 | end 104 | end 105 | -------------------------------------------------------------------------------- /spec/default_facts.yml: -------------------------------------------------------------------------------- 1 | # Use default_module_facts.yml for module specific facts. 2 | # 3 | # Facts specified here will override the values provided by rspec-puppet-facts. 4 | --- 5 | networking: 6 | ip: "172.16.254.254" 7 | ip6: "FE80:0000:0000:0000:AAAA:AAAA:AAAA" 8 | mac: "AA:AA:AA:AA:AA:AA" 9 | is_pe: false 10 | -------------------------------------------------------------------------------- /spec/defines/get_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | describe 'rsync::get', type: :define do 3 | let :title do 4 | 'foobar' 5 | end 6 | 7 | let :common_params do 8 | { 9 | source: 'example.com', 10 | } 11 | end 12 | 13 | describe 'when using default class paramaters' do 14 | let :params do 15 | common_params 16 | end 17 | 18 | it { 19 | is_expected.to contain_exec('rsync foobar').with( 20 | command: 'rsync -q -a example.com foobar', 21 | onlyif: 'test `rsync --dry-run --itemize-changes -a example.com foobar | wc -l` -gt 0', 22 | timeout: '900', 23 | user: 'root', 24 | ) 25 | } 26 | end 27 | 28 | describe 'when setting the execuser' do 29 | let :params do 30 | common_params.merge(execuser: 'username') 31 | end 32 | 33 | it { is_expected.to contain_exec('rsync foobar').with(user: 'username') } 34 | end 35 | 36 | describe 'when setting the timeout' do 37 | let :params do 38 | common_params.merge(timeout: '200') 39 | end 40 | 41 | it { 42 | is_expected.to contain_exec('rsync foobar').with(timeout: '200') 43 | } 44 | end 45 | 46 | describe 'when setting a user but not a keyfile' do 47 | let :params do 48 | common_params.merge(user: 'mr_baz') 49 | end 50 | 51 | it { 52 | is_expected.to contain_exec('rsync foobar').with( 53 | command: 'rsync -q -a -e \'ssh -i /home/mr_baz/.ssh/id_rsa -l mr_baz\' mr_baz@example.com foobar', 54 | onlyif: 'test `rsync --dry-run --itemize-changes -a -e \'ssh -i /home/mr_baz/.ssh/id_rsa -l mr_baz\' mr_baz@example.com foobar | wc -l` -gt 0', 55 | ) 56 | } 57 | end 58 | 59 | describe 'when setting a keyfile but not a user' do 60 | let :params do 61 | common_params.merge(keyfile: '/path/to/keyfile') 62 | end 63 | 64 | it { 65 | is_expected.to contain_exec('rsync foobar').with( 66 | command: 'rsync -q -a example.com foobar', 67 | onlyif: 'test `rsync --dry-run --itemize-changes -a example.com foobar | wc -l` -gt 0', 68 | ) 69 | } 70 | end 71 | 72 | describe 'when setting a user and a keyfile' do 73 | let :params do 74 | common_params.merge( 75 | user: 'mr_baz', 76 | keyfile: '/path/to/keyfile', 77 | ) 78 | end 79 | 80 | it { 81 | is_expected.to contain_exec('rsync foobar').with( 82 | command: 'rsync -q -a -e \'ssh -i /path/to/keyfile -l mr_baz\' mr_baz@example.com foobar', 83 | onlyif: 'test `rsync --dry-run --itemize-changes -a -e \'ssh -i /path/to/keyfile -l mr_baz\' mr_baz@example.com foobar | wc -l` -gt 0', 84 | ) 85 | } 86 | end 87 | 88 | describe 'when setting an exclude path' do 89 | let :params do 90 | common_params.merge(exclude: '/path/to/exclude/') 91 | end 92 | 93 | it { 94 | is_expected.to contain_exec('rsync foobar').with( 95 | command: 'rsync -q -a --exclude=/path/to/exclude/ example.com foobar', 96 | onlyif: 'test `rsync --dry-run --itemize-changes -a --exclude=/path/to/exclude/ example.com foobar | wc -l` -gt 0', 97 | ) 98 | } 99 | end 100 | 101 | describe 'when setting multiple exclude paths' do 102 | let :params do 103 | common_params.merge(exclude: ['logs/', 'tmp/']) 104 | end 105 | 106 | it { 107 | is_expected.to contain_exec('rsync foobar').with( 108 | command: 'rsync -q -a --exclude=logs/ --exclude=tmp/ example.com foobar', 109 | onlyif: 'test `rsync --dry-run --itemize-changes -a --exclude=logs/ --exclude=tmp/ example.com foobar | wc -l` -gt 0', 110 | ) 111 | } 112 | end 113 | 114 | describe 'when setting an include path' do 115 | let :params do 116 | common_params.merge(include: '/path/to/include/') 117 | end 118 | 119 | it { 120 | is_expected.to contain_exec('rsync foobar').with( 121 | command: 'rsync -q -a --include=/path/to/include/ example.com foobar', 122 | onlyif: 'test `rsync --dry-run --itemize-changes -a --include=/path/to/include/ example.com foobar | wc -l` -gt 0', 123 | ) 124 | } 125 | end 126 | 127 | describe 'when setting multiple include paths' do 128 | let :params do 129 | common_params.merge(include: ['htdocs/', 'cache/']) 130 | end 131 | 132 | it { 133 | is_expected.to contain_exec('rsync foobar').with( 134 | command: 'rsync -q -a --include=htdocs/ --include=cache/ example.com foobar', 135 | onlyif: 'test `rsync --dry-run --itemize-changes -a --include=htdocs/ --include=cache/ example.com foobar | wc -l` -gt 0', 136 | ) 137 | } 138 | end 139 | 140 | describe 'when leaving default exclude and include order (exclude first)' do 141 | let :params do 142 | common_params.merge(include: 'cache/', exclude: 'something') 143 | end 144 | 145 | it { 146 | is_expected.to contain_exec('rsync foobar').with( 147 | command: 'rsync -q -a --exclude=something --include=cache/ example.com foobar', 148 | onlyif: 'test `rsync --dry-run --itemize-changes -a --exclude=something --include=cache/ example.com foobar | wc -l` -gt 0', 149 | ) 150 | } 151 | end 152 | 153 | describe 'when changing the exclude and include order to include first' do 154 | let :params do 155 | common_params.merge(include: 'cache/', exclude: 'something', exclude_first: false) 156 | end 157 | 158 | it { 159 | is_expected.to contain_exec('rsync foobar').with( 160 | command: 'rsync -q -a --include=cache/ --exclude=something example.com foobar', 161 | onlyif: 'test `rsync --dry-run --itemize-changes -a --include=cache/ --exclude=something example.com foobar | wc -l` -gt 0', 162 | ) 163 | } 164 | end 165 | 166 | describe 'when enabling purge' do 167 | let :params do 168 | common_params.merge(purge: true) 169 | end 170 | 171 | it { 172 | is_expected.to contain_exec('rsync foobar').with( 173 | command: 'rsync -q -a --delete example.com foobar', 174 | onlyif: 'test `rsync --dry-run --itemize-changes -a --delete example.com foobar | wc -l` -gt 0', 175 | ) 176 | } 177 | end 178 | 179 | describe 'when enabling recursive' do 180 | let :params do 181 | common_params.merge(recursive: true) 182 | end 183 | 184 | it { 185 | is_expected.to contain_exec('rsync foobar').with( 186 | command: 'rsync -q -a -r example.com foobar', 187 | onlyif: 'test `rsync --dry-run --itemize-changes -a -r example.com foobar | wc -l` -gt 0', 188 | ) 189 | } 190 | end 191 | 192 | describe 'when enabling links' do 193 | let :params do 194 | common_params.merge(links: true) 195 | end 196 | 197 | it { 198 | is_expected.to contain_exec('rsync foobar').with( 199 | command: 'rsync -q -a --links example.com foobar', 200 | onlyif: 'test `rsync --dry-run --itemize-changes -a --links example.com foobar | wc -l` -gt 0', 201 | ) 202 | } 203 | end 204 | 205 | describe 'when changing rsync options' do 206 | let :params do 207 | common_params.merge(options: '-rlpcgoD') 208 | end 209 | 210 | it { 211 | is_expected.to contain_exec('rsync foobar').with( 212 | command: 'rsync -q -rlpcgoD example.com foobar', 213 | onlyif: 'test `rsync --dry-run --itemize-changes -rlpcgoD example.com foobar | wc -l` -gt 0', 214 | ) 215 | } 216 | end 217 | 218 | describe 'when enabling hardlinks' do 219 | let :params do 220 | common_params.merge(hardlinks: true) 221 | end 222 | 223 | it { 224 | is_expected.to contain_exec('rsync foobar').with( 225 | command: 'rsync -q -a --hard-links example.com foobar', 226 | onlyif: 'test `rsync --dry-run --itemize-changes -a --hard-links example.com foobar | wc -l` -gt 0', 227 | ) 228 | } 229 | end 230 | 231 | describe 'when enabling copylinks' do 232 | let :params do 233 | common_params.merge(copylinks: true) 234 | end 235 | 236 | it { 237 | is_expected.to contain_exec('rsync foobar').with( 238 | command: 'rsync -q -a --copy-links example.com foobar', 239 | onlyif: 'test `rsync --dry-run --itemize-changes -a --copy-links example.com foobar | wc -l` -gt 0', 240 | ) 241 | } 242 | end 243 | 244 | describe 'when enabling times' do 245 | let :params do 246 | common_params.merge(times: true) 247 | end 248 | 249 | it { 250 | is_expected.to contain_exec('rsync foobar').with( 251 | command: 'rsync -q -a --times example.com foobar', 252 | onlyif: 'test `rsync --dry-run --itemize-changes -a --times example.com foobar | wc -l` -gt 0', 253 | ) 254 | } 255 | end 256 | 257 | describe 'when setting a custom path' do 258 | let :params do 259 | common_params.merge(path: 'barfoo') 260 | end 261 | 262 | it { 263 | is_expected.to contain_exec('rsync foobar').with( 264 | command: 'rsync -q -a example.com barfoo', 265 | onlyif: 'test `rsync --dry-run --itemize-changes -a example.com barfoo | wc -l` -gt 0', 266 | ) 267 | } 268 | end 269 | 270 | describe 'when setting a custom onlyif condition' do 271 | let :params do 272 | common_params.merge(onlyif: 'false') 273 | end 274 | 275 | it { 276 | is_expected.to contain_exec('rsync foobar').with( 277 | command: 'rsync -q -a example.com foobar', 278 | onlyif: 'false', 279 | ) 280 | } 281 | end 282 | 283 | describe 'when setting chown' do 284 | let :params do 285 | common_params.merge(chown: 'user:group') 286 | end 287 | 288 | it { 289 | is_expected.to contain_exec('rsync foobar').with( 290 | command: 'rsync -q -a --chown=user:group example.com foobar', 291 | onlyif: 'test `rsync --dry-run --itemize-changes -a --chown=user:group example.com foobar | wc -l` -gt 0', 292 | ) 293 | } 294 | end 295 | 296 | describe 'when setting chmod' do 297 | let :params do 298 | common_params.merge(chmod: 'Dg-s,u+w,go-w,+X,+x') 299 | end 300 | 301 | it { 302 | is_expected.to contain_exec('rsync foobar').with( 303 | command: 'rsync -q -a --chmod=Dg-s,u+w,go-w,+X,+x example.com foobar', 304 | onlyif: 'test `rsync --dry-run --itemize-changes -a --chmod=Dg-s,u+w,go-w,+X,+x example.com foobar | wc -l` -gt 0', 305 | ) 306 | } 307 | end 308 | 309 | describe 'when setting logfile' do 310 | let :params do 311 | common_params.merge(logfile: '/tmp/logfile.out') 312 | end 313 | 314 | it { 315 | is_expected.to contain_exec('rsync foobar').with( 316 | command: 'rsync -q -a --log-file=/tmp/logfile.out example.com foobar', 317 | onlyif: 'test `rsync --dry-run --itemize-changes -a --log-file=/tmp/logfile.out example.com foobar | wc -l` -gt 0', 318 | ) 319 | } 320 | end 321 | end 322 | -------------------------------------------------------------------------------- /spec/defines/put_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | describe 'rsync::put', type: :define do 3 | let :title do 4 | 'foobar' 5 | end 6 | 7 | let :common_params do 8 | { 9 | source: 'example.com', 10 | } 11 | end 12 | 13 | describe 'when using default class paramaters' do 14 | let :params do 15 | common_params 16 | end 17 | 18 | it { 19 | is_expected.to contain_exec('rsync foobar').with( 20 | command: 'rsync -q -a example.com foobar', 21 | onlyif: 'test `rsync --dry-run --itemize-changes -a example.com foobar | wc -l` -gt 0', 22 | timeout: '900', 23 | ) 24 | } 25 | end 26 | 27 | describe 'when setting the timeout' do 28 | let :params do 29 | common_params.merge(timeout: '200') 30 | end 31 | 32 | it { 33 | is_expected.to contain_exec('rsync foobar').with(timeout: '200') 34 | } 35 | end 36 | 37 | describe 'when setting a user but not a keyfile' do 38 | let :params do 39 | common_params.merge(user: 'mr_baz') 40 | end 41 | 42 | it { 43 | is_expected.to contain_exec('rsync foobar').with( 44 | command: 'rsync -q -a -e \'ssh -i /home/mr_baz/.ssh/id_rsa -l mr_baz\' example.com mr_baz@foobar', 45 | onlyif: 'test `rsync --dry-run --itemize-changes -a -e \'ssh -i /home/mr_baz/.ssh/id_rsa -l mr_baz\' example.com mr_baz@foobar | wc -l` -gt 0', 46 | ) 47 | } 48 | end 49 | 50 | describe 'when setting a keyfile but not a user' do 51 | let :params do 52 | common_params.merge(keyfile: '/path/to/keyfile') 53 | end 54 | 55 | it { 56 | is_expected.to contain_exec('rsync foobar').with( 57 | command: 'rsync -q -a example.com foobar', 58 | onlyif: 'test `rsync --dry-run --itemize-changes -a example.com foobar | wc -l` -gt 0', 59 | ) 60 | } 61 | end 62 | 63 | describe 'when setting a user and a keyfile' do 64 | let :params do 65 | common_params.merge( 66 | user: 'mr_baz', 67 | keyfile: '/path/to/keyfile', 68 | ) 69 | end 70 | 71 | it { 72 | is_expected.to contain_exec('rsync foobar').with( 73 | command: 'rsync -q -a -e \'ssh -i /path/to/keyfile -l mr_baz\' example.com mr_baz@foobar', 74 | onlyif: 'test `rsync --dry-run --itemize-changes -a -e \'ssh -i /path/to/keyfile -l mr_baz\' example.com mr_baz@foobar | wc -l` -gt 0', 75 | ) 76 | } 77 | end 78 | 79 | describe 'when setting an exclude path' do 80 | let :params do 81 | common_params.merge(exclude: '/path/to/exclude/') 82 | end 83 | 84 | it { 85 | is_expected.to contain_exec('rsync foobar').with( 86 | command: 'rsync -q -a --exclude=/path/to/exclude/ example.com foobar', 87 | onlyif: 'test `rsync --dry-run --itemize-changes -a --exclude=/path/to/exclude/ example.com foobar | wc -l` -gt 0', 88 | ) 89 | } 90 | end 91 | 92 | describe 'when setting multiple exclude paths' do 93 | let :params do 94 | common_params.merge(exclude: ['logs/', 'tmp/']) 95 | end 96 | 97 | it { 98 | is_expected.to contain_exec('rsync foobar').with( 99 | command: 'rsync -q -a --exclude=logs/ --exclude=tmp/ example.com foobar', 100 | onlyif: 'test `rsync --dry-run --itemize-changes -a --exclude=logs/ --exclude=tmp/ example.com foobar | wc -l` -gt 0', 101 | ) 102 | } 103 | end 104 | 105 | describe 'when setting an include path' do 106 | let :params do 107 | common_params.merge(include: '/path/to/include/') 108 | end 109 | 110 | it { 111 | is_expected.to contain_exec('rsync foobar').with( 112 | command: 'rsync -q -a --include=/path/to/include/ example.com foobar', 113 | onlyif: 'test `rsync --dry-run --itemize-changes -a --include=/path/to/include/ example.com foobar | wc -l` -gt 0', 114 | ) 115 | } 116 | end 117 | 118 | describe 'when setting multiple include paths' do 119 | let :params do 120 | common_params.merge(include: ['htdocs/', 'cache/']) 121 | end 122 | 123 | it { 124 | is_expected.to contain_exec('rsync foobar').with( 125 | command: 'rsync -q -a --include=htdocs/ --include=cache/ example.com foobar', 126 | onlyif: 'test `rsync --dry-run --itemize-changes -a --include=htdocs/ --include=cache/ example.com foobar | wc -l` -gt 0', 127 | ) 128 | } 129 | end 130 | 131 | describe 'when leaving default exclude and include order (exclude first)' do 132 | let :params do 133 | common_params.merge(include: 'cache/', exclude: 'something') 134 | end 135 | 136 | it { 137 | is_expected.to contain_exec('rsync foobar').with( 138 | command: 'rsync -q -a --exclude=something --include=cache/ example.com foobar', 139 | onlyif: 'test `rsync --dry-run --itemize-changes -a --exclude=something --include=cache/ example.com foobar | wc -l` -gt 0', 140 | ) 141 | } 142 | end 143 | 144 | describe 'when changing the exclude and include order to include first' do 145 | let :params do 146 | common_params.merge(include: 'cache/', exclude: 'something', exclude_first: false) 147 | end 148 | 149 | it { 150 | is_expected.to contain_exec('rsync foobar').with( 151 | command: 'rsync -q -a --include=cache/ --exclude=something example.com foobar', 152 | onlyif: 'test `rsync --dry-run --itemize-changes -a --include=cache/ --exclude=something example.com foobar | wc -l` -gt 0', 153 | ) 154 | } 155 | end 156 | 157 | describe 'when enabling purge' do 158 | let :params do 159 | common_params.merge(purge: true) 160 | end 161 | 162 | it { 163 | is_expected.to contain_exec('rsync foobar').with( 164 | command: 'rsync -q -a --delete example.com foobar', 165 | onlyif: 'test `rsync --dry-run --itemize-changes -a --delete example.com foobar | wc -l` -gt 0', 166 | ) 167 | } 168 | end 169 | 170 | describe 'when changing rsync options' do 171 | let :params do 172 | common_params.merge(options: '-rlpcgoD') 173 | end 174 | 175 | it { 176 | is_expected.to contain_exec('rsync foobar').with( 177 | command: 'rsync -q -rlpcgoD example.com foobar', 178 | onlyif: 'test `rsync --dry-run --itemize-changes -rlpcgoD example.com foobar | wc -l` -gt 0', 179 | ) 180 | } 181 | end 182 | 183 | describe 'when setting a custom path' do 184 | let :params do 185 | common_params.merge(path: 'barfoo') 186 | end 187 | 188 | it { 189 | is_expected.to contain_exec('rsync foobar').with( 190 | command: 'rsync -q -a example.com barfoo', 191 | onlyif: 'test `rsync --dry-run --itemize-changes -a example.com barfoo | wc -l` -gt 0', 192 | ) 193 | } 194 | end 195 | end 196 | -------------------------------------------------------------------------------- /spec/defines/server_module_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'rsync::server::module', type: :define do 4 | on_supported_os.each do |os, facts| 5 | context "on #{os} " do 6 | let :facts do 7 | facts 8 | end 9 | 10 | let :title do 11 | 'foobar' 12 | end 13 | 14 | let :pre_condition do 15 | 'class { "rsync::server": }' 16 | end 17 | 18 | let :fragment_name do 19 | 'frag-foobar' 20 | end 21 | 22 | let :mandatory_params do 23 | { path: '/some/path' } 24 | end 25 | 26 | let :params do 27 | mandatory_params 28 | end 29 | 30 | describe 'when using default class paramaters' do 31 | it { is_expected.to contain_concat__fragment(fragment_name).with_content(%r{^\[ foobar \]$}) } 32 | it { is_expected.to contain_concat__fragment(fragment_name).with_content(%r{^path\s*=\s*/some/path$}) } 33 | it { is_expected.to contain_concat__fragment(fragment_name).with_content(%r{^read only\s*=\s*yes$}) } 34 | it { is_expected.to contain_concat__fragment(fragment_name).with_content(%r{^write only\s*=\s*no$}) } 35 | it { is_expected.to contain_concat__fragment(fragment_name).with_content(%r{^list\s*=\s*yes$}) } 36 | it { is_expected.to contain_concat__fragment(fragment_name).with_content(%r{^max connections\s*=\s*0$}) } 37 | it { is_expected.to contain_concat__fragment(fragment_name).with_content(%r{^timeout\s*=\s*0$}) } 38 | it { is_expected.not_to contain_concat__fragment(fragment_name).with_content(%r{^uid\s*=.*$}) } 39 | it { is_expected.not_to contain_concat__fragment(fragment_name).with_content(%r{^gid\s*=.*$}) } 40 | it { is_expected.not_to contain_concat__fragment(fragment_name).with_content(%r{^incoming chmod\s*=.*$}) } 41 | it { is_expected.not_to contain_concat__fragment(fragment_name).with_content(%r{^outgoing chmod\s*=.*$}) } 42 | it { is_expected.not_to contain_concat__fragment(fragment_name).with_content(%r{^lock file\s*=.*$}) } 43 | it { is_expected.not_to contain_concat__fragment(fragment_name).with_content(%r{^use chroot\s*=\s*yes$}) } 44 | it { is_expected.not_to contain_concat__fragment(fragment_name).with_content(%r{^numeric ids\s*=\s*yes$}) } 45 | it { is_expected.not_to contain_concat__fragment(fragment_name).with_content(%r{^secrets file\s*=.*$}) } 46 | it { is_expected.not_to contain_concat__fragment(fragment_name).with_content(%r{^auth users\s*=.*$}) } 47 | it { is_expected.not_to contain_concat__fragment(fragment_name).with_content(%r{^hosts allow\s*=.*$}) } 48 | it { is_expected.not_to contain_concat__fragment(fragment_name).with_content(%r{^hosts deny\s*=.*$}) } 49 | it { is_expected.not_to contain_concat__fragment(fragment_name).with_content(%r{^transfer logging\s*=.*$}) } 50 | it { is_expected.not_to contain_concat__fragment(fragment_name).with_content(%r{^log format\s*=.*$}) } 51 | it { is_expected.not_to contain_concat__fragment(fragment_name).with_content(%r{^refuse options\s*=.*$}) } 52 | it { is_expected.not_to contain_concat__fragment(fragment_name).with_content(%r{^include\s*=.*$}) } 53 | it { is_expected.not_to contain_concat__fragment(fragment_name).with_content(%r{^include from\s*=.*$}) } 54 | it { is_expected.not_to contain_concat__fragment(fragment_name).with_content(%r{^exclude\s*=.*$}) } 55 | it { is_expected.not_to contain_concat__fragment(fragment_name).with_content(%r{^exclude from\s*=.*$}) } 56 | it { is_expected.not_to contain_concat__fragment(fragment_name).with_content(%r{^dont compress\s*=.*$}) } 57 | end 58 | 59 | describe 'when overriding max connections' do 60 | let :params do 61 | mandatory_params.merge(max_connections: 1) 62 | end 63 | 64 | it { is_expected.to contain_concat__fragment(fragment_name).with_content(%r{^max connections\s*=\s*1$}) } 65 | it { is_expected.to contain_concat__fragment(fragment_name).with_content(%r{^lock file\s*=\s*/var/run/rsyncd\.lock$}) } 66 | end 67 | 68 | describe 'when setting incoming chmod to false' do 69 | let :params do 70 | mandatory_params.merge(incoming_chmod: false, 71 | outgoing_chmod: false) 72 | end 73 | 74 | it { is_expected.not_to contain_file(fragment_name).with_content(%r{^incoming chmod.*$}) } 75 | it { is_expected.not_to contain_file(fragment_name).with_content(%r{^outgoing chmod.*$}) } 76 | end 77 | 78 | { 79 | comment: 'super module !', 80 | read_only: 'no', 81 | write_only: 'yes', 82 | use_chroot: 'no', 83 | list: 'no', 84 | uid: '4682', 85 | gid: '4682', 86 | numeric_ids: 'no', 87 | incoming_chmod: '0777', 88 | outgoing_chmod: '0777', 89 | max_connections: '10', 90 | timeout: '10', 91 | secrets_file: '/path/to/secrets', 92 | hosts_allow: ['localhost', '169.254.42.51'], 93 | hosts_deny: ['some-host.example.com', '10.0.0.128'], 94 | transfer_logging: 'true', 95 | log_format: '%t %a %m %f %b', 96 | refuse_options: ['c', 'delete'], 97 | include: ['a', 'b'], 98 | exclude: ['c', 'd'], 99 | include_from: '/path/to/file', 100 | exclude_from: '/path/to/otherfile', 101 | dont_compress: ['a', 'b'], 102 | ignore_nonreadable: 'yes', 103 | }.each_pair do |k, v| 104 | describe "when overriding #{k}" do 105 | let :params do 106 | mandatory_params.merge(k => v) 107 | end 108 | 109 | it { is_expected.to contain_concat__fragment(fragment_name).with_content(%r{^#{k.to_s.tr('_', ' ')}\s*=\s*#{Array(v).join(' ')}$}) } 110 | end 111 | 112 | describe 'when overriding auth_users' do 113 | let :params do 114 | mandatory_params.merge(auth_users: ['me', 'you', 'them']) 115 | end 116 | 117 | it { is_expected.to contain_concat__fragment(fragment_name).with_content(%r{^auth users\s*=\s*me, you, them$}) } 118 | end 119 | 120 | describe 'when overriding log_file' do 121 | let :params do 122 | mandatory_params.merge(log_file: '/var/log/rsync.log') 123 | end 124 | 125 | it { is_expected.to contain_concat__fragment(fragment_name).with_content(%r{^log file\s*=\s*/var/log/rsync.log$}) } 126 | end 127 | end 128 | end 129 | end 130 | end 131 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.configure do |c| 4 | c.mock_with :rspec 5 | end 6 | 7 | require 'puppetlabs_spec_helper/module_spec_helper' 8 | require 'rspec-puppet-facts' 9 | 10 | require 'spec_helper_local' if File.file?(File.join(File.dirname(__FILE__), 'spec_helper_local.rb')) 11 | 12 | include RspecPuppetFacts 13 | 14 | default_facts = { 15 | puppetversion: Puppet.version, 16 | facterversion: Facter.version, 17 | } 18 | 19 | default_fact_files = [ 20 | File.expand_path(File.join(File.dirname(__FILE__), 'default_facts.yml')), 21 | File.expand_path(File.join(File.dirname(__FILE__), 'default_module_facts.yml')), 22 | ] 23 | 24 | default_fact_files.each do |f| 25 | next unless File.exist?(f) && File.readable?(f) && File.size?(f) 26 | 27 | begin 28 | default_facts.merge!(YAML.safe_load(File.read(f), permitted_classes: [], permitted_symbols: [], aliases: true)) 29 | rescue StandardError => e 30 | RSpec.configuration.reporter.message "WARNING: Unable to load #{f}: #{e}" 31 | end 32 | end 33 | 34 | # read default_facts and merge them over what is provided by facterdb 35 | default_facts.each do |fact, value| 36 | add_custom_fact fact, value 37 | end 38 | 39 | RSpec.configure do |c| 40 | c.default_facts = default_facts 41 | c.before :each do 42 | # set to strictest setting for testing 43 | # by default Puppet runs at warning level 44 | Puppet.settings[:strict] = :warning 45 | Puppet.settings[:strict_variables] = true 46 | end 47 | c.filter_run_excluding(bolt: true) unless ENV['GEM_BOLT'] 48 | c.after(:suite) do 49 | RSpec::Puppet::Coverage.report!(0) 50 | end 51 | 52 | # Filter backtrace noise 53 | backtrace_exclusion_patterns = [ 54 | %r{spec_helper}, 55 | %r{gems}, 56 | ] 57 | 58 | if c.respond_to?(:backtrace_exclusion_patterns) 59 | c.backtrace_exclusion_patterns = backtrace_exclusion_patterns 60 | elsif c.respond_to?(:backtrace_clean_patterns) 61 | c.backtrace_clean_patterns = backtrace_exclusion_patterns 62 | end 63 | end 64 | 65 | # Ensures that a module is defined 66 | # @param module_name Name of the module 67 | def ensure_module_defined(module_name) 68 | module_name.split('::').reduce(Object) do |last_module, next_module| 69 | last_module.const_set(next_module, Module.new) unless last_module.const_defined?(next_module, false) 70 | last_module.const_get(next_module, false) 71 | end 72 | end 73 | 74 | # 'spec_overrides' from sync.yml will appear below this line 75 | -------------------------------------------------------------------------------- /templates/header.erb: -------------------------------------------------------------------------------- 1 | # This file is being maintained by Puppet. 2 | # DO NOT EDIT 3 | 4 | <% if @pid_file != 'UNSET' -%> 5 | pid file = <%= @pid_file %> 6 | <% end -%> 7 | uid = <%= @uid %> 8 | gid = <%= @gid %> 9 | use chroot = <%= @use_chroot %> 10 | log format = %t %a %m %f %b 11 | syslog facility = local3 12 | timeout = 300 13 | address = <%= @address %> 14 | <% if @motd_file != 'UNSET' -%> 15 | motd file = <%= @motd_file %> 16 | <% end -%> 17 | -------------------------------------------------------------------------------- /templates/module.erb: -------------------------------------------------------------------------------- 1 | [ <%= @name %> ] 2 | path = <%= @path %> 3 | read only = <%= @read_only %> 4 | write only = <%= @write_only %> 5 | list = <%= @list %> 6 | <% if @uid -%> 7 | uid = <%= @uid %> 8 | <% end -%> 9 | <% if @gid -%> 10 | gid = <%= @gid %> 11 | <% end -%> 12 | <% if @numeric_ids -%> 13 | numeric ids = <%= @numeric_ids %> 14 | <% end -%> 15 | <% if @use_chroot -%> 16 | use chroot = <%= @use_chroot %> 17 | <% end -%> 18 | <% if @incoming_chmod -%> 19 | incoming chmod = <%= @incoming_chmod %> 20 | <% end -%> 21 | <% if @outgoing_chmod -%> 22 | outgoing chmod = <%= @outgoing_chmod %> 23 | <% end -%> 24 | <% if @max_connections -%> 25 | max connections = <%= @max_connections %> 26 | <% end -%> 27 | <% if @timeout -%> 28 | timeout = <%= @timeout %> 29 | <% end -%> 30 | <% if Integer(@max_connections) > 0 -%> 31 | lock file = <%= @lock_file %> 32 | <% end -%> 33 | <% if @comment -%> 34 | comment = <%= @comment %> 35 | <% end -%> 36 | <% if @secrets_file -%> 37 | secrets file = <%= @secrets_file %> 38 | <% end -%> 39 | <% if @auth_users -%> 40 | auth users = <%= Array(@auth_users).join(', ')%> 41 | <% end -%> 42 | <% if @hosts_allow -%> 43 | hosts allow = <%= Array(@hosts_allow).join(' ')%> 44 | <% end -%> 45 | <% if @hosts_deny -%> 46 | hosts deny = <%= Array(@hosts_deny).join(' ')%> 47 | <% end -%> 48 | <% if @transfer_logging -%> 49 | transfer logging = <%= @transfer_logging %> 50 | <% end -%> 51 | <% if @log_format -%> 52 | log format = <%= @log_format %> 53 | <% end -%> 54 | <% if @refuse_options -%> 55 | refuse options = <%= Array(@refuse_options).join(' ')%> 56 | <% end -%> 57 | <% if @ignore_nonreadable -%> 58 | ignore nonreadable = <%= @ignore_nonreadable %> 59 | <% end -%> 60 | <% if @log_file -%> 61 | log file = <%= @log_file %> 62 | <% end -%> 63 | <% if @include -%> 64 | include = <%= Array(@include).join(' ')%> 65 | <% end -%> 66 | <% if @include_from -%> 67 | include from = <%= @include_from%> 68 | <% end -%> 69 | <% if @exclude -%> 70 | exclude = <%= Array(@exclude).join(' ')%> 71 | <% end -%> 72 | <% if @exclude_from -%> 73 | exclude from = <%= @exclude_from%> 74 | <% end -%> 75 | <% if @dont_compress -%> 76 | dont compress = <%= Array(@dont_compress).join(' ')%> 77 | <% end -%> 78 | --------------------------------------------------------------------------------