diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 000000000..12ed4ff10 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,6 @@ +FROM puppet/pdk:latest + +# [Optional] Uncomment this section to install additional packages. +# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ +# && apt-get -y install --no-install-recommends + diff --git a/.devcontainer/README.md b/.devcontainer/README.md new file mode 100644 index 000000000..a71936168 --- /dev/null +++ b/.devcontainer/README.md @@ -0,0 +1,38 @@ +# devcontainer + + +For format details, see https://aka.ms/devcontainer.json. + +For config options, see the README at: +https://github.com/microsoft/vscode-dev-containers/tree/v0.140.1/containers/puppet + +``` json +{ + "name": "Puppet Development Kit (Community)", + "dockerFile": "Dockerfile", + + // Set *default* container specific settings.json values on container create. + "settings": { + "terminal.integrated.profiles.linux": { + "bash": { + "path": "bash", + } + } + }, + + // Add the IDs of extensions you want installed when the container is created. + "extensions": [ + "puppet.puppet-vscode", + "rebornix.Ruby" + ], + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + "forwardPorts": [], + + // Use 'postCreateCommand' to run commands after the container is created. + "postCreateCommand": "pdk --version", +} +``` + + + diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000..cdd65d220 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,17 @@ +{ + "name": "Puppet Development Kit (Community)", + "dockerFile": "Dockerfile", + + "settings": { + "terminal.integrated.profiles.linux": { + "bash": { + "path": "bash" + } + } + }, + + "extensions": [ + "puppet.puppet-vscode", + "rebornix.Ruby" + ] +} diff --git a/.fixtures.yml b/.fixtures.yml index 37b737752..b25e8c459 100644 --- a/.fixtures.yml +++ b/.fixtures.yml @@ -1,3 +1,8 @@ fixtures: + repositories: + facts: 'https://github.com/puppetlabs/puppetlabs-facts.git' + puppet_agent: 'https://github.com/puppetlabs/puppetlabs-puppet_agent.git' + provision: 'https://github.com/puppetlabs/provision.git' symlinks: stdlib: "#{source_dir}" + test: "#{source_dir}/spec/fixtures/test" \ No newline at end of file diff --git a/.gemspec b/.gemspec deleted file mode 100644 index e27495093..000000000 --- a/.gemspec +++ /dev/null @@ -1,40 +0,0 @@ -# -# -*- encoding: utf-8 -*- - -Gem::Specification.new do |s| - s.name = "puppetmodule-stdlib" - - s.version = "4.0.2" - - s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= - s.authors = ["Puppet Labs"] - s.date = "2013-04-12" - s.description = [ 'This Gem format of the stdlib module is intended to make', - 'it easier for _module authors_ to resolve dependencies', - 'using a Gemfile when running automated testing jobs like', - 'Travis or Jenkins. The recommended best practice for', - 'installation by end users is to use the `puppet module', - 'install` command to install stdlib from the [Puppet', - 'Forge](http://forge.puppetlabs.com/puppetlabs/stdlib).' ].join(' ') - s.email = "puppet-dev@puppetlabs.com" - s.executables = [] - s.files = [ 'CHANGELOG', 'CONTRIBUTING.md', 'Gemfile', 'LICENSE', 'Modulefile', - 'README.markdown', 'README_DEVELOPER.markdown', 'RELEASE_PROCESS.markdown', - 'Rakefile', 'spec/spec.opts' ] - s.files += Dir['lib/**/*.rb'] + Dir['manifests/**/*.pp'] + Dir['tests/**/*.pp'] + Dir['spec/**/*.rb'] - s.homepage = "http://forge.puppetlabs.com/puppetlabs/stdlib" - s.rdoc_options = ["--title", "Puppet Standard Library Development Gem", "--main", "README.markdown", "--line-numbers"] - s.require_paths = ["lib"] - s.rubyforge_project = "puppetmodule-stdlib" - s.rubygems_version = "1.8.24" - s.summary = "This gem provides a way to make the standard library available for other module spec testing tasks." - - if s.respond_to? :specification_version then - s.specification_version = 3 - - if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then - else - end - else - end -end diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..9032a014a --- /dev/null +++ b/.gitattributes @@ -0,0 +1,5 @@ +*.rb eol=lf +*.erb eol=lf +*.pp eol=lf +*.sh eol=lf +*.epp eol=lf diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 000000000..e3a97007e --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,15 @@ +## Summary +Provide a detailed description of all the changes present in this pull request. + +## Additional Context +Add any additional context about the problem here. +- [ ] Root cause and the steps to reproduce. (If applicable) +- [ ] Thought process behind the implementation. + +## Related Issues (if any) +Mention any related issues or pull requests. + +## Checklist +- [ ] 🟢 Spec tests. +- [ ] 🟢 Acceptance tests. +- [ ] Manually verified. (For example `puppet apply`) \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..2cdfc30f1 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,19 @@ +name: "ci" + +on: + pull_request: + branches: + - "main" + workflow_dispatch: + +jobs: + Spec: + uses: "puppetlabs/cat-github-actions/.github/workflows/module_ci.yml@main" + secrets: "inherit" + + Acceptance: + needs: Spec + uses: "puppetlabs/cat-github-actions/.github/workflows/module_acceptance.yml@main" + with: + flags: "--nightly" + secrets: "inherit" diff --git a/.github/workflows/mend.yml b/.github/workflows/mend.yml new file mode 100644 index 000000000..b4100a5af --- /dev/null +++ b/.github/workflows/mend.yml @@ -0,0 +1,15 @@ +name: "mend" + +on: + pull_request: + branches: + - "main" + schedule: + - cron: "0 0 * * *" + workflow_dispatch: + +jobs: + + mend: + uses: "puppetlabs/cat-github-actions/.github/workflows/mend_ruby.yml@main" + secrets: "inherit" diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml new file mode 100644 index 000000000..5a39a47c7 --- /dev/null +++ b/.github/workflows/nightly.yml @@ -0,0 +1,18 @@ +name: "nightly" + +on: + schedule: + - cron: "0 0 * * *" + workflow_dispatch: + +jobs: + Spec: + uses: "puppetlabs/cat-github-actions/.github/workflows/module_ci.yml@main" + secrets: "inherit" + + Acceptance: + needs: Spec + uses: "puppetlabs/cat-github-actions/.github/workflows/module_acceptance.yml@main" + with: + flags: "--nightly" + secrets: "inherit" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..4b3b80fc8 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,9 @@ +name: "Publish module" + +on: + workflow_dispatch: + +jobs: + release: + uses: "puppetlabs/cat-github-actions/.github/workflows/module_release.yml@main" + secrets: "inherit" diff --git a/.github/workflows/release_prep.yml b/.github/workflows/release_prep.yml new file mode 100644 index 000000000..bb0b7acce --- /dev/null +++ b/.github/workflows/release_prep.yml @@ -0,0 +1,15 @@ +name: "Release Prep" + +on: + workflow_dispatch: + inputs: + version: + description: "Module version to be released. Must be a valid semver string. (1.2.3)" + required: true + +jobs: + release_prep: + uses: "puppetlabs/cat-github-actions/.github/workflows/module_release_prep.yml@main" + with: + version: "${{ github.event.inputs.version }}" + secrets: "inherit" diff --git a/.gitignore b/.gitignore index 37c4f5968..2803e566b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,35 @@ -/pkg/ -/Gemfile.lock -/vendor/ -/spec/fixtures/manifests/* -/spec/fixtures/modules/* -!/spec/fixtures/modules/stdlib -!/spec/fixtures/modules/stdlib/* -/.vagrant/ +.git/ +.*.sw[op] +.metadata +.yardoc +.yardwarns +*.iml /.bundle/ -/coverage/ /.idea/ -*.iml +/.vagrant/ +/coverage/ +/bin/ +/doc/ +/Gemfile.local +/Gemfile.lock +/junit/ +/log/ +/pkg/ +/spec/fixtures/manifests/ +/spec/fixtures/modules/* +/tmp/ +/vendor/ +/.vendor/ +/convert_report.txt +/update_report.txt +.DS_Store +.project +.envrc +/inventory.yaml +/spec/fixtures/litmus_inventory.yaml +.resource_types +.modules +.task_cache.json +.plan_cache.json +.rerun.json +bolt-debug.log diff --git a/.gitpod.Dockerfile b/.gitpod.Dockerfile new file mode 100644 index 000000000..0814c5e61 --- /dev/null +++ b/.gitpod.Dockerfile @@ -0,0 +1,18 @@ +FROM gitpod/workspace-full +RUN sudo wget https://apt.puppet.com/puppet-tools-release-bionic.deb && \ + wget https://apt.puppetlabs.com/puppet6-release-bionic.deb && \ + sudo dpkg -i puppet6-release-bionic.deb && \ + sudo dpkg -i puppet-tools-release-bionic.deb && \ + sudo apt-get update && \ + sudo apt-get install -y pdk zsh puppet-agent && \ + sudo apt-get clean && \ + sudo rm -rf /var/lib/apt/lists/* +RUN sudo usermod -s $(which zsh) gitpod && \ + sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" && \ + echo "plugins=(git gitignore github gem pip bundler python ruby docker docker-compose)" >> /home/gitpod/.zshrc && \ + echo 'PATH="$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/opt/puppetlabs/bin:/opt/puppetlabs/puppet/bin"' >> /home/gitpod/.zshrc && \ + sudo /opt/puppetlabs/puppet/bin/gem install puppet-debugger hub -N && \ + mkdir -p /home/gitpod/.config/puppet && \ + /opt/puppetlabs/puppet/bin/ruby -r yaml -e "puts ({'disabled' => true}).to_yaml" > /home/gitpod/.config/puppet/analytics.yml +RUN rm -f puppet6-release-bionic.deb puppet-tools-release-bionic.deb +ENTRYPOINT /usr/bin/zsh diff --git a/.gitpod.yml b/.gitpod.yml new file mode 100644 index 000000000..9d89d9faa --- /dev/null +++ b/.gitpod.yml @@ -0,0 +1,9 @@ +image: + file: .gitpod.Dockerfile + +tasks: + - init: pdk bundle install + +vscode: + extensions: + - puppet.puppet-vscode@1.2.0:f5iEPbmOj6FoFTOV6q8LTg== diff --git a/.pdkignore b/.pdkignore new file mode 100644 index 000000000..84684be63 --- /dev/null +++ b/.pdkignore @@ -0,0 +1,51 @@ +.git/ +.*.sw[op] +.metadata +.yardoc +.yardwarns +*.iml +/.bundle/ +/.idea/ +/.vagrant/ +/coverage/ +/bin/ +/doc/ +/Gemfile.local +/Gemfile.lock +/junit/ +/log/ +/pkg/ +/spec/fixtures/manifests/ +/spec/fixtures/modules/* +/tmp/ +/vendor/ +/.vendor/ +/convert_report.txt +/update_report.txt +.DS_Store +.project +.envrc +/inventory.yaml +/spec/fixtures/litmus_inventory.yaml +.resource_types +.modules +.task_cache.json +.plan_cache.json +.rerun.json +bolt-debug.log +/.fixtures.yml +/Gemfile +/.gitattributes +/.github/ +/.gitignore +/.pdkignore +/.puppet-lint.rc +/Rakefile +/rakelib/ +/.rspec +/..yml +/.yardopts +/spec/ +/.vscode/ +/.sync.yml +/.devcontainer/ diff --git a/.project b/.project deleted file mode 100644 index 4e2c033ac..000000000 --- a/.project +++ /dev/null @@ -1,23 +0,0 @@ - - - stdlib - - - - - - org.cloudsmith.geppetto.pp.dsl.ui.modulefileBuilder - - - - - org.eclipse.xtext.ui.shared.xtextBuilder - - - - - - org.cloudsmith.geppetto.pp.dsl.ui.puppetNature - org.eclipse.xtext.ui.shared.xtextNature - - diff --git a/.puppet-lint.rc b/.puppet-lint.rc new file mode 100644 index 000000000..9e15c6e01 --- /dev/null +++ b/.puppet-lint.rc @@ -0,0 +1,9 @@ +--fail-on-warnings +--relative +--no-80chars-check +--no-140chars-check +--no-class_inherits_from_params_class-check +--no-autoloader_layout-check +--no-documentation-check +--no-single_quote_string_with_variables-check +--ignore-paths=.vendor/**/*.pp,.bundle/**/*.pp,pkg/**/*.pp,spec/**/*.pp,tests/**/*.pp,types/**/*.pp,vendor/**/*.pp diff --git a/.rspec b/.rspec index 7ab5f55c5..16f9cdb01 100644 --- a/.rspec +++ b/.rspec @@ -1,4 +1,2 @@ --color ---format -progress ---backtrace +--format documentation diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 000000000..47b1aadbe --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,731 @@ +--- +require: +- rubocop-performance +- rubocop-rspec +AllCops: + NewCops: enable + DisplayCopNames: true + TargetRubyVersion: 3.1 + Include: + - "**/*.rb" + Exclude: + - bin/* + - ".vendor/**/*" + - "**/Gemfile" + - "**/Rakefile" + - pkg/**/* + - spec/fixtures/**/* + - vendor/**/* + - "**/Puppetfile" + - "**/Vagrantfile" + - "**/Guardfile" +inherit_from: ".rubocop_todo.yml" +Layout/LineLength: + Description: People have wide screens, use them. + Max: 200 +RSpec/BeforeAfterAll: + Description: Beware of using after(:all) as it may cause state to leak between tests. + A necessary evil in acceptance testing. + Exclude: + - spec/acceptance/**/*.rb +RSpec/HookArgument: + Description: Prefer explicit :each argument, matching existing module's style + EnforcedStyle: each +RSpec/DescribeSymbol: + Exclude: + - spec/unit/facter/**/*.rb +Style/BlockDelimiters: + Description: Prefer braces for chaining. Mostly an aesthetical choice. Better to + be consistent then. + EnforcedStyle: braces_for_chaining +Style/ClassAndModuleChildren: + Description: Compact style reduces the required amount of indentation. + EnforcedStyle: compact +Style/EmptyElse: + Description: Enforce against empty else clauses, but allow `nil` for clarity. + EnforcedStyle: empty +Style/FormatString: + Description: Following the main puppet project's style, prefer the % format format. + EnforcedStyle: percent +Style/FormatStringToken: + Description: Following the main puppet project's style, prefer the simpler template + tokens over annotated ones. + EnforcedStyle: template +Style/Lambda: + Description: Prefer the keyword for easier discoverability. + EnforcedStyle: literal +Style/RegexpLiteral: + Description: Community preference. See https://github.com/voxpupuli/modulesync_config/issues/168 + EnforcedStyle: percent_r +Style/TernaryParentheses: + Description: Checks for use of parentheses around ternary conditions. Enforce parentheses + on complex expressions for better readability, but seriously consider breaking + it up. + EnforcedStyle: require_parentheses_when_complex +Style/TrailingCommaInArguments: + Description: Prefer always trailing comma on multiline argument lists. This makes + diffs, and re-ordering nicer. + EnforcedStyleForMultiline: comma +Style/TrailingCommaInArrayLiteral: + Description: Prefer always trailing comma on multiline literals. This makes diffs, + and re-ordering nicer. + EnforcedStyleForMultiline: comma +Style/SymbolArray: + Description: Using percent style obscures symbolic intent of array's contents. + EnforcedStyle: brackets +RSpec/MessageSpies: + EnforcedStyle: receive +Style/Documentation: + Exclude: + - lib/puppet/parser/functions/**/* + - spec/**/* +Style/WordArray: + EnforcedStyle: brackets +Performance/AncestorsInclude: + Enabled: true +Performance/BigDecimalWithNumericArgument: + Enabled: true +Performance/BlockGivenWithExplicitBlock: + Enabled: true +Performance/CaseWhenSplat: + Enabled: true +Performance/ConstantRegexp: + Enabled: true +Performance/MethodObjectAsBlock: + Enabled: true +Performance/RedundantSortBlock: + Enabled: true +Performance/RedundantStringChars: + Enabled: true +Performance/ReverseFirst: + Enabled: true +Performance/SortReverse: + Enabled: true +Performance/Squeeze: + Enabled: true +Performance/StringInclude: + Enabled: true +Performance/Sum: + Enabled: true +Style/CollectionMethods: + Enabled: true +Style/MethodCalledOnDoEndBlock: + Enabled: true +Style/StringMethods: + Enabled: true +Bundler/GemFilename: + Enabled: false +Bundler/InsecureProtocolSource: + Enabled: false +Capybara/CurrentPathExpectation: + Enabled: false +Capybara/VisibilityMatcher: + Enabled: false +Gemspec/DuplicatedAssignment: + Enabled: false +Gemspec/OrderedDependencies: + Enabled: false +Gemspec/RequiredRubyVersion: + Enabled: false +Gemspec/RubyVersionGlobalsUsage: + Enabled: false +Layout/ArgumentAlignment: + Enabled: false +Layout/BeginEndAlignment: + Enabled: false +Layout/ClosingHeredocIndentation: + Enabled: false +Layout/EmptyComment: + Enabled: false +Layout/EmptyLineAfterGuardClause: + Enabled: false +Layout/EmptyLinesAroundArguments: + Enabled: false +Layout/EmptyLinesAroundAttributeAccessor: + Enabled: false +Layout/EndOfLine: + Enabled: false +Layout/FirstArgumentIndentation: + Enabled: false +Layout/HashAlignment: + Enabled: false +Layout/HeredocIndentation: + Enabled: false +Layout/LeadingEmptyLines: + Enabled: false +Layout/SpaceAroundMethodCallOperator: + Enabled: false +Layout/SpaceInsideArrayLiteralBrackets: + Enabled: false +Layout/SpaceInsideReferenceBrackets: + Enabled: false +Lint/BigDecimalNew: + Enabled: false +Lint/BooleanSymbol: + Enabled: false +Lint/ConstantDefinitionInBlock: + Enabled: false +Lint/DeprecatedOpenSSLConstant: + Enabled: false +Lint/DisjunctiveAssignmentInConstructor: + Enabled: false +Lint/DuplicateElsifCondition: + Enabled: false +Lint/DuplicateRequire: + Enabled: false +Lint/DuplicateRescueException: + Enabled: false +Lint/EmptyConditionalBody: + Enabled: false +Lint/EmptyFile: + Enabled: false +Lint/ErbNewArguments: + Enabled: false +Lint/FloatComparison: + Enabled: false +Lint/HashCompareByIdentity: + Enabled: false +Lint/IdentityComparison: + Enabled: false +Lint/InterpolationCheck: + Enabled: false +Lint/MissingCopEnableDirective: + Enabled: false +Lint/MixedRegexpCaptureTypes: + Enabled: false +Lint/NestedPercentLiteral: + Enabled: false +Lint/NonDeterministicRequireOrder: + Enabled: false +Lint/OrderedMagicComments: + Enabled: false +Lint/OutOfRangeRegexpRef: + Enabled: false +Lint/RaiseException: + Enabled: false +Lint/RedundantCopEnableDirective: + Enabled: false +Lint/RedundantRequireStatement: + Enabled: false +Lint/RedundantSafeNavigation: + Enabled: false +Lint/RedundantWithIndex: + Enabled: false +Lint/RedundantWithObject: + Enabled: false +Lint/RegexpAsCondition: + Enabled: false +Lint/ReturnInVoidContext: + Enabled: false +Lint/SafeNavigationConsistency: + Enabled: false +Lint/SafeNavigationWithEmpty: + Enabled: false +Lint/SelfAssignment: + Enabled: false +Lint/SendWithMixinArgument: + Enabled: false +Lint/ShadowedArgument: + Enabled: false +Lint/StructNewOverride: + Enabled: false +Lint/ToJSON: + Enabled: false +Lint/TopLevelReturnWithArgument: + Enabled: false +Lint/TrailingCommaInAttributeDeclaration: + Enabled: false +Lint/UnreachableLoop: + Enabled: false +Lint/UriEscapeUnescape: + Enabled: false +Lint/UriRegexp: + Enabled: false +Lint/UselessMethodDefinition: + Enabled: false +Lint/UselessTimes: + Enabled: false +Metrics/AbcSize: + Enabled: false +Metrics/BlockLength: + Enabled: false +Metrics/BlockNesting: + Enabled: false +Metrics/ClassLength: + Enabled: false +Metrics/CyclomaticComplexity: + Enabled: false +Metrics/MethodLength: + Enabled: false +Metrics/ModuleLength: + Enabled: false +Metrics/ParameterLists: + Enabled: false +Metrics/PerceivedComplexity: + Enabled: false +Migration/DepartmentName: + Enabled: false +Naming/AccessorMethodName: + Enabled: false +Naming/BlockParameterName: + Enabled: false +Naming/HeredocDelimiterCase: + Enabled: false +Naming/HeredocDelimiterNaming: + Enabled: false +Naming/MemoizedInstanceVariableName: + Enabled: false +Naming/MethodParameterName: + Enabled: false +Naming/RescuedExceptionsVariableName: + Enabled: false +Naming/VariableNumber: + Enabled: false +Performance/BindCall: + Enabled: false +Performance/DeletePrefix: + Enabled: false +Performance/DeleteSuffix: + Enabled: false +Performance/InefficientHashSearch: + Enabled: false +Performance/UnfreezeString: + Enabled: false +Performance/UriDefaultParser: + Enabled: false +RSpec/Be: + Enabled: false +RSpec/Capybara/FeatureMethods: + Enabled: false +RSpec/ContainExactly: + Enabled: false +RSpec/ContextMethod: + Enabled: false +RSpec/ContextWording: + Enabled: false +RSpec/DescribeClass: + Enabled: false +RSpec/EmptyHook: + Enabled: false +RSpec/EmptyLineAfterExample: + Enabled: false +RSpec/EmptyLineAfterExampleGroup: + Enabled: false +RSpec/EmptyLineAfterHook: + Enabled: false +RSpec/ExampleLength: + Enabled: false +RSpec/ExampleWithoutDescription: + Enabled: false +RSpec/ExpectChange: + Enabled: false +RSpec/ExpectInHook: + Enabled: false +RSpec/FactoryBot/AttributeDefinedStatically: + Enabled: false +RSpec/FactoryBot/CreateList: + Enabled: false +RSpec/FactoryBot/FactoryClassName: + Enabled: false +RSpec/HooksBeforeExamples: + Enabled: false +RSpec/ImplicitBlockExpectation: + Enabled: false +RSpec/ImplicitSubject: + Enabled: false +RSpec/LeakyConstantDeclaration: + Enabled: false +RSpec/LetBeforeExamples: + Enabled: false +RSpec/MatchArray: + Enabled: false +RSpec/MissingExampleGroupArgument: + Enabled: false +RSpec/MultipleExpectations: + Enabled: false +RSpec/MultipleMemoizedHelpers: + Enabled: false +RSpec/MultipleSubjects: + Enabled: false +RSpec/NestedGroups: + Enabled: false +RSpec/PredicateMatcher: + Enabled: false +RSpec/ReceiveCounts: + Enabled: false +RSpec/ReceiveNever: + Enabled: false +RSpec/RepeatedExampleGroupBody: + Enabled: false +RSpec/RepeatedExampleGroupDescription: + Enabled: false +RSpec/RepeatedIncludeExample: + Enabled: false +RSpec/ReturnFromStub: + Enabled: false +RSpec/SharedExamples: + Enabled: false +RSpec/StubbedMock: + Enabled: false +RSpec/UnspecifiedException: + Enabled: false +RSpec/VariableDefinition: + Enabled: false +RSpec/VoidExpect: + Enabled: false +RSpec/Yield: + Enabled: false +Security/Open: + Enabled: false +Style/AccessModifierDeclarations: + Enabled: false +Style/AccessorGrouping: + Enabled: false +Style/BisectedAttrAccessor: + Enabled: false +Style/CaseLikeIf: + Enabled: false +Style/ClassEqualityComparison: + Enabled: false +Style/ColonMethodDefinition: + Enabled: false +Style/CombinableLoops: + Enabled: false +Style/CommentedKeyword: + Enabled: false +Style/Dir: + Enabled: false +Style/DoubleCopDisableDirective: + Enabled: false +Style/EmptyBlockParameter: + Enabled: false +Style/EmptyLambdaParameter: + Enabled: false +Style/Encoding: + Enabled: false +Style/EvalWithLocation: + Enabled: false +Style/ExpandPathArguments: + Enabled: false +Style/ExplicitBlockArgument: + Enabled: false +Style/ExponentialNotation: + Enabled: false +Style/FloatDivision: + Enabled: false +Style/FrozenStringLiteralComment: + Enabled: false +Style/GlobalStdStream: + Enabled: false +Style/HashAsLastArrayItem: + Enabled: false +Style/HashLikeCase: + Enabled: false +Style/HashTransformKeys: + Enabled: false +Style/HashTransformValues: + Enabled: false +Style/IfUnlessModifier: + Enabled: false +Style/KeywordParametersOrder: + Enabled: false +Style/MinMax: + Enabled: false +Style/MixinUsage: + Enabled: false +Style/MultilineWhenThen: + Enabled: false +Style/NegatedUnless: + Enabled: false +Style/NumericPredicate: + Enabled: false +Style/OptionalBooleanParameter: + Enabled: false +Style/OrAssignment: + Enabled: false +Style/RandomWithOffset: + Enabled: false +Style/RedundantAssignment: + Enabled: false +Style/RedundantCondition: + Enabled: false +Style/RedundantConditional: + Enabled: false +Style/RedundantFetchBlock: + Enabled: false +Style/RedundantFileExtensionInRequire: + Enabled: false +Style/RedundantRegexpCharacterClass: + Enabled: false +Style/RedundantRegexpEscape: + Enabled: false +Style/RedundantSelfAssignment: + Enabled: false +Style/RedundantSort: + Enabled: false +Style/RescueStandardError: + Enabled: false +Style/SingleArgumentDig: + Enabled: false +Style/SlicingWithRange: + Enabled: false +Style/SoleNestedConditional: + Enabled: false +Style/StderrPuts: + Enabled: false +Style/StringConcatenation: + Enabled: false +Style/Strip: + Enabled: false +Style/SymbolProc: + Enabled: false +Style/TrailingBodyOnClass: + Enabled: false +Style/TrailingBodyOnMethodDefinition: + Enabled: false +Style/TrailingBodyOnModule: + Enabled: false +Style/TrailingCommaInHashLiteral: + Enabled: false +Style/TrailingMethodEndStatement: + Enabled: false +Style/UnpackFirst: + Enabled: false +Capybara/MatchStyle: + Enabled: false +Capybara/NegationMatcher: + Enabled: false +Capybara/SpecificActions: + Enabled: false +Capybara/SpecificFinders: + Enabled: false +Capybara/SpecificMatcher: + Enabled: false +Gemspec/DeprecatedAttributeAssignment: + Enabled: false +Gemspec/DevelopmentDependencies: + Enabled: false +Gemspec/RequireMFA: + Enabled: false +Layout/LineContinuationLeadingSpace: + Enabled: false +Layout/LineContinuationSpacing: + Enabled: false +Layout/LineEndStringConcatenationIndentation: + Enabled: false +Layout/SpaceBeforeBrackets: + Enabled: false +Lint/AmbiguousAssignment: + Enabled: false +Lint/AmbiguousOperatorPrecedence: + Enabled: false +Lint/AmbiguousRange: + Enabled: false +Lint/ConstantOverwrittenInRescue: + Enabled: false +Lint/DeprecatedConstants: + Enabled: false +Lint/DuplicateBranch: + Enabled: false +Lint/DuplicateMagicComment: + Enabled: false +Lint/DuplicateMatchPattern: + Enabled: false +Lint/DuplicateRegexpCharacterClassElement: + Enabled: false +Lint/EmptyBlock: + Enabled: false +Lint/EmptyClass: + Enabled: false +Lint/EmptyInPattern: + Enabled: false +Lint/IncompatibleIoSelectWithFiberScheduler: + Enabled: false +Lint/LambdaWithoutLiteralBlock: + Enabled: false +Lint/NoReturnInBeginEndBlocks: + Enabled: false +Lint/NonAtomicFileOperation: + Enabled: false +Lint/NumberedParameterAssignment: + Enabled: false +Lint/OrAssignmentToConstant: + Enabled: false +Lint/RedundantDirGlobSort: + Enabled: false +Lint/RefinementImportMethods: + Enabled: false +Lint/RequireRangeParentheses: + Enabled: false +Lint/RequireRelativeSelfPath: + Enabled: false +Lint/SymbolConversion: + Enabled: false +Lint/ToEnumArguments: + Enabled: false +Lint/TripleQuotes: + Enabled: false +Lint/UnexpectedBlockArity: + Enabled: false +Lint/UnmodifiedReduceAccumulator: + Enabled: false +Lint/UselessRescue: + Enabled: false +Lint/UselessRuby2Keywords: + Enabled: false +Metrics/CollectionLiteralLength: + Enabled: false +Naming/BlockForwarding: + Enabled: false +Performance/CollectionLiteralInLoop: + Enabled: false +Performance/ConcurrentMonotonicTime: + Enabled: false +Performance/MapCompact: + Enabled: false +Performance/RedundantEqualityComparisonBlock: + Enabled: false +Performance/RedundantSplitRegexpArgument: + Enabled: false +Performance/StringIdentifierArgument: + Enabled: false +RSpec/BeEq: + Enabled: false +RSpec/BeNil: + Enabled: false +RSpec/ChangeByZero: + Enabled: false +RSpec/ClassCheck: + Enabled: false +RSpec/DuplicatedMetadata: + Enabled: false +RSpec/ExcessiveDocstringSpacing: + Enabled: false +RSpec/FactoryBot/ConsistentParenthesesStyle: + Enabled: false +RSpec/FactoryBot/FactoryNameStyle: + Enabled: false +RSpec/FactoryBot/SyntaxMethods: + Enabled: false +RSpec/IdenticalEqualityAssertion: + Enabled: false +RSpec/NoExpectationExample: + Enabled: false +RSpec/PendingWithoutReason: + Enabled: false +RSpec/Rails/AvoidSetupHook: + Enabled: false +RSpec/Rails/HaveHttpStatus: + Enabled: false +RSpec/Rails/InferredSpecType: + Enabled: false +RSpec/Rails/MinitestAssertions: + Enabled: false +RSpec/Rails/TravelAround: + Enabled: false +RSpec/RedundantAround: + Enabled: false +RSpec/SkipBlockInsideExample: + Enabled: false +RSpec/SortMetadata: + Enabled: false +RSpec/SubjectDeclaration: + Enabled: false +RSpec/VerifiedDoubleReference: + Enabled: false +Security/CompoundHash: + Enabled: false +Security/IoMethods: + Enabled: false +Style/ArgumentsForwarding: + Enabled: false +Style/ArrayIntersect: + Enabled: false +Style/CollectionCompact: + Enabled: false +Style/ComparableClamp: + Enabled: false +Style/ConcatArrayLiterals: + Enabled: false +Style/DataInheritance: + Enabled: false +Style/DirEmpty: + Enabled: false +Style/DocumentDynamicEvalDefinition: + Enabled: false +Style/EmptyHeredoc: + Enabled: false +Style/EndlessMethod: + Enabled: false +Style/EnvHome: + Enabled: false +Style/FetchEnvVar: + Enabled: false +Style/FileEmpty: + Enabled: false +Style/FileRead: + Enabled: false +Style/FileWrite: + Enabled: false +Style/HashConversion: + Enabled: false +Style/HashExcept: + Enabled: false +Style/IfWithBooleanLiteralBranches: + Enabled: false +Style/InPatternThen: + Enabled: false +Style/MagicCommentFormat: + Enabled: false +Style/MapCompactWithConditionalBlock: + Enabled: false +Style/MapToHash: + Enabled: false +Style/MapToSet: + Enabled: false +Style/MinMaxComparison: + Enabled: false +Style/MultilineInPatternThen: + Enabled: false +Style/NegatedIfElseCondition: + Enabled: false +Style/NestedFileDirname: + Enabled: false +Style/NilLambda: + Enabled: false +Style/NumberedParameters: + Enabled: false +Style/NumberedParametersLimit: + Enabled: false +Style/ObjectThen: + Enabled: false +Style/OpenStructUse: + Enabled: false +Style/OperatorMethodCall: + Enabled: false +Style/QuotedSymbols: + Enabled: false +Style/RedundantArgument: + Enabled: false +Style/RedundantConstantBase: + Enabled: false +Style/RedundantDoubleSplatHashBraces: + Enabled: false +Style/RedundantEach: + Enabled: false +Style/RedundantHeredocDelimiterQuotes: + Enabled: false +Style/RedundantInitialize: + Enabled: false +Style/RedundantLineContinuation: + Enabled: false +Style/RedundantSelfAssignmentBranch: + Enabled: false +Style/RedundantStringEscape: + Enabled: false +Style/SelectByRegexp: + Enabled: false +Style/StringChars: + Enabled: false +Style/SwapValues: + Enabled: false diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml new file mode 100644 index 000000000..7eb42c4b1 --- /dev/null +++ b/.rubocop_todo.yml @@ -0,0 +1,33 @@ +# This configuration was generated by +# `rubocop --auto-gen-config` +# on 2023-11-28 17:34:47 UTC using RuboCop version 1.48.1. +# The point is for the user to remove these configuration records +# one by one as the offenses are removed from the code base. +# Note that changes in the inspected code, or installation of new +# versions of RuboCop, may require this file to be generated again. + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +Layout/RescueEnsureAlignment: + Exclude: + - 'lib/puppet/parser/functions/any2bool.rb' + +# Offense count: 3 +# This cop supports safe autocorrection (--autocorrect). +Lint/RedundantCopDisableDirective: + Exclude: + - 'lib/puppet/functions/deprecation.rb' + - 'spec/functions/loadjson_spec.rb' + +# Offense count: 3 +# Configuration parameters: AllowComments, AllowNil. +Lint/SuppressedException: + Exclude: + - 'lib/puppet/functions/stdlib/merge.rb' + - 'lib/puppet/parser/functions/has_interface_with.rb' + +# Offense count: 257 +# Configuration parameters: EnforcedStyle, IgnoreSharedExamples. +# SupportedStyles: always, named_only +RSpec/NamedSubject: + Enabled: false diff --git a/.sync.yml b/.sync.yml index 21e872e0c..dedc937aa 100644 --- a/.sync.yml +++ b/.sync.yml @@ -1,9 +1,27 @@ --- -.travis.yml: - script: "\"bundle exec rake validate && bundle exec rake lint && bundle exec rake spec SPEC_OPTS='--color --format documentation'\"" +".gitlab-ci.yml": + delete: true +".rubocop.yml": + include_todos: true +appveyor.yml: + delete: true Rakefile: - unmanaged: true -Gemfile: - unmanaged: true + changelog_max_issues: 500 + spec/spec_helper.rb: - unmanaged: true + mock_with: ":rspec" + coverage_report: true +.gitpod.Dockerfile: + unmanaged: false +.gitpod.yml: + unmanaged: false +.github/workflows/auto_release.yml: + unmanaged: false +.github/workflows/ci.yml: + unmanaged: false +.github/workflows/nightly.yml: + unmanaged: false +.github/workflows/release.yml: + unmanaged: false +.travis.yml: + delete: true diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 6fad7a4ad..000000000 --- a/.travis.yml +++ /dev/null @@ -1,21 +0,0 @@ ---- -sudo: false -language: ruby -cache: bundler -bundler_args: --without system_tests -script: "bundle exec rake validate && bundle exec rake lint && bundle exec rake spec SPEC_OPTS='--color --format documentation'" -matrix: - fast_finish: true - include: - - rvm: 1.8.7 - env: PUPPET_GEM_VERSION="~> 3.0" - - rvm: 1.9.3 - env: PUPPET_GEM_VERSION="~> 3.0" - - rvm: 2.1.5 - env: PUPPET_GEM_VERSION="~> 3.0" - - rvm: 2.1.5 - env: PUPPET_GEM_VERSION="~> 3.0" FUTURE_PARSER="yes" - - rvm: 2.1.6 - env: PUPPET_GEM_VERSION="~> 4.0" STRICT_VARIABLES="yes" -notifications: - email: false diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 000000000..6da8d472f --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,6 @@ +{ + "recommendations": [ + "puppet.puppet-vscode", + "Shopify.ruby-lsp" + ] +} diff --git a/.yardopts b/.yardopts new file mode 100644 index 000000000..29c933bcf --- /dev/null +++ b/.yardopts @@ -0,0 +1 @@ +--markup markdown diff --git a/CHANGELOG.md b/CHANGELOG.md index d29963c4d..6f650b7a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,571 +1,1263 @@ -##2015-08-13 - Supported Release 4.8.1 -###Summary - -Adds some new functions. - -####Features -- Add new functions: `dos2unix` and `unix2dos` - -####Bugfixes -- n/a - -####Improvements -- n/a - -## 2015-08-10 - Supported Release 4.8.0 -### Summary -This release adds a function for reading metadata.json from any module, and expands file\_line's abilities. - -#### Features -- New parameter `replace` on `file_line` -- New function `load_module_metadata()` to load metadata.json and return the content as a hash. -- Added hash support to `size()` - -#### Bugfixes -- Fix various docs typos -- Fix `file_line` resource on puppet < 3.3 - -##2015-06-22 - Supported Release 4.7.0 -###Summary - -Adds Solaris 12 support along with improved Puppet 4 support. There are significant test improvements, and some minor fixes. - -####Features -- Add support for Solaris 12 - -####Bugfixes -- Fix for AIO Puppet 4 -- Fix time for ruby 1.8.7 -- Specify rspec-puppet version -- range() fix for typeerror and missing functionality -- Fix pw_hash() on JRuby < 1.7.17 -- fqdn_rand_string: fix argument error message -- catch and rescue from looking up non-existent facts -- Use puppet_install_helper, for Puppet 4 - -####Improvements -- Enforce support for Puppet 4 testing -- fqdn_rotate/fqdn_rand_string acceptance tests and implementation -- Simplify mac address regex -- validate_integer, validate_numeric: explicitely reject hashes in arrays -- Readme edits -- Remove all the pops stuff for rspec-puppet -- Sync via modulesync -- Add validate_slength optional 3rd arg -- Move tests directory to examples directory - -##2015-04-14 - Supported Release 4.6.0 -###Summary - -Adds functions and function argument abilities, and improves compatibility with the new puppet parser - -####Features -- MODULES-444: `concat()` can now take more than two arrays -- `basename()` added to have Ruby File.basename functionality -- `delete()` can now take an array of items to remove -- `prefix()` can now take a hash -- `upcase()` can now take a hash or array of upcaseable things -- `validate_absolute_path()` can now take an array -- `validate_cmd()` can now use % in the command to embed the validation file argument in the string -- MODULES-1473: deprecate `type()` function in favor of `type3x()` -- MODULES-1473: Add `type_of()` to give better type information on future parser -- Deprecate `private()` for `assert_private()` due to future parser -- Adds `ceiling()` to take the ceiling of a number -- Adds `fqdn_rand_string()` to generate random string based on fqdn -- Adds `pw_hash()` to generate password hashes -- Adds `validate_integer()` -- Adds `validate_numeric()` (like `validate_integer()` but also accepts floats) - -####Bugfixes -- Fix seeding of `fqdn_rotate()` -- `ensure_resource()` is more verbose on debug mode -- Stricter argument checking for `dirname()` -- Fix `is_domain_name()` to better match RFC -- Fix `uriescape()` when called with array -- Fix `file_line` resource when using the `after` attribute with `match` - -##2015-01-14 - Supported Release 4.5.1 -###Summary - -This release changes the temporary facter_dot_d cache locations outside of the /tmp directory due to a possible security vunerability. CVE-2015-1029 - -####Bugfixes -- Facter_dot_d cache will now be stored in puppet libdir instead of tmp - -##2014-12-15 - Supported Release 4.5.0 -###Summary - -This release improves functionality of the member function and adds improved future parser support. - -####Features -- MODULES-1329: Update member() to allow the variable to be an array. -- Sync .travis.yml, Gemfile, Rakefile, and CONTRIBUTING.md via modulesync - -####Bugfixes -- Fix range() to work with numeric ranges with the future parser -- Accurately express SLES support in metadata.json (was missing 10SP4 and 12) -- Don't require `line` to match the `match` parameter - -##2014-11-10 - Supported Release 4.4.0 -###Summary -This release has an overhauled readme, new private manifest function, and fixes many future parser bugs. - -####Features -- All new shiny README -- New `private()` function for making private manifests (yay!) - -####Bugfixes -- Code reuse in `bool2num()` and `zip()` -- Fix many functions to handle `generate()` no longer returning a string on new puppets -- `concat()` no longer modifies the first argument (whoops) -- strict variable support for `getvar()`, `member()`, `values_at`, and `has_interface_with()` -- `to_bytes()` handles PB and EB now -- Fix `tempfile` ruby requirement for `validate_augeas()` and `validate_cmd()` -- Fix `validate_cmd()` for windows -- Correct `validate_string()` docs to reflect non-handling of `undef` -- Fix `file_line` matching on older rubies - - -##2014-07-15 - Supported Release 4.3.2 -###Summary - -This release merely updates metadata.json so the module can be uninstalled and -upgraded via the puppet module command. - -##2014-07-14 - Supported Release 4.3.1 -### Summary -This supported release updates the metadata.json to work around upgrade behavior of the PMT. - -#### Bugfixes -- Synchronize metadata.json with PMT-generated metadata to pass checksums + +# Changelog -##2014-06-27 - Supported Release 4.3.0 -### Summary -This release is the first supported release of the stdlib 4 series. It remains -backwards-compatible with the stdlib 3 series. It adds two new functions, one bugfix, and many testing updates. +All notable changes to this project will be documented in this file. -#### Features -- New `bool2str()` function -- New `camelcase()` function +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org). -#### Bugfixes -- Fix `has_interface_with()` when interfaces fact is nil +## [v9.7.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v9.7.0) - 2024-12-17 -##2014-06-04 - Release 4.2.2 -### Summary +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v9.6.0...v9.7.0) -This release adds PE3.3 support in the metadata and fixes a few tests. +### Added -## 2014-05-08 - Release - 4.2.1 -### Summary -This release moves a stray symlink that can cause problems. +- (CAT-2119) Add Ubuntu 24.04 support [#1440](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1440) ([shubhamshinde360](https://github.com/shubhamshinde360)) +- (CAT-2101) Add support for Debian-12 [#1439](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1439) ([skyamgarp](https://github.com/skyamgarp)) +- Support for Amazon linux 2 and 2023 [#1427](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1427) ([h0tw1r3](https://github.com/h0tw1r3)) -## 2014-05-08 - Release - 4.2.0 -### Summary -This release adds many new functions and fixes, and continues to be backwards compatible with stdlib 3.x +### Fixed -#### Features -- New `base64()` function -- New `deep_merge()` function -- New `delete_undef_values()` function -- New `delete_values()` function -- New `difference()` function -- New `intersection()` function -- New `is_bool()` function -- New `pick_default()` function -- New `union()` function -- New `validate_ipv4_address` function -- New `validate_ipv6_address` function -- Update `ensure_packages()` to take an option hash as a second parameter. -- Update `range()` to take an optional third argument for range step -- Update `validate_slength()` to take an optional third argument for minimum length -- Update `file_line` resource to take `after` and `multiple` attributes +- (CAT-2180) Upgrade rexml to address CVE-2024-49761 [#1443](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1443) ([amitkarsale](https://github.com/amitkarsale)) -#### Bugfixes -- Correct `is_string`, `is_domain_name`, `is_array`, `is_float`, and `is_function_available` for parsing odd types such as bools and hashes. -- Allow facts.d facts to contain `=` in the value -- Fix `root_home` fact on darwin systems -- Fix `concat()` to work with a second non-array argument -- Fix `floor()` to work with integer strings -- Fix `is_integer()` to return true if passed integer strings -- Fix `is_numeric()` to return true if passed integer strings -- Fix `merge()` to work with empty strings -- Fix `pick()` to raise the correct error type -- Fix `uriescape()` to use the default URI.escape list -- Add/update unit & acceptance tests. +## [v9.6.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v9.6.0) - 2024-04-03 +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v9.5.0...v9.6.0) -##2014-03-04 - Supported Release - 3.2.1 -###Summary -This is a supported release +### Added -####Bugfixes -- Fixed `is_integer`/`is_float`/`is_numeric` for checking the value of arithmatic expressions. +- Allow usage of file templates with stdlib::manage [#1422](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1422) ([tuxmea](https://github.com/tuxmea)) -####Known bugs -* No known bugs +## [v9.5.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v9.5.0) - 2024-03-11 ---- +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v9.4.1...v9.5.0) -##### 2013-05-06 - Jeff McCune - 4.1.0 +### Added - * (#20582) Restore facter\_dot\_d to stdlib for PE users (3b887c8) - * (maint) Update Gemfile with GEM\_FACTER\_VERSION (f44d535) +- Add function stdlib::sort_by [#1384](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1384) ([XMol](https://github.com/XMol)) -##### 2013-05-06 - Alex Cline - 4.1.0 +### Fixed - * Terser method of string to array conversion courtesy of ethooz. (d38bce0) +- (#1389) - pw_hash with bcrypt not working on puppet master [#1410](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1410) ([TuningYourCode](https://github.com/TuningYourCode)) -##### 2013-05-06 - Alex Cline 4.1.0 +### Other - * Refactor ensure\_resource expectations (b33cc24) +- Deprecate `time` function [#1417](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1417) ([alexjfisher](https://github.com/alexjfisher)) -##### 2013-05-06 - Alex Cline 4.1.0 +## [v9.4.1](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v9.4.1) - 2023-11-09 - * Changed str-to-array conversion and removed abbreviation. (de253db) +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v9.4.0...v9.4.1) -##### 2013-05-03 - Alex Cline 4.1.0 +### Fixed - * (#20548) Allow an array of resource titles to be passed into the ensure\_resource function (e08734a) +- Correct casing of Stdlib::IP::Address [#1406](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1406) ([ekohl](https://github.com/ekohl)) -##### 2013-05-02 - RaphaĆ«l Pinson - 4.1.0 +## [v9.4.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v9.4.0) - 2023-09-29 - * Add a dirname function (2ba9e47) +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v9.3.0...v9.4.0) -##### 2013-04-29 - Mark Smith-Guerrero - 4.1.0 +### Added - * (maint) Fix a small typo in hash() description (928036a) +- Modernise `fqdn_rotate` function [#1341](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1341) ([alexjfisher](https://github.com/alexjfisher)) -##### 2013-04-12 - Jeff McCune - 4.0.2 +## [v9.3.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v9.3.0) - 2023-08-01 - * Update user information in gemspec to make the intent of the Gem clear. +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v9.2.0...v9.3.0) -##### 2013-04-11 - Jeff McCune - 4.0.1 +### Added - * Fix README function documentation (ab3e30c) +- Add stdlib::has_function [#1386](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1386) ([seanmil](https://github.com/seanmil)) -##### 2013-04-11 - Jeff McCune - 4.0.0 +### Fixed - * stdlib 4.0 drops support with Puppet 2.7 - * stdlib 4.0 preserves support with Puppet 3 +- Re-add block support to deprecated top-level merge [#1385](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1385) ([seanmil](https://github.com/seanmil)) -##### 2013-04-11 - Jeff McCune - 4.0.0 +## [v9.2.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v9.2.0) - 2023-06-27 - * Add ability to use puppet from git via bundler (9c5805f) +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v9.1.0...v9.2.0) -##### 2013-04-10 - Jeff McCune - 4.0.0 +### Added - * (maint) Make stdlib usable as a Ruby GEM (e81a45e) +- Add `use_strict_setting` parameter to `deprecation` function [#1378](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1378) ([alexjfisher](https://github.com/alexjfisher)) -##### 2013-04-10 - Erik DalĆ©n - 4.0.0 +### Fixed - * Add a count function (f28550e) +- Ignore Puppet's `strict` setting when calling function without namespace [#1377](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1377) ([alexjfisher](https://github.com/alexjfisher)) +- Pass calling scope to `stdlib::ensure_packages` from shim [#1366](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1366) ([alexjfisher](https://github.com/alexjfisher)) -##### 2013-03-31 - Amos Shapira - 4.0.0 +## [v9.1.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v9.1.0) - 2023-06-15 - * (#19998) Implement any2array (7a2fb80) +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v9.0.0...v9.1.0) -##### 2013-03-29 - Steve Huff - 4.0.0 +### Added - * (19864) num2bool match fix (8d217f0) +- re-add support for loading aliases in yaml files [#1362](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1362) ([lollipopman](https://github.com/lollipopman)) -##### 2013-03-20 - Erik DalĆ©n - 4.0.0 +### Fixed - * Allow comparisons of Numeric and number as String (ff5dd5d) +- (CONT-1035) Alter logic of pw_hash [#1370](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1370) ([david22swan](https://github.com/david22swan)) +- Fix `fqdn_rand_string` regression [#1367](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1367) ([alexjfisher](https://github.com/alexjfisher)) +- (CONT-1023) - Enhancing deferrable_epp to support nested hash [#1359](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1359) ([Ramesh7](https://github.com/Ramesh7)) -##### 2013-03-26 - Richard Soderberg - 4.0.0 +## [v9.0.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v9.0.0) - 2023-05-30 - * add suffix function to accompany the prefix function (88a93ac) +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v8.6.0...v9.0.0) -##### 2013-03-19 - Kristof Willaert - 4.0.0 +### Changed - * Add floor function implementation and unit tests (0527341) +- Deprecate the `validate_legacy()` function [#1353](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1353) ([smortex](https://github.com/smortex)) +- Remove deprecated functions [#1352](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1352) ([smortex](https://github.com/smortex)) +- Rewrite validate_email_address() as a Puppet 4.x function [#1350](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1350) ([smortex](https://github.com/smortex)) +- Rewrite validate_domain_name() as a Puppet 4.x function [#1345](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1345) ([smortex](https://github.com/smortex)) +- Rewrite seeded_rand() as a Puppet 4.x function [#1344](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1344) ([smortex](https://github.com/smortex)) +- Rewrite fqdn_rand_string() as a Puppet 4.x function [#1343](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1343) ([smortex](https://github.com/smortex)) +- Remove deprecated strip function [#1338](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1338) ([smortex](https://github.com/smortex)) +- Remove deprecated rstrip function [#1337](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1337) ([smortex](https://github.com/smortex)) +- Remove deprecated getvar function [#1336](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1336) ([smortex](https://github.com/smortex)) +- Remove deprecated sort function [#1335](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1335) ([smortex](https://github.com/smortex)) +- Remove deprecated upcase function [#1334](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1334) ([smortex](https://github.com/smortex)) +- Remove deprecated round function [#1333](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1333) ([smortex](https://github.com/smortex)) +- Remove deprecated chop function [#1331](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1331) ([smortex](https://github.com/smortex)) +- Remove deprecated chomp function [#1330](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1330) ([smortex](https://github.com/smortex)) +- Remove deprecated ceiling function [#1329](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1329) ([smortex](https://github.com/smortex)) +- Remove deprecated capitalize functions [#1328](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1328) ([smortex](https://github.com/smortex)) +- Remove deprecated camelcase function [#1327](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1327) ([smortex](https://github.com/smortex)) +- Modernise `has_interface_with` function [#1326](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1326) ([alexjfisher](https://github.com/alexjfisher)) +- Remove deprecated is_array function [#1325](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1325) ([MartyEwings](https://github.com/MartyEwings)) +- Remove deprecated is_absolute_path function [#1324](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1324) ([MartyEwings](https://github.com/MartyEwings)) +- Remove deprecated min function [#1323](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1323) ([MartyEwings](https://github.com/MartyEwings)) +- Remove deprecated max function [#1322](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1322) ([MartyEwings](https://github.com/MartyEwings)) +- Remove deprecated lstrip function [#1321](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1321) ([MartyEwings](https://github.com/MartyEwings)) +- Remove deprecated hash function [#1320](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1320) ([MartyEwings](https://github.com/MartyEwings)) +- Remove deprecated has_key function [#1319](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1319) ([MartyEwings](https://github.com/MartyEwings)) +- Remove deprecated downcase function [#1318](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1318) ([MartyEwings](https://github.com/MartyEwings)) +- Remove deprecated abs function [#1317](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1317) ([MartyEwings](https://github.com/MartyEwings)) +- Remove dig and dig44 functions [#1316](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1316) ([MartyEwings](https://github.com/MartyEwings)) +- Remove Puppet 5.5 deprecations [#1314](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1314) ([MartyEwings](https://github.com/MartyEwings)) +- Remove deprecated unique function [#1311](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1311) ([MartyEwings](https://github.com/MartyEwings)) +- Remove deprecated Private function [#1310](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1310) ([MartyEwings](https://github.com/MartyEwings)) +- Remove deprecated type and type3x functions [#1309](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1309) ([MartyEwings](https://github.com/MartyEwings)) +- (CONT-801) Puppet 8 support / Drop Puppet 6 support [#1307](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1307) ([LukasAud](https://github.com/LukasAud)) -##### 2012-04-03 - Eric Shamow - 4.0.0 +### Added - * (#13610) Add is\_function\_available to stdlib (961dcab) +- Namespace Puppet 4.x functions [#1356](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1356) ([smortex](https://github.com/smortex)) +- Add a function to update / regenerate deprecated shims [#1349](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1349) ([smortex](https://github.com/smortex)) -##### 2012-12-17 - Justin Lambert - 4.0.0 +### Fixed - * str2bool should return a boolean if called with a boolean (5d5a4d4) +- Remove deprecated File.exists? [#1357](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1357) ([ekohl](https://github.com/ekohl)) +- Fix validate_domain_name called without parameters [#1351](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1351) ([smortex](https://github.com/smortex)) +- Add Stdlib::IP::Address::CIDR [#1348](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1348) ([Geod24](https://github.com/Geod24)) +- Allow `deferrable_epp` to return a `Sensitive[String]` [#1342](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1342) ([alexjfisher](https://github.com/alexjfisher)) -##### 2012-10-23 - Uwe Stuehler - 4.0.0 +## [v8.6.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v8.6.0) - 2023-04-24 - * Fix number of arguments check in flatten() (e80207b) +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v8.5.0...v8.6.0) -##### 2013-03-11 - Jeff McCune - 4.0.0 +### Added - * Add contributing document (96e19d0) +- Stdlib::Http::Method: Add new type for http methods [#1299](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1299) ([b4ldr](https://github.com/b4ldr)) +- Add `stdlib::sha256` [#1289](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1289) ([jcpunk](https://github.com/jcpunk)) +- Add `stdlib::crc32` [#1288](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1288) ([jcpunk](https://github.com/jcpunk)) +- Add Stdlib::Ensure::Package type [#1281](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1281) ([arjenz](https://github.com/arjenz)) -##### 2013-03-04 - RaphaĆ«l Pinson - 4.0.0 +### Fixed - * Add missing documentation for validate\_augeas and validate\_cmd to README.markdown (a1510a1) +- (PUP-11752) Fix fqdn_rand_string_spec.rb test [#1308](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1308) ([alexjfisher](https://github.com/alexjfisher)) +- Make ensure_packages work with `ensure => present` [#1300](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1300) ([alexjfisher](https://github.com/alexjfisher)) +- Safely handle a missing root user [#1295](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1295) ([ekohl](https://github.com/ekohl)) +- stdlib::ensure: update function to support the generic case [#1286](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1286) ([b4ldr](https://github.com/b4ldr)) +- Drop Puppet < 3.6 support in package_provider fact [#1280](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1280) ([ekohl](https://github.com/ekohl)) +- Correct bcrypt salt regex [#1279](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1279) ([sabo](https://github.com/sabo)) +- Determine root_home without shelling out [#1278](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1278) ([ekohl](https://github.com/ekohl)) +- (CONT-173) - Updating deprecated facter instances [#1277](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1277) ([jordanbreen28](https://github.com/jordanbreen28)) -##### 2013-02-14 - Joshua Hoblitt - 4.0.0 +## [v8.5.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v8.5.0) - 2022-10-13 - * (#19272) Add has\_element() function (95cf3fe) +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v8.4.0...v8.5.0) -##### 2013-02-07 - RaphaĆ«l Pinson - 4.0.0 +### Added - * validate\_cmd(): Use Puppet::Util::Execution.execute when available (69248df) +- Add a Stdlib::CreateResources type [#1267](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1267) ([ekohl](https://github.com/ekohl)) +- pdksync - (GH-cat-11) Certify Support for Ubuntu 22.04 [#1261](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1261) ([david22swan](https://github.com/david22swan)) +- (FEAT) Add function parsepson [#1259](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1259) ([david22swan](https://github.com/david22swan)) -##### 2012-12-06 - RaphaĆ«l Pinson - 4.0.0 +### Fixed - * Add validate\_augeas function (3a97c23) +- (CONT-200) Fix require relative paths [#1275](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1275) ([chelnak](https://github.com/chelnak)) +- pdksync - (CONT-189) Remove support for RedHat6 / OracleLinux6 / Scientific6 [#1272](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1272) ([david22swan](https://github.com/david22swan)) +- pdksync - (CONT-130) - Dropping Support for Debian 9 [#1269](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1269) ([jordanbreen28](https://github.com/jordanbreen28)) +- (MAINT) Drop support for AIX + Windows EOL OSs [#1265](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1265) ([jordanbreen28](https://github.com/jordanbreen28)) +- (GH-1262) Use 'require_relative' to load stdlib due to lookup errors [#1264](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1264) ([david22swan](https://github.com/david22swan)) +- Switch parsejson() from PSON to JSON parsing [#1240](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1240) ([seanmil](https://github.com/seanmil)) -##### 2012-12-06 - RaphaĆ«l Pinson - 4.0.0 +## [v8.4.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v8.4.0) - 2022-07-21 - * Add validate\_cmd function (6902cc5) +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v8.3.0...v8.4.0) -##### 2013-01-14 - David Schmitt - 4.0.0 +### Added - * Add geppetto project definition (b3fc0a3) +- deferrable epp function simplifying deferred templates [#1253](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1253) ([binford2k](https://github.com/binford2k)) -##### 2013-01-02 - Jaka Hudoklin - 4.0.0 +## [v8.3.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v8.3.0) - 2022-07-11 - * Add getparam function to get defined resource parameters (20e0e07) +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v8.2.0...v8.3.0) -##### 2013-01-05 - Jeff McCune - 4.0.0 +### Added - * (maint) Add Travis CI Support (d082046) +- pdksync - (GH-cat-12) Add Support for Redhat 9 [#1247](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1247) ([david22swan](https://github.com/david22swan)) +- Convert `ensure_packages` to new API and refactor [#1244](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1244) ([alexjfisher](https://github.com/alexjfisher)) -##### 2012-12-04 - Jeff McCune - 4.0.0 +### Fixed - * Clarify that stdlib 3 supports Puppet 3 (3a6085f) +- (MODULES-2892) Handle missing file in file_line [#1251](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1251) ([silug](https://github.com/silug)) +- Simplify stdlib::manage [#1250](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1250) ([jcpunk](https://github.com/jcpunk)) +- Unbreak `rake strings:generate:reference` [#1239](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1239) ([smortex](https://github.com/smortex)) +- loadjson: do not send http_basic_authentication if not needed [#1208](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1208) ([chaen](https://github.com/chaen)) -##### 2012-11-30 - Erik DalĆ©n - 4.0.0 +## [v8.2.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v8.2.0) - 2022-05-16 - * maint: style guideline fixes (7742e5f) +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v8.1.0...v8.2.0) -##### 2012-11-09 - James Fryman - 4.0.0 +### Added - * puppet-lint cleanup (88acc52) +- Add `xml_encode` function [#1236](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1236) ([alexjfisher](https://github.com/alexjfisher)) +- (MODULES-4976) Add windows escaping functions [#1235](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1235) ([smortex](https://github.com/smortex)) +- MODULES-11309 : convert a string to a resource [#1233](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1233) ([jcpunk](https://github.com/jcpunk)) +- pdksync - (FM-8922) - Add Support for Windows 2022 [#1222](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1222) ([david22swan](https://github.com/david22swan)) +- (MODULES-11196) Add support for AIX 7.2 [#1220](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1220) ([david22swan](https://github.com/david22swan)) +- pdksync - (IAC-1753) - Add Support for AlmaLinux 8 [#1216](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1216) ([david22swan](https://github.com/david22swan)) -##### 2012-11-06 - Joe Julian - 4.0.0 +### Fixed - * Add function, uriescape, to URI.escape strings. Redmine #17459 (fd52b8d) +- Update load_module_metadata.rb to correct capitalisation in strings documentartion [#1241](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1241) ([davidsandilands](https://github.com/davidsandilands)) +- Modernize escape functions [#1238](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1238) ([smortex](https://github.com/smortex)) +- Convert data to Pcore before serialisation in to_ruby/to_python [#1237](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1237) ([smortex](https://github.com/smortex)) +- (maint) Update str2saltedpbkdf2.rb to use the correct salt length [#1232](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1232) ([AriaXLi](https://github.com/AriaXLi)) +- Fix `to_yaml` `options` parameter [#1231](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1231) ([alexjfisher](https://github.com/alexjfisher)) +- pdksync - (GH-iac-334) Remove Support for Ubuntu 14.04/16.04 [#1224](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1224) ([david22swan](https://github.com/david22swan)) +- pdksync - (IAC-1787) Remove Support for CentOS 6 [#1219](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1219) ([david22swan](https://github.com/david22swan)) +- Fix serialization of undef in to_python() [#1205](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1205) ([smortex](https://github.com/smortex)) -##### 2012-09-18 - Chad Metcalf - 3.2.0 +## [v8.1.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v8.1.0) - 2021-10-04 - * Add an ensure\_packages function. (8a8c09e) +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v8.0.0...v8.1.0) -##### 2012-11-23 - Erik DalĆ©n - 3.2.0 +### Added - * (#17797) min() and max() functions (9954133) +- pdksync - (IAC-1751) - Add Support for Rocky 8 [#1214](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1214) ([david22swan](https://github.com/david22swan)) +- stdlib::ensure: Add support for package resource [#1213](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1213) ([david-caro](https://github.com/david-caro)) +- Added to_toml function [#1209](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1209) ([nmaludy](https://github.com/nmaludy)) -##### 2012-05-23 - Peter Meier - 3.2.0 +### Fixed - * (#14670) autorequire a file\_line resource's path (dfcee63) +- [MODULES-11195] Add lint-ignore for pattern length [#1212](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1212) ([carabasdaniel](https://github.com/carabasdaniel)) +- pdksync - (IAC-1598) - Remove Support for Debian 8 [#1210](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1210) ([david22swan](https://github.com/david22swan)) +- os_version_gte: fix version comparison logic [#1207](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1207) ([kenyon](https://github.com/kenyon)) +- max, lstrip: fix deprecated message [#1204](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1204) ([b4ldr](https://github.com/b4ldr)) +- (MODULES-11126) Replacing URI.escape with URI::DEFAULT_PARSER [#1195](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1195) ([valleedelisle](https://github.com/valleedelisle)) -##### 2012-11-19 - Joshua Harlan Lifton - 3.2.0 +## [v8.0.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v8.0.0) - 2021-08-24 - * Add join\_keys\_to\_values function (ee0f2b3) +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v7.1.0...v8.0.0) -##### 2012-11-17 - Joshua Harlan Lifton - 3.2.0 +### Changed - * Extend delete function for strings and hashes (7322e4d) +- Flip installed and present in Function ensure_packages [#1196](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1196) ([cocker-cc](https://github.com/cocker-cc)) -##### 2012-08-03 - Gary Larizza - 3.2.0 +### Added - * Add the pick() function (ba6dd13) +- New function to_python() / to_ruby() [#1200](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1200) ([smortex](https://github.com/smortex)) +- pdksync - (IAC-1709) - Add Support for Debian 11 [#1199](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1199) ([david22swan](https://github.com/david22swan)) +- Stdlib::Http::Method: Add new type for http methods [#1192](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1192) ([b4ldr](https://github.com/b4ldr)) -##### 2012-03-20 - Wil Cooley - 3.2.0 +### Fixed - * (#13974) Add predicate functions for interface facts (f819417) +- (MODULES-11099) Make merge parameter data types actually backwards compatible [#1191](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1191) ([LadyNamedLaura](https://github.com/LadyNamedLaura)) -##### 2012-11-06 - Joe Julian - 3.2.0 +## [v7.1.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v7.1.0) - 2021-05-17 - * Add function, uriescape, to URI.escape strings. Redmine #17459 (70f4a0e) +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v7.0.1...v7.1.0) -##### 2012-10-25 - Jeff McCune - 3.1.1 +### Added - * (maint) Fix spec failures resulting from Facter API changes (97f836f) +- pw_hash: add support for bcrypt variants [#1173](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1173) ([kjetilho](https://github.com/kjetilho)) -##### 2012-10-23 - Matthaus Owens - 3.1.0 +## [v7.0.1](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v7.0.1) - 2021-04-12 - * Add PE facts to stdlib (cdf3b05) +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v7.0.0...v7.0.1) -##### 2012-08-16 - Jeff McCune - 3.0.1 +### Fixed - * Fix accidental removal of facts\_dot\_d.rb in 3.0.0 release +- Fix typo in validate_ipv6_address function [#1176](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1176) ([nbarrientos](https://github.com/nbarrientos)) -##### 2012-08-16 - Jeff McCune - 3.0.0 +## [v7.0.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v7.0.0) - 2021-03-01 - * stdlib 3.0 drops support with Puppet 2.6 - * stdlib 3.0 preserves support with Puppet 2.7 +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v6.6.0...v7.0.0) -##### 2012-08-07 - Dan Bode - 3.0.0 +### Changed - * Add function ensure\_resource and defined\_with\_params (ba789de) +- pdksync - Remove Puppet 5 from testing and bump minimal version to 6.0.0 [#1164](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1164) ([carabasdaniel](https://github.com/carabasdaniel)) -##### 2012-07-10 - Hailee Kenney - 3.0.0 +### Added - * (#2157) Remove facter\_dot\_d for compatibility with external facts (f92574f) +- Stdlib::Email type [#1160](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1160) ([b4ldr](https://github.com/b4ldr)) -##### 2012-04-10 - Chris Price - 3.0.0 +### Fixed - * (#13693) moving logic from local spec\_helper to puppetlabs\_spec\_helper (85f96df) +- (bugfix) Setting stricter email validation [#1163](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1163) ([pmcmaw](https://github.com/pmcmaw)) +- (IAC-1414) Throw error in range() function when step size invalid [#1161](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1161) ([sanfrancrisko](https://github.com/sanfrancrisko)) -##### 2012-10-25 - Jeff McCune - 2.5.1 +## [v6.6.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v6.6.0) - 2021-02-02 - * (maint) Fix spec failures resulting from Facter API changes (97f836f) +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v6.5.0...v6.6.0) -##### 2012-10-23 - Matthaus Owens - 2.5.0 +### Added - * Add PE facts to stdlib (cdf3b05) +- stdlib::ensure: new fuction to cast ensure values [#1150](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1150) ([b4ldr](https://github.com/b4ldr)) +- (feat) Add support for Puppet 7 [#1144](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1144) ([daianamezdrea](https://github.com/daianamezdrea)) +- Allow options injection for to_yaml [#1137](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1137) ([baurmatt](https://github.com/baurmatt)) +- Allow start/end checks on empty strings [#1135](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1135) ([jvrsantacruz](https://github.com/jvrsantacruz)) +- Stdlib::HttpStatus: add type for HTTP status codes as per rfc2616 [#1132](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1132) ([b4ldr](https://github.com/b4ldr)) -##### 2012-08-15 - Dan Bode - 2.5.0 +### Fixed - * Explicitly load functions used by ensure\_resource (9fc3063) +- (IAC-1375) fix unit tests for pe_version fact, when using later facte… [#1155](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1155) ([tphoney](https://github.com/tphoney)) +- seeded_rand: update funtion to ensure it returns an int not String [#1139](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1139) ([b4ldr](https://github.com/b4ldr)) -##### 2012-08-13 - Dan Bode - 2.5.0 +## [v6.5.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v6.5.0) - 2020-09-30 - * Add better docs about duplicate resource failures (97d327a) +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v6.4.0...v6.5.0) -##### 2012-08-13 - Dan Bode - 2.5.0 +### Added - * Handle undef for parameter argument (4f8b133) +- Add parsehocon() function [#1130](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1130) ([reidmv](https://github.com/reidmv)) +- Add new types for Stdlib::Ensure::File [#1129](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1129) ([b4ldr](https://github.com/b4ldr)) +- Add additional types Stdlib::Port::Dynamic,Ephemeral,Registered,User} [#1128](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1128) ([b4ldr](https://github.com/b4ldr)) +- Stdlib::Datasize: This CR adds a new data size type alias [#1126](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1126) ([b4ldr](https://github.com/b4ldr)) -##### 2012-08-07 - Dan Bode - 2.5.0 +## [v6.4.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v6.4.0) - 2020-08-21 - * Add function ensure\_resource and defined\_with\_params (a0cb8cd) +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v6.3.0...v6.4.0) -##### 2012-08-20 - Jeff McCune - 2.5.0 +### Added - * Disable tests that fail on 2.6.x due to #15912 (c81496e) +- pdksync - (IAC-973) - Update travis/appveyor to run on new default branch `main` [#1117](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1117) ([david22swan](https://github.com/david22swan)) +- (IAC-746) - Add ubuntu 20.04 support [#1110](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1110) ([david22swan](https://github.com/david22swan)) -##### 2012-08-20 - Jeff McCune - 2.5.0 +### Fixed - * (Maint) Fix mis-use of rvalue functions as statements (4492913) +- [MODULES-10781] Fix defined type defined_with_params() [#1122](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1122) ([trevor-vaughan](https://github.com/trevor-vaughan)) +- [MODULES-10729] defined_with_params - unnamed type [#1115](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1115) ([trevor-vaughan](https://github.com/trevor-vaughan)) -##### 2012-08-20 - Jeff McCune - 2.5.0 +## [v6.3.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v6.3.0) - 2020-04-16 - * Add .rspec file to repo root (88789e8) +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v6.2.0...v6.3.0) -##### 2012-06-07 - Chris Price - 2.4.0 +### Added - * Add support for a 'match' parameter to file\_line (a06c0d8) +- Add start_with function [#1086](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1086) ([baurmatt](https://github.com/baurmatt)) +- stdlib::end_with: create String.end_with function [#1084](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1084) ([b4ldr](https://github.com/b4ldr)) +- Adding str2saltedpbkdf2 function [#1040](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1040) ([genebean](https://github.com/genebean)) -##### 2012-08-07 - Erik DalĆ©n - 2.4.0 +### Fixed - * (#15872) Add to\_bytes function (247b69c) +- (MODULES-10623) explicitly top-scope calls to JSON methods [#1101](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1101) ([tkishel](https://github.com/tkishel)) +- [IAC-547] Remove strftime from stdlib as it has already been replaced by the puppet agent since 4.8.0 [#1097](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1097) ([carabasdaniel](https://github.com/carabasdaniel)) +- Add correct namespace for start_with function [#1095](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1095) ([baurmatt](https://github.com/baurmatt)) +- intersection: show types in exception due to invalid arguments [#1077](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1077) ([runejuhl](https://github.com/runejuhl)) +- Make type aliases stricter [#1066](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1066) ([pegasd](https://github.com/pegasd)) -##### 2012-07-19 - Jeff McCune - 2.4.0 +## [v6.2.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v6.2.0) - 2019-12-10 - * (Maint) use PuppetlabsSpec::PuppetInternals.scope (master) (deafe88) +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v6.1.0...v6.2.0) -##### 2012-07-10 - Hailee Kenney - 2.4.0 +### Added - * (#2157) Make facts\_dot\_d compatible with external facts (5fb0ddc) +- (FM-8696) - Addition of Support for CentOS 8 [#1065](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1065) ([david22swan](https://github.com/david22swan)) +- Add support for additional options to to_json_pretty [#1055](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1055) ([runejuhl](https://github.com/runejuhl)) -##### 2012-03-16 - Steve Traylen - 2.4.0 +### Fixed - * (#13205) Rotate array/string randomley based on fqdn, fqdn\_rotate() (fef247b) +- Fix PE detection (for the moment) [#1049](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1049) ([trevor-vaughan](https://github.com/trevor-vaughan)) -##### 2012-05-22 - Peter Meier - 2.3.3 +## [v6.1.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v6.1.0) - 2019-09-20 - * fix regression in #11017 properly (f0a62c7) +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v6.0.0...v6.1.0) -##### 2012-05-10 - Jeff McCune - 2.3.3 +### Added - * Fix spec tests using the new spec\_helper (7d34333) +- (MODULES-9915) Add type aliases for cloud object store uris [#1048](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1048) ([hooten](https://github.com/hooten)) +- FM-8411 - add support for debian10 [#1045](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1045) ([lionce](https://github.com/lionce)) +- (FM-8230) Convert testing to litmus [#1031](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1031) ([eimlav](https://github.com/eimlav)) +- (FM-8160) Add Windows Server 2019 support [#1025](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1025) ([eimlav](https://github.com/eimlav)) +- (FM-8048) Add RedHat 8 support [#1022](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1022) ([eimlav](https://github.com/eimlav)) +- (MODULES-9049) Add type alias for 'yes' and 'no'. [#1017](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1017) ([ghoneycutt](https://github.com/ghoneycutt)) +- add Stdlib::Syslogfacility type [#1005](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1005) ([bastelfreak](https://github.com/bastelfreak)) -##### 2012-05-10 - Puppet Labs - 2.3.2 +### Fixed - * Make file\_line default to ensure => present (1373e70) - * Memoize file\_line spec instance variables (20aacc5) - * Fix spec tests using the new spec\_helper (1ebfa5d) - * (#13595) initialize\_everything\_for\_tests couples modules Puppet ver (3222f35) - * (#13439) Fix MRI 1.9 issue with spec\_helper (15c5fd1) - * (#13439) Fix test failures with Puppet 2.6.x (665610b) - * (#13439) refactor spec helper for compatibility with both puppet 2.7 and master (82194ca) - * (#13494) Specify the behavior of zero padded strings (61891bb) +- fix lib/puppet/parser/functions/fqdn_rand_string.rb:21: syntax error [#1029](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1029) ([pulecp](https://github.com/pulecp)) +- Limit the maximum array size produced by range(). [#1023](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1023) ([mbaynton](https://github.com/mbaynton)) -##### 2012-03-29 Puppet Labs - 2.1.3 +## [v6.0.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v6.0.0) - 2019-05-22 -* (#11607) Add Rakefile to enable spec testing -* (#12377) Avoid infinite loop when retrying require json +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/5.2.0...v6.0.0) -##### 2012-03-13 Puppet Labs - 2.3.1 +### Changed -* (#13091) Fix LoadError bug with puppet apply and puppet\_vardir fact +- pdksync - (MODULES-8444) - Raise lower Puppet bound [#1011](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1011) ([david22swan](https://github.com/david22swan)) -##### 2012-03-12 Puppet Labs - 2.3.0 +### Added -* Add a large number of new Puppet functions -* Backwards compatibility preserved with 2.2.x +- (MODULES-8760) Add iterative feature to merge() function [#1008](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1008) ([hlindberg](https://github.com/hlindberg)) +- Add a stdlib::ip_in_range() function [#1003](https://github.com/puppetlabs/puppetlabs-stdlib/pull/1003) ([iglov](https://github.com/iglov)) -##### 2011-12-30 Puppet Labs - 2.2.1 +## [5.2.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/5.2.0) - 2019-01-18 -* Documentation only release for the Forge +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/5.1.0...5.2.0) -##### 2011-12-30 Puppet Labs - 2.1.2 +### Added -* Documentation only release for PE 2.0.x +- (MODULES-8404) - Relax `Stdlib::Filesource` type [#981](https://github.com/puppetlabs/puppetlabs-stdlib/pull/981) ([alexjfisher](https://github.com/alexjfisher)) +- Creates new type Stdlib::IP::Address::V6::CIDR [#980](https://github.com/puppetlabs/puppetlabs-stdlib/pull/980) ([timhughes](https://github.com/timhughes)) +- (MODULES-8137) - Addition of support for SLES 15 [#978](https://github.com/puppetlabs/puppetlabs-stdlib/pull/978) ([david22swan](https://github.com/david22swan)) +- (MODULES-8322) Consider IPs with /0 as valid [#975](https://github.com/puppetlabs/puppetlabs-stdlib/pull/975) ([simondeziel](https://github.com/simondeziel)) +- Add a function to compare the OS version [#972](https://github.com/puppetlabs/puppetlabs-stdlib/pull/972) ([ekohl](https://github.com/ekohl)) +- (MODULES-8273) - Make unquoted classes useable [#971](https://github.com/puppetlabs/puppetlabs-stdlib/pull/971) ([baurmatt](https://github.com/baurmatt)) +- add Function extname() [#949](https://github.com/puppetlabs/puppetlabs-stdlib/pull/949) ([cocker-cc](https://github.com/cocker-cc)) +- (MODULES-7024) Add 20-octet MAC addresses [#905](https://github.com/puppetlabs/puppetlabs-stdlib/pull/905) ([ananace](https://github.com/ananace)) -##### 2011-11-08 Puppet Labs - 2.2.0 +### Fixed -* #10285 - Refactor json to use pson instead. -* Maint - Add watchr autotest script -* Maint - Make rspec tests work with Puppet 2.6.4 -* #9859 - Add root\_home fact and tests +- pdksync - (FM-7655) Fix rubygems-update for ruby < 2.3 [#979](https://github.com/puppetlabs/puppetlabs-stdlib/pull/979) ([tphoney](https://github.com/tphoney)) +- fix ensure_packages duplicate checking [#969](https://github.com/puppetlabs/puppetlabs-stdlib/pull/969) ([netzvieh](https://github.com/netzvieh)) -##### 2011-08-18 Puppet Labs - 2.1.1 +## [5.1.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/5.1.0) - 2018-10-01 -* Change facts.d paths to match Facter 2.0 paths. -* /etc/facter/facts.d -* /etc/puppetlabs/facter/facts.d +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/5.0.0...5.1.0) -##### 2011-08-17 Puppet Labs - 2.1.0 +### Added -* Add R.I. Pienaar's facts.d custom facter fact -* facts defined in /etc/facts.d and /etc/puppetlabs/facts.d are - automatically loaded now. +- pdksync - (MODULES-6805) metadata.json shows support for puppet 6 [#958](https://github.com/puppetlabs/puppetlabs-stdlib/pull/958) ([tphoney](https://github.com/tphoney)) +- (maint) Convert from mocking with mocha to rspec-mocks [#948](https://github.com/puppetlabs/puppetlabs-stdlib/pull/948) ([rodjek](https://github.com/rodjek)) -##### 2011-08-04 Puppet Labs - 2.0.0 +### Fixed -* Rename whole\_line to file\_line -* This is an API change and as such motivating a 2.0.0 release according to semver.org. +- (FM-7388) - Fixing unit tests for puppet 4, 5 and 6 [#962](https://github.com/puppetlabs/puppetlabs-stdlib/pull/962) ([tphoney](https://github.com/tphoney)) +- (MODULES-7768) Handle nil in delete_undef_values() function [#954](https://github.com/puppetlabs/puppetlabs-stdlib/pull/954) ([hlindberg](https://github.com/hlindberg)) +- Update docs for 'concat' to be correct [#950](https://github.com/puppetlabs/puppetlabs-stdlib/pull/950) ([rhowe-gds](https://github.com/rhowe-gds)) -##### 2011-08-04 Puppet Labs - 1.1.0 +## [5.0.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/5.0.0) - 2018-08-22 -* Rename append\_line to whole\_line -* This is an API change and as such motivating a 1.1.0 release. +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.25.1...5.0.0) -##### 2011-08-04 Puppet Labs - 1.0.0 +### Added -* Initial stable release -* Add validate\_array and validate\_string functions -* Make merge() function work with Ruby 1.8.5 -* Add hash merging function -* Add has\_key function -* Add loadyaml() function -* Add append\_line native +- (MODULES-7541) http type checks case insensitive [#934](https://github.com/puppetlabs/puppetlabs-stdlib/pull/934) ([tphoney](https://github.com/tphoney)) +- (MODULES-7440) Update Stdlib to support Ubuntu 18.04 [#932](https://github.com/puppetlabs/puppetlabs-stdlib/pull/932) ([david22swan](https://github.com/david22swan)) +- Allow loadyaml() and loadjason() to accept URLs with HTTP basic auth [#923](https://github.com/puppetlabs/puppetlabs-stdlib/pull/923) ([jonnytdevops](https://github.com/jonnytdevops)) +- Load https file into loadjson() and loadyaml() [#918](https://github.com/puppetlabs/puppetlabs-stdlib/pull/918) ([jonnytdevops](https://github.com/jonnytdevops)) +- Add support for symbolic file modes [#915](https://github.com/puppetlabs/puppetlabs-stdlib/pull/915) ([runejuhl](https://github.com/runejuhl)) +- (MODULES-7181) Remove Stdlib::(Ipv4|IPv6|Ip_address) [#909](https://github.com/puppetlabs/puppetlabs-stdlib/pull/909) ([baurmatt](https://github.com/baurmatt)) +- Allow pick() to work with strict variables [#890](https://github.com/puppetlabs/puppetlabs-stdlib/pull/890) ([binford2k](https://github.com/binford2k)) +- seeded_rand_string() function [#877](https://github.com/puppetlabs/puppetlabs-stdlib/pull/877) ([pegasd](https://github.com/pegasd)) -##### 2011-06-21 Jeff McCune - 0.1.7 +### Fixed -* Add validate\_hash() and getvar() functions +- Make any2array return empty array on empty string [#930](https://github.com/puppetlabs/puppetlabs-stdlib/pull/930) ([jbro](https://github.com/jbro)) +- Revert "Allow pick() to work with strict variables" [#927](https://github.com/puppetlabs/puppetlabs-stdlib/pull/927) ([mwhahaha](https://github.com/mwhahaha)) +- (docs) update documentation wrt functions moved to puppet [#922](https://github.com/puppetlabs/puppetlabs-stdlib/pull/922) ([hlindberg](https://github.com/hlindberg)) -##### 2011-06-15 Jeff McCune - 0.1.6 +## [4.25.1](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.25.1) - 2018-04-04 -* Add anchor resource type to provide containment for composite classes +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.25.0...4.25.1) -##### 2011-06-03 Jeff McCune - 0.1.5 +## [4.25.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.25.0) - 2018-03-13 -* Add validate\_bool() function to stdlib +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.24.0...4.25.0) -##### 0.1.4 2011-05-26 Jeff McCune +### Added -* Move most stages after main +- (MODULES-6366) Add data types for IP validation [#872](https://github.com/puppetlabs/puppetlabs-stdlib/pull/872) ([ghoneycutt](https://github.com/ghoneycutt)) +- add Stdlib::Fqdn and Stdlib::Host [#842](https://github.com/puppetlabs/puppetlabs-stdlib/pull/842) ([b4ldr](https://github.com/b4ldr)) +- add Stdlib::Filesource [#841](https://github.com/puppetlabs/puppetlabs-stdlib/pull/841) ([b4ldr](https://github.com/b4ldr)) +- add Stdlib::base64 and Stdlib::Base32 types [#840](https://github.com/puppetlabs/puppetlabs-stdlib/pull/840) ([b4ldr](https://github.com/b4ldr)) +- add Stdlib::Port, Stdlib::Privilegedport & Stdlib::Unprivilegedport [#839](https://github.com/puppetlabs/puppetlabs-stdlib/pull/839) ([b4ldr](https://github.com/b4ldr)) -##### 0.1.3 2011-05-25 Jeff McCune +### Fixed -* Add validate\_re() function +- Handle join_keys_to_values() with undef values. [#874](https://github.com/puppetlabs/puppetlabs-stdlib/pull/874) ([BobVanB](https://github.com/BobVanB)) +- FixToAccountForVersionChange [#867](https://github.com/puppetlabs/puppetlabs-stdlib/pull/867) ([david22swan](https://github.com/david22swan)) -##### 0.1.2 2011-05-24 Jeff McCune +## [4.24.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.24.0) - 2017-12-08 -* Update to add annotated tag +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.23.0...4.24.0) -##### 0.1.1 2011-05-24 Jeff McCune +### Fixed -* Add stdlib::stages class with a standard set of stages +- (MODULES-6216) - Fix type3x function in stdlib [#861](https://github.com/puppetlabs/puppetlabs-stdlib/pull/861) ([pmcmaw](https://github.com/pmcmaw)) + +## [4.23.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.23.0) - 2017-11-24 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.22.0...4.23.0) + +## [4.22.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.22.0) - 2017-11-15 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.21.0...4.22.0) + +### Fixed + +- Fixes a minor typo [#845](https://github.com/puppetlabs/puppetlabs-stdlib/pull/845) ([jbondpdx](https://github.com/jbondpdx)) + +## [4.21.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.21.0) - 2017-11-03 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.20.0...4.21.0) + +### Added + +- Add Stdlib::Mode type [#834](https://github.com/puppetlabs/puppetlabs-stdlib/pull/834) ([ghoneycutt](https://github.com/ghoneycutt)) +- (MODULES-5680) Added new function sprintf_hash to allow using named references [#824](https://github.com/puppetlabs/puppetlabs-stdlib/pull/824) ([vStone](https://github.com/vStone)) +- (MODULES-5679) Add a new function ifelse to match ruby's tenary operator [#823](https://github.com/puppetlabs/puppetlabs-stdlib/pull/823) ([vStone](https://github.com/vStone)) +- Add a type for ensure on service resources [#750](https://github.com/puppetlabs/puppetlabs-stdlib/pull/750) ([npwalker](https://github.com/npwalker)) + +### Fixed + +- Revert "(MODULES-5679) Add a new function ifelse to match ruby's tenary operator" [#832](https://github.com/puppetlabs/puppetlabs-stdlib/pull/832) ([david22swan](https://github.com/david22swan)) +- (maint) Fix example syntax [#829](https://github.com/puppetlabs/puppetlabs-stdlib/pull/829) ([binford2k](https://github.com/binford2k)) +- correct test cases to properly check result [#826](https://github.com/puppetlabs/puppetlabs-stdlib/pull/826) ([felixdoerre](https://github.com/felixdoerre)) +- (MODULES-5651) Do not append infinitely [#825](https://github.com/puppetlabs/puppetlabs-stdlib/pull/825) ([hunner](https://github.com/hunner)) +- use single quotes in validate_legacy example code [#816](https://github.com/puppetlabs/puppetlabs-stdlib/pull/816) ([mutante](https://github.com/mutante)) +- Allow root as valid UNIX path [#811](https://github.com/puppetlabs/puppetlabs-stdlib/pull/811) ([kofrezo](https://github.com/kofrezo)) +- Fix filenames of two function spec tests [#777](https://github.com/puppetlabs/puppetlabs-stdlib/pull/777) ([alexjfisher](https://github.com/alexjfisher)) + +## [4.20.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.20.0) - 2017-09-11 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.19.0...4.20.0) + +### Added + +- (MODULES-5546) add check for pw_hash [#810](https://github.com/puppetlabs/puppetlabs-stdlib/pull/810) ([eputnam](https://github.com/eputnam)) +- Added to_json, to_json_pretty, and to_yaml functions [#809](https://github.com/puppetlabs/puppetlabs-stdlib/pull/809) ([WhatsARanjit](https://github.com/WhatsARanjit)) + +## [4.19.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.19.0) - 2017-08-21 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.18.0...4.19.0) + +## [4.18.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.18.0) - 2017-08-11 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.17.1...4.18.0) + +### Added + +- MODULES-5382 Add documentation for email functions [#800](https://github.com/puppetlabs/puppetlabs-stdlib/pull/800) ([tphoney](https://github.com/tphoney)) +- add type for MAC address [#796](https://github.com/puppetlabs/puppetlabs-stdlib/pull/796) ([bastelfreak](https://github.com/bastelfreak)) +- (MODULES-4908) adds support for sensitive data type to pw_hash [#791](https://github.com/puppetlabs/puppetlabs-stdlib/pull/791) ([eputnam](https://github.com/eputnam)) +- (FACT-932) Add new function, fact() [#787](https://github.com/puppetlabs/puppetlabs-stdlib/pull/787) ([reidmv](https://github.com/reidmv)) +- Add validate_domain_name function [#753](https://github.com/puppetlabs/puppetlabs-stdlib/pull/753) ([frapex](https://github.com/frapex)) +- Add a round function to complement ceiling and floor [#748](https://github.com/puppetlabs/puppetlabs-stdlib/pull/748) ([npwalker](https://github.com/npwalker)) +- Add new file_line option append_on_no_match [#717](https://github.com/puppetlabs/puppetlabs-stdlib/pull/717) ([ripclawffb](https://github.com/ripclawffb)) + +### Fixed + +- MODULES-5440 fix upper bound for puppet [#803](https://github.com/puppetlabs/puppetlabs-stdlib/pull/803) ([tphoney](https://github.com/tphoney)) +- (MODULES-5003) file_line does not change multiple lines when one matches [#794](https://github.com/puppetlabs/puppetlabs-stdlib/pull/794) ([tkishel](https://github.com/tkishel)) +- (MODULES-5003) file_line fix all broken lines [#788](https://github.com/puppetlabs/puppetlabs-stdlib/pull/788) ([tphoney](https://github.com/tphoney)) +- (MODULES-5113) Make line support Sensitive [#786](https://github.com/puppetlabs/puppetlabs-stdlib/pull/786) ([reidmv](https://github.com/reidmv)) +- Fix headers in CHANGELOG.md so that headers render correctly [#783](https://github.com/puppetlabs/puppetlabs-stdlib/pull/783) ([davewongillies](https://github.com/davewongillies)) +- (Modules 4377) Causes ensure_packages to accept concurrent declarations with ensure => 'present' and 'installed' [#716](https://github.com/puppetlabs/puppetlabs-stdlib/pull/716) ([EmersonPrado](https://github.com/EmersonPrado)) + +## [4.17.1](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.17.1) - 2017-06-16 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.17.0...4.17.1) + +### Fixed + +- (MODULES-5095) Workaround for PUP-7650 [#780](https://github.com/puppetlabs/puppetlabs-stdlib/pull/780) ([thallgren](https://github.com/thallgren)) +- (FM-6197) formatting fixes for file_line resource [#779](https://github.com/puppetlabs/puppetlabs-stdlib/pull/779) ([jbondpdx](https://github.com/jbondpdx)) + +## [4.17.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.17.0) - 2017-05-10 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.16.0...4.17.0) + +### Added + +- (FM-6116) - Adding POT file for metadata.json [#746](https://github.com/puppetlabs/puppetlabs-stdlib/pull/746) ([pmcmaw](https://github.com/pmcmaw)) +- Add glob function [#718](https://github.com/puppetlabs/puppetlabs-stdlib/pull/718) ([sspreitzer](https://github.com/sspreitzer)) + +### Fixed + +- (MODULES-4706) prerelease fixes [#771](https://github.com/puppetlabs/puppetlabs-stdlib/pull/771) ([eputnam](https://github.com/eputnam)) +- (MODULES-4706) prerelease fixes [#770](https://github.com/puppetlabs/puppetlabs-stdlib/pull/770) ([jbondpdx](https://github.com/jbondpdx)) +- (PE-20308) Fix defined_with_params() for defined type strings & references [#765](https://github.com/puppetlabs/puppetlabs-stdlib/pull/765) ([hunner](https://github.com/hunner)) +- (PE-20308) Correct boundary for 4.5 vs 4.6 [#763](https://github.com/puppetlabs/puppetlabs-stdlib/pull/763) ([hunner](https://github.com/hunner)) +- (PE-20308) Pass a literal type and not a string to findresource [#761](https://github.com/puppetlabs/puppetlabs-stdlib/pull/761) ([hunner](https://github.com/hunner)) +- Ruby 1.8 doesn't support open_args [#758](https://github.com/puppetlabs/puppetlabs-stdlib/pull/758) ([sathieu](https://github.com/sathieu)) +- [MODULES-4528] Replace Puppet.version.to_f version comparison from spec_helper.rb [#745](https://github.com/puppetlabs/puppetlabs-stdlib/pull/745) ([wilson208](https://github.com/wilson208)) + +## [4.16.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.16.0) - 2017-03-21 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.15.0...4.16.0) + +### Added + +- (FM-6051) Adds comments to warn for UTF8 incompatibility [#741](https://github.com/puppetlabs/puppetlabs-stdlib/pull/741) ([HelenCampbell](https://github.com/HelenCampbell)) +- Addition of new length function [#736](https://github.com/puppetlabs/puppetlabs-stdlib/pull/736) ([HelenCampbell](https://github.com/HelenCampbell)) +- (FM-6086) - Unit tests for Resource Types [#734](https://github.com/puppetlabs/puppetlabs-stdlib/pull/734) ([pmcmaw](https://github.com/pmcmaw)) +- (FM-6063) - Unit tests for high effort functions [#732](https://github.com/puppetlabs/puppetlabs-stdlib/pull/732) ([pmcmaw](https://github.com/pmcmaw)) +- (MODULES-4485) Improve ipv6 support for type [#731](https://github.com/puppetlabs/puppetlabs-stdlib/pull/731) ([petems](https://github.com/petems)) +- (#FM-6068) allow file encoding to be specified [#726](https://github.com/puppetlabs/puppetlabs-stdlib/pull/726) ([GeoffWilliams](https://github.com/GeoffWilliams)) + +### Fixed + +- Permit double slash in absolute/Unix path types [#740](https://github.com/puppetlabs/puppetlabs-stdlib/pull/740) ([domcleal](https://github.com/domcleal)) +- (MODULES-4528) Use versioncmp to check Puppet version for 4.10.x compat [#737](https://github.com/puppetlabs/puppetlabs-stdlib/pull/737) ([domcleal](https://github.com/domcleal)) +- Should only try to apply the resource if it not defined [#735](https://github.com/puppetlabs/puppetlabs-stdlib/pull/735) ([elmobp](https://github.com/elmobp)) +- loosen the regex for tuple checking [#728](https://github.com/puppetlabs/puppetlabs-stdlib/pull/728) ([tphoney](https://github.com/tphoney)) +- Fix acceptance test failure "Hiera is not a class" [#720](https://github.com/puppetlabs/puppetlabs-stdlib/pull/720) ([DavidS](https://github.com/DavidS)) +- Fix unsupported data type error with rspec-puppet master [#715](https://github.com/puppetlabs/puppetlabs-stdlib/pull/715) ([domcleal](https://github.com/domcleal)) + +## [4.15.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.15.0) - 2017-01-20 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.14.0...4.15.0) + +### Added + +- Implement beaker-module_install_helper [#713](https://github.com/puppetlabs/puppetlabs-stdlib/pull/713) ([wilson208](https://github.com/wilson208)) +- Addition of compat hash type for deprecation [#708](https://github.com/puppetlabs/puppetlabs-stdlib/pull/708) ([HelenCampbell](https://github.com/HelenCampbell)) +- add ubuntu xenial to metadata [#705](https://github.com/puppetlabs/puppetlabs-stdlib/pull/705) ([eputnam](https://github.com/eputnam)) +- (MODULES-4188) Add UUID generation function [#700](https://github.com/puppetlabs/puppetlabs-stdlib/pull/700) ([petems](https://github.com/petems)) +- Add pry() function from hunner-pry [#640](https://github.com/puppetlabs/puppetlabs-stdlib/pull/640) ([hunner](https://github.com/hunner)) +- Add puppet_server fact to return agent's server [#613](https://github.com/puppetlabs/puppetlabs-stdlib/pull/613) ([reidmv](https://github.com/reidmv)) + +## [4.14.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.14.0) - 2016-12-12 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.13.1...4.14.0) + +### Added + +- (MODULES-3829) Add tests for ensure_resources [#697](https://github.com/puppetlabs/puppetlabs-stdlib/pull/697) ([HAIL9000](https://github.com/HAIL9000)) +- Addition of 4.6 and 4.7 travis cells [#686](https://github.com/puppetlabs/puppetlabs-stdlib/pull/686) ([HelenCampbell](https://github.com/HelenCampbell)) +- Handle array values in join_keys_to_values function [#632](https://github.com/puppetlabs/puppetlabs-stdlib/pull/632) ([edestecd](https://github.com/edestecd)) + +### Fixed + +- (MODULES-3393) Deprecation - Use puppet stacktrace if available [#693](https://github.com/puppetlabs/puppetlabs-stdlib/pull/693) ([HelenCampbell](https://github.com/HelenCampbell)) +- Revert "Call site output for deprecation warnings" [#692](https://github.com/puppetlabs/puppetlabs-stdlib/pull/692) ([bmjen](https://github.com/bmjen)) +- Fix spec failures on puppet 4.8 [#689](https://github.com/puppetlabs/puppetlabs-stdlib/pull/689) ([DavidS](https://github.com/DavidS)) +- (MODULES-3829) Use .dup to duplicate classes for modification. [#687](https://github.com/puppetlabs/puppetlabs-stdlib/pull/687) ([MG2R](https://github.com/MG2R)) +- (MODULES-3980) Fix ipv4 regex validator [#680](https://github.com/puppetlabs/puppetlabs-stdlib/pull/680) ([DavidS](https://github.com/DavidS)) + +## [4.13.1](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.13.1) - 2016-10-13 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.13.0...4.13.1) + +## [4.13.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.13.0) - 2016-10-11 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.12.0...4.13.0) + +### Added + +- Add deprecation warnings to remaining validates [#656](https://github.com/puppetlabs/puppetlabs-stdlib/pull/656) ([HelenCampbell](https://github.com/HelenCampbell)) +- Addition of logging with file and line numbers [#651](https://github.com/puppetlabs/puppetlabs-stdlib/pull/651) ([HelenCampbell](https://github.com/HelenCampbell)) +- Add facter fact for puppet_environmentpath [#648](https://github.com/puppetlabs/puppetlabs-stdlib/pull/648) ([stbenjam](https://github.com/stbenjam)) +- (MODULES-3540) Addition of validate legacy function [#630](https://github.com/puppetlabs/puppetlabs-stdlib/pull/630) ([HelenCampbell](https://github.com/HelenCampbell)) +- Added documentation for regexpescape function. [#625](https://github.com/puppetlabs/puppetlabs-stdlib/pull/625) ([mooresm1](https://github.com/mooresm1)) +- Added the regexpescape function. [#624](https://github.com/puppetlabs/puppetlabs-stdlib/pull/624) ([mooresm1](https://github.com/mooresm1)) +- (MODULES-3529) add deprecation function [#617](https://github.com/puppetlabs/puppetlabs-stdlib/pull/617) ([tphoney](https://github.com/tphoney)) +- Add delete_regex [#605](https://github.com/puppetlabs/puppetlabs-stdlib/pull/605) ([jyaworski](https://github.com/jyaworski)) +- Add a missing s in the ensure_packages hash example [#604](https://github.com/puppetlabs/puppetlabs-stdlib/pull/604) ([rjw1](https://github.com/rjw1)) +- (MODULES-1439) Adds any2bool function [#601](https://github.com/puppetlabs/puppetlabs-stdlib/pull/601) ([petems](https://github.com/petems)) +- Add the default value to the "loadyaml" function [#600](https://github.com/puppetlabs/puppetlabs-stdlib/pull/600) ([dmitryilyin](https://github.com/dmitryilyin)) + +### Fixed + +- (MODULES-3590) Fix match_for_absence parameter [#666](https://github.com/puppetlabs/puppetlabs-stdlib/pull/666) ([HAIL9000](https://github.com/HAIL9000)) +- Ignore :undefined_variable "reason" in getvar [#665](https://github.com/puppetlabs/puppetlabs-stdlib/pull/665) ([mks-m](https://github.com/mks-m)) +- (MODULES-3933) Fix getparam for 'false' values [#663](https://github.com/puppetlabs/puppetlabs-stdlib/pull/663) ([DavidS](https://github.com/DavidS)) +- Permit undef passed as `nil` to validate_string [#662](https://github.com/puppetlabs/puppetlabs-stdlib/pull/662) ([domcleal](https://github.com/domcleal)) +- Ensure validate functions use Puppet 4 deprecation [#659](https://github.com/puppetlabs/puppetlabs-stdlib/pull/659) ([HelenCampbell](https://github.com/HelenCampbell)) +- Revert "Ensure validate functions use Puppet 4 deprecation" [#655](https://github.com/puppetlabs/puppetlabs-stdlib/pull/655) ([HelenCampbell](https://github.com/HelenCampbell)) +- Ensure validate functions use Puppet 4 deprecation [#654](https://github.com/puppetlabs/puppetlabs-stdlib/pull/654) ([HelenCampbell](https://github.com/HelenCampbell)) +- Fix whitespace [#653](https://github.com/puppetlabs/puppetlabs-stdlib/pull/653) ([hunner](https://github.com/hunner)) +- MODULES-3699 Deprecation spec fix 2 [#646](https://github.com/puppetlabs/puppetlabs-stdlib/pull/646) ([eputnam](https://github.com/eputnam)) +- Fix markdown indentation [#631](https://github.com/puppetlabs/puppetlabs-stdlib/pull/631) ([smortex](https://github.com/smortex)) +- Fix str2bool error message [#626](https://github.com/puppetlabs/puppetlabs-stdlib/pull/626) ([LoicGombeaud](https://github.com/LoicGombeaud)) +- (MODULES-3543) Fixup defined_with_params to work on all puppet versions [#615](https://github.com/puppetlabs/puppetlabs-stdlib/pull/615) ([DavidS](https://github.com/DavidS)) +- (MODULES-3543) Fix define_with_params to handle undef properly [#614](https://github.com/puppetlabs/puppetlabs-stdlib/pull/614) ([DavidS](https://github.com/DavidS)) +- (MODULES-3354) Use 1.8.7 hash in validate_email_address function [#606](https://github.com/puppetlabs/puppetlabs-stdlib/pull/606) ([stbenjam](https://github.com/stbenjam)) +- Use reject instead of delete_if [#592](https://github.com/puppetlabs/puppetlabs-stdlib/pull/592) ([jyaworski](https://github.com/jyaworski)) + +## [4.12.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.12.0) - 2016-05-03 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.11.0...4.12.0) + +### Added + +- Add support for regular expressions to delete [#591](https://github.com/puppetlabs/puppetlabs-stdlib/pull/591) ([jyaworski](https://github.com/jyaworski)) +- Add validate_email_address function [#583](https://github.com/puppetlabs/puppetlabs-stdlib/pull/583) ([jyaworski](https://github.com/jyaworski)) +- Add check if Gem is defined [#579](https://github.com/puppetlabs/puppetlabs-stdlib/pull/579) ([sulaweyo](https://github.com/sulaweyo)) +- Add enclose_ipv6 function [#577](https://github.com/puppetlabs/puppetlabs-stdlib/pull/577) ([EmilienM](https://github.com/EmilienM)) +- ensure_packages.rb: Modifed to pass hiera parameters (as hash,array) as first argument [#576](https://github.com/puppetlabs/puppetlabs-stdlib/pull/576) ([yadavnikhil](https://github.com/yadavnikhil)) +- Extend Base64() function support [#575](https://github.com/puppetlabs/puppetlabs-stdlib/pull/575) ([guessi](https://github.com/guessi)) +- Add dig function [#573](https://github.com/puppetlabs/puppetlabs-stdlib/pull/573) ([mks-m](https://github.com/mks-m)) +- Add is_ipv4_address and is_ipv6_address functions [#570](https://github.com/puppetlabs/puppetlabs-stdlib/pull/570) ([gfidente](https://github.com/gfidente)) +- Add test for basename on path with scheme [#567](https://github.com/puppetlabs/puppetlabs-stdlib/pull/567) ([alechenninger](https://github.com/alechenninger)) + +### Fixed + +- Undo changing delete() to delete regex matches [#599](https://github.com/puppetlabs/puppetlabs-stdlib/pull/599) ([hunner](https://github.com/hunner)) +- (MODULES-3271) Ensure that is_email_address works on unsupported rubies [#598](https://github.com/puppetlabs/puppetlabs-stdlib/pull/598) ([DavidS](https://github.com/DavidS)) +- (MODULES-3246) Fix concat with Hash arguments. [#590](https://github.com/puppetlabs/puppetlabs-stdlib/pull/590) ([alext](https://github.com/alext)) +- (maint) Fixes fqdn_rand_string tests [#578](https://github.com/puppetlabs/puppetlabs-stdlib/pull/578) ([bmjen](https://github.com/bmjen)) +- Fix reference to validate_bool in function [#568](https://github.com/puppetlabs/puppetlabs-stdlib/pull/568) ([mattbostock](https://github.com/mattbostock)) + +## [4.11.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.11.0) - 2016-01-11 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.10.0...4.11.0) + +### Added + +- minor tweak to 4.11.0 adding debian 8 to metadata [#565](https://github.com/puppetlabs/puppetlabs-stdlib/pull/565) ([tphoney](https://github.com/tphoney)) +- Allow package_provider fact to resolve on PE 3.x [#561](https://github.com/puppetlabs/puppetlabs-stdlib/pull/561) ([DavidS](https://github.com/DavidS)) +- adds new parser called is_absolute_path [#553](https://github.com/puppetlabs/puppetlabs-stdlib/pull/553) ([logicminds](https://github.com/logicminds)) +- Add a function to validate an x509 RSA key pair [#552](https://github.com/puppetlabs/puppetlabs-stdlib/pull/552) ([mattbostock](https://github.com/mattbostock)) +- Add clamp function [#545](https://github.com/puppetlabs/puppetlabs-stdlib/pull/545) ([mpolenchuk](https://github.com/mpolenchuk)) + +## [4.10.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.10.0) - 2015-12-15 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.9.1...4.10.0) + +### Added + +- (#2886) seeded_rand: new function [#554](https://github.com/puppetlabs/puppetlabs-stdlib/pull/554) ([kjetilho](https://github.com/kjetilho)) + +## [4.9.1](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.9.1) - 2015-12-04 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.9.0...4.9.1) + +### Added + +- Add validator for any IP address [#546](https://github.com/puppetlabs/puppetlabs-stdlib/pull/546) ([devvesa](https://github.com/devvesa)) +- Add check to ensure regex does not throw for none type. [#539](https://github.com/puppetlabs/puppetlabs-stdlib/pull/539) ([mentat](https://github.com/mentat)) +- add functionality to bool2str function [#538](https://github.com/puppetlabs/puppetlabs-stdlib/pull/538) ([mmckinst](https://github.com/mmckinst)) +- Add package_provider fact [#534](https://github.com/puppetlabs/puppetlabs-stdlib/pull/534) ([asasfu](https://github.com/asasfu)) +- (MODULES-2561) add is_a function [#523](https://github.com/puppetlabs/puppetlabs-stdlib/pull/523) ([DavidS](https://github.com/DavidS)) +- accept any case of boolean strings [#518](https://github.com/puppetlabs/puppetlabs-stdlib/pull/518) ([logicminds](https://github.com/logicminds)) +- [MODULES-2462] Improve parseyaml function [#511](https://github.com/puppetlabs/puppetlabs-stdlib/pull/511) ([dmitryilyin](https://github.com/dmitryilyin)) +- Add a service_provider fact [#506](https://github.com/puppetlabs/puppetlabs-stdlib/pull/506) ([binford2k](https://github.com/binford2k)) + +### Fixed + +- Fix reference to validate_bool in IP4 function [#551](https://github.com/puppetlabs/puppetlabs-stdlib/pull/551) ([mattbostock](https://github.com/mattbostock)) +- Fix Gemfile to work with ruby 1.8.7 [#548](https://github.com/puppetlabs/puppetlabs-stdlib/pull/548) ([bmjen](https://github.com/bmjen)) +- (FM-3773) Fix root_home fact on AIX 5.x [#547](https://github.com/puppetlabs/puppetlabs-stdlib/pull/547) ([reidmv](https://github.com/reidmv)) +- Use absolute class name in example [#543](https://github.com/puppetlabs/puppetlabs-stdlib/pull/543) ([ghoneycutt](https://github.com/ghoneycutt)) +- use properly encoded characters [#542](https://github.com/puppetlabs/puppetlabs-stdlib/pull/542) ([greg0ire](https://github.com/greg0ire)) +- Fix load module metadata [#537](https://github.com/puppetlabs/puppetlabs-stdlib/pull/537) ([cmurphy](https://github.com/cmurphy)) +- prevent deprecation warning about the allow_virtual parameter [#535](https://github.com/puppetlabs/puppetlabs-stdlib/pull/535) ([martinpfeifer](https://github.com/martinpfeifer)) +- Fix backwards compatibility from #511 [#527](https://github.com/puppetlabs/puppetlabs-stdlib/pull/527) ([underscorgan](https://github.com/underscorgan)) + +## [4.9.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.9.0) - 2015-09-08 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.8.0...4.9.0) + +### Added + +- Adds a convert_base function, which can convert numbers between bases [#514](https://github.com/puppetlabs/puppetlabs-stdlib/pull/514) ([DavidS](https://github.com/DavidS)) +- Add a new function "try_get_value" [#513](https://github.com/puppetlabs/puppetlabs-stdlib/pull/513) ([dmitryilyin](https://github.com/dmitryilyin)) +- (MODULES-2456) Modify union to accept more than two arrays [#507](https://github.com/puppetlabs/puppetlabs-stdlib/pull/507) ([Jetroid](https://github.com/Jetroid)) +- (MODULES-2410) Add new functions dos2unix and unix2dos [#505](https://github.com/puppetlabs/puppetlabs-stdlib/pull/505) ([gibbsoft](https://github.com/gibbsoft)) + +### Fixed + +- (MAINT) fix up try_get_value acceptance test [#517](https://github.com/puppetlabs/puppetlabs-stdlib/pull/517) ([DavidS](https://github.com/DavidS)) +- Ticket/MODULES-2478 Make root_home fact work on AIX using native lsuser command [#515](https://github.com/puppetlabs/puppetlabs-stdlib/pull/515) ([jfautley](https://github.com/jfautley)) + +## [4.8.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.8.0) - 2015-08-12 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.7.0...4.8.0) + +### Added + +- [#puppethack] Adding replace attribute to file_line [#494](https://github.com/puppetlabs/puppetlabs-stdlib/pull/494) ([rmaika](https://github.com/rmaika)) +- Add load_metadata_json function [#483](https://github.com/puppetlabs/puppetlabs-stdlib/pull/483) ([nibalizer](https://github.com/nibalizer)) + +### Fixed + +- Fix extraneous end [#501](https://github.com/puppetlabs/puppetlabs-stdlib/pull/501) ([hunner](https://github.com/hunner)) +- (MODULES-2316) Change file_type boolean parameter to symbols [#497](https://github.com/puppetlabs/puppetlabs-stdlib/pull/497) ([domcleal](https://github.com/domcleal)) +- Style fixes [#491](https://github.com/puppetlabs/puppetlabs-stdlib/pull/491) ([ekohl](https://github.com/ekohl)) + +## [4.7.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.7.0) - 2015-07-23 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.6.0...4.7.0) + +### Added + +- adding support for hash in the size function [#489](https://github.com/puppetlabs/puppetlabs-stdlib/pull/489) ([gcmalloc](https://github.com/gcmalloc)) +- Add support for Solaris 12 [#478](https://github.com/puppetlabs/puppetlabs-stdlib/pull/478) ([drewfisher314](https://github.com/drewfisher314)) +- (FM-2130) Document new location of facts.d cache [#454](https://github.com/puppetlabs/puppetlabs-stdlib/pull/454) ([elyscape](https://github.com/elyscape)) + +### Fixed + +- (maint) Fix test to not assume is_pe fact on > 4.0.0 puppet [#488](https://github.com/puppetlabs/puppetlabs-stdlib/pull/488) ([cyberious](https://github.com/cyberious)) +- Fix documentation error in upcase [#487](https://github.com/puppetlabs/puppetlabs-stdlib/pull/487) ([liv3d](https://github.com/liv3d)) +- Clarify that third argument to ensure_resource() is a hash [#485](https://github.com/puppetlabs/puppetlabs-stdlib/pull/485) ([ghoneycutt](https://github.com/ghoneycutt)) +- Use puppet_install_helper [#484](https://github.com/puppetlabs/puppetlabs-stdlib/pull/484) ([underscorgan](https://github.com/underscorgan)) +- catch and rescue from looking up non-existent facts [#479](https://github.com/puppetlabs/puppetlabs-stdlib/pull/479) ([mklette](https://github.com/mklette)) +- AIO uses puppet 4 so should return true for is_future_parser_enabled [#477](https://github.com/puppetlabs/puppetlabs-stdlib/pull/477) ([underscorgan](https://github.com/underscorgan)) +- Also catch :undefined_variable as thrown by future parser [#470](https://github.com/puppetlabs/puppetlabs-stdlib/pull/470) ([bobtfish](https://github.com/bobtfish)) +- Fix time() on 1.8.7 [#469](https://github.com/puppetlabs/puppetlabs-stdlib/pull/469) ([hunner](https://github.com/hunner)) +- Fix spelling of camelcase [#468](https://github.com/puppetlabs/puppetlabs-stdlib/pull/468) ([kylog](https://github.com/kylog)) +- (MODULES-1882) convert function tests to rspec-puppet [#464](https://github.com/puppetlabs/puppetlabs-stdlib/pull/464) ([DavidS](https://github.com/DavidS)) +- (MODULES-2071) Patch file_line provider to use multiple with after [#463](https://github.com/puppetlabs/puppetlabs-stdlib/pull/463) ([rmaika](https://github.com/rmaika)) +- fqdn_rotate: Don't use the value itself as part of the random seed [#462](https://github.com/puppetlabs/puppetlabs-stdlib/pull/462) ([elyscape](https://github.com/elyscape)) +- validate_integer, validate_numeric: explicitely reject hashes in arrays [#461](https://github.com/puppetlabs/puppetlabs-stdlib/pull/461) ([DavidS](https://github.com/DavidS)) +- fqdn_rotate: reset srand seed correctly on old ruby versions [#460](https://github.com/puppetlabs/puppetlabs-stdlib/pull/460) ([DavidS](https://github.com/DavidS)) +- range(): fix TypeError(can't convert nil into Integer) when using range ... [#448](https://github.com/puppetlabs/puppetlabs-stdlib/pull/448) ([DavidS](https://github.com/DavidS)) +- Fix pw_hash() on JRuby < 1.7.17 [#446](https://github.com/puppetlabs/puppetlabs-stdlib/pull/446) ([elyscape](https://github.com/elyscape)) +- uses include type class declaration [#441](https://github.com/puppetlabs/puppetlabs-stdlib/pull/441) ([mrzarquon](https://github.com/mrzarquon)) +- fqdn_rand_string: fix argument error message [#440](https://github.com/puppetlabs/puppetlabs-stdlib/pull/440) ([DavidS](https://github.com/DavidS)) +- Check if file exists before loading with loadyaml. If not, return nil [#314](https://github.com/puppetlabs/puppetlabs-stdlib/pull/314) ([amateo](https://github.com/amateo)) + +## [4.6.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.6.0) - 2015-04-15 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.5.1...4.6.0) + +### Added + +- Modules-2474: Only runs enhanced salts functions test on systems that ... [#434](https://github.com/puppetlabs/puppetlabs-stdlib/pull/434) ([bmjen](https://github.com/bmjen)) +- Clarifying behaviour of attributes and adding an extra example. [#430](https://github.com/puppetlabs/puppetlabs-stdlib/pull/430) ([underscorgan](https://github.com/underscorgan)) +- (BKR-147) add Gemfile setting for BEAKER_VERSION for puppet... [#426](https://github.com/puppetlabs/puppetlabs-stdlib/pull/426) ([anodelman](https://github.com/anodelman)) +- Add ability to pin beaker versions [#423](https://github.com/puppetlabs/puppetlabs-stdlib/pull/423) ([cyberious](https://github.com/cyberious)) +- Add support for hashes in the prefix function [#420](https://github.com/puppetlabs/puppetlabs-stdlib/pull/420) ([underscorgan](https://github.com/underscorgan)) +- Loosen the restrictions of upcase and allow for recursion of the objects... [#419](https://github.com/puppetlabs/puppetlabs-stdlib/pull/419) ([cyberious](https://github.com/cyberious)) +- Add Hash to upcase [#417](https://github.com/puppetlabs/puppetlabs-stdlib/pull/417) ([cyberious](https://github.com/cyberious)) +- (MODULES-1737) Add pw_hash() function [#408](https://github.com/puppetlabs/puppetlabs-stdlib/pull/408) ([elyscape](https://github.com/elyscape)) +- Add a ceiling function to complement the floor function. [#407](https://github.com/puppetlabs/puppetlabs-stdlib/pull/407) ([adamcrews](https://github.com/adamcrews)) +- (MODULES-1715) Add FQDN-based random string generator [#405](https://github.com/puppetlabs/puppetlabs-stdlib/pull/405) ([elyscape](https://github.com/elyscape)) +- (MODULES-560) Add new functions validate_numeric() and validate_integer(). [#375](https://github.com/puppetlabs/puppetlabs-stdlib/pull/375) ([poikilotherm](https://github.com/poikilotherm)) + +### Fixed + +- Fix the 4.6.0 release date [#438](https://github.com/puppetlabs/puppetlabs-stdlib/pull/438) ([hunner](https://github.com/hunner)) +- Fix acceptance tests for #405 [#433](https://github.com/puppetlabs/puppetlabs-stdlib/pull/433) ([cmurphy](https://github.com/cmurphy)) +- Fix unsupported platforms variable name in tests [#432](https://github.com/puppetlabs/puppetlabs-stdlib/pull/432) ([cmurphy](https://github.com/cmurphy)) +- File_line checks provided after param if no match is found [#431](https://github.com/puppetlabs/puppetlabs-stdlib/pull/431) ([bmjen](https://github.com/bmjen)) +- Fix off-by-one error in validate_augeas_spec.rb that was causing rspec failure [#425](https://github.com/puppetlabs/puppetlabs-stdlib/pull/425) ([jeffcoat](https://github.com/jeffcoat)) +- Fix issue with 1.8.7 and upcase [#418](https://github.com/puppetlabs/puppetlabs-stdlib/pull/418) ([cyberious](https://github.com/cyberious)) +- Check for string before copying [#413](https://github.com/puppetlabs/puppetlabs-stdlib/pull/413) ([underscorgan](https://github.com/underscorgan)) +- (MODULES-1771) Don't modify input to is_domain_name() [#412](https://github.com/puppetlabs/puppetlabs-stdlib/pull/412) ([seanmil](https://github.com/seanmil)) +- Fix Travis builds [#411](https://github.com/puppetlabs/puppetlabs-stdlib/pull/411) ([elyscape](https://github.com/elyscape)) +- (MODULES-1738) Don't modify the global seed in fqdn_rotate() [#406](https://github.com/puppetlabs/puppetlabs-stdlib/pull/406) ([elyscape](https://github.com/elyscape)) +- (MODULES-1670) Do not match dotted-quad IP address as domain name [#404](https://github.com/puppetlabs/puppetlabs-stdlib/pull/404) ([roderickm](https://github.com/roderickm)) +- Dirname typecheck [#369](https://github.com/puppetlabs/puppetlabs-stdlib/pull/369) ([rfugina](https://github.com/rfugina)) + +## [4.5.1](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.5.1) - 2015-01-14 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.5.0...4.5.1) + +### Added + +- MODULES-1606 add ability to pass array to delete for items to delete [#392](https://github.com/puppetlabs/puppetlabs-stdlib/pull/392) ([cyberious](https://github.com/cyberious)) +- MODULES-444-Add concat multiple [#374](https://github.com/puppetlabs/puppetlabs-stdlib/pull/374) ([petems](https://github.com/petems)) +- Allow array of pathes in validate_absolute_path [#372](https://github.com/puppetlabs/puppetlabs-stdlib/pull/372) ([poikilotherm](https://github.com/poikilotherm)) +- Basename implementation [#368](https://github.com/puppetlabs/puppetlabs-stdlib/pull/368) ([rfugina](https://github.com/rfugina)) + +### Fixed + +- FM-2131 Move to non temp directory for factor_dot_d [#401](https://github.com/puppetlabs/puppetlabs-stdlib/pull/401) ([cyberious](https://github.com/cyberious)) +- Pull in RSpec 3.0 fixes. [#398](https://github.com/puppetlabs/puppetlabs-stdlib/pull/398) ([cyberious](https://github.com/cyberious)) +- Change all to each [#396](https://github.com/puppetlabs/puppetlabs-stdlib/pull/396) ([hunner](https://github.com/hunner)) +- FM-2130 Move cache file to non temp directory [#395](https://github.com/puppetlabs/puppetlabs-stdlib/pull/395) ([cyberious](https://github.com/cyberious)) +- Fix bad check in test [#389](https://github.com/puppetlabs/puppetlabs-stdlib/pull/389) ([underscorgan](https://github.com/underscorgan)) +- (MODULES-1582) File location placeholder [#377](https://github.com/puppetlabs/puppetlabs-stdlib/pull/377) ([petems](https://github.com/petems)) +- ensure_resource: be more verbose in debug mode [#336](https://github.com/puppetlabs/puppetlabs-stdlib/pull/336) ([mklette](https://github.com/mklette)) +- Correct function name in changelog [#301](https://github.com/puppetlabs/puppetlabs-stdlib/pull/301) ([3flex](https://github.com/3flex)) + +## [4.5.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.5.0) - 2014-12-16 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.4.0...4.5.0) + +### Added + +- FM-2020 SLES Support verified [#371](https://github.com/puppetlabs/puppetlabs-stdlib/pull/371) ([cyberious](https://github.com/cyberious)) +- FM-1523: Added module summary to metadata.json [#370](https://github.com/puppetlabs/puppetlabs-stdlib/pull/370) ([jbondpdx](https://github.com/jbondpdx)) +- (MODULES-1329) Allow member to look for array [#319](https://github.com/puppetlabs/puppetlabs-stdlib/pull/319) ([Spredzy](https://github.com/Spredzy)) + +### Fixed + +- Need to convert strings and fixnums to arrays [#367](https://github.com/puppetlabs/puppetlabs-stdlib/pull/367) ([underscorgan](https://github.com/underscorgan)) +- Make the range function work with integers [#365](https://github.com/puppetlabs/puppetlabs-stdlib/pull/365) ([dalen](https://github.com/dalen)) +- (maint) Fix indentation of range function [#364](https://github.com/puppetlabs/puppetlabs-stdlib/pull/364) ([dalen](https://github.com/dalen)) + +## [4.4.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.4.0) - 2014-11-12 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.3.2...4.4.0) + +### Added + +- (QENG-1404) Segregate system testing gems [#356](https://github.com/puppetlabs/puppetlabs-stdlib/pull/356) ([justinstoller](https://github.com/justinstoller)) +- MODULES-1413 Add ability for member to take numeric objects [#350](https://github.com/puppetlabs/puppetlabs-stdlib/pull/350) ([cyberious](https://github.com/cyberious)) +- Add proper exception catching of Windows errors when CreateProcess does not succeed [#348](https://github.com/puppetlabs/puppetlabs-stdlib/pull/348) ([cyberious](https://github.com/cyberious)) +- Added correct converstions for PB and EB. [#343](https://github.com/puppetlabs/puppetlabs-stdlib/pull/343) ([big-samantha](https://github.com/big-samantha)) +- add require 'tempfile' to resolve a previously autorequired resource [#340](https://github.com/puppetlabs/puppetlabs-stdlib/pull/340) ([cyberious](https://github.com/cyberious)) +- (MODULES-1221) Add file_line autorequire documentation [#300](https://github.com/puppetlabs/puppetlabs-stdlib/pull/300) ([trlinkin](https://github.com/trlinkin)) + +### Fixed + +- Fix exclude windows test on ensure_package [#363](https://github.com/puppetlabs/puppetlabs-stdlib/pull/363) ([hunner](https://github.com/hunner)) +- Correct type() logic [#358](https://github.com/puppetlabs/puppetlabs-stdlib/pull/358) ([hunner](https://github.com/hunner)) +- Fix the unless for test cases on ensure_package and ensure_resource [#353](https://github.com/puppetlabs/puppetlabs-stdlib/pull/353) ([cyberious](https://github.com/cyberious)) +- Fix validate_cmd, previous addition of SystemCallError only works for Puppet 3.7, previous version throw different exception. Wrapping in generic Exception catch all [#349](https://github.com/puppetlabs/puppetlabs-stdlib/pull/349) ([cyberious](https://github.com/cyberious)) +- Fix issue with ensure_request [#347](https://github.com/puppetlabs/puppetlabs-stdlib/pull/347) ([cyberious](https://github.com/cyberious)) +- Spec_helper_acceptance fix provision section [#346](https://github.com/puppetlabs/puppetlabs-stdlib/pull/346) ([cyberious](https://github.com/cyberious)) +- Fix logic issue with not including windows for testing ensure_packages as ruby and gem are not on the install path [#345](https://github.com/puppetlabs/puppetlabs-stdlib/pull/345) ([cyberious](https://github.com/cyberious)) +- Fix testcases for Future Parser and resolve issue with values_at in assuming that it was dealing with a string [#344](https://github.com/puppetlabs/puppetlabs-stdlib/pull/344) ([cyberious](https://github.com/cyberious)) +- ENTERPRISE-281 fixes issue with has_interfaces and case mismatch causing... [#334](https://github.com/puppetlabs/puppetlabs-stdlib/pull/334) ([cyberious](https://github.com/cyberious)) +- MODULES-1248 Fix issue with not properly counting regex matches with leg... [#321](https://github.com/puppetlabs/puppetlabs-stdlib/pull/321) ([cyberious](https://github.com/cyberious)) +- Fix strict_variables = true [#303](https://github.com/puppetlabs/puppetlabs-stdlib/pull/303) ([bobtfish](https://github.com/bobtfish)) + +## [4.3.2](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.3.2) - 2014-07-16 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.3.1...4.3.2) + +## [4.3.1](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.3.1) - 2014-07-16 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.3.0...4.3.1) + +### Fixed + +- Correct metadata.json to match checksum [#297](https://github.com/puppetlabs/puppetlabs-stdlib/pull/297) ([hunner](https://github.com/hunner)) + +## [4.3.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.3.0) - 2014-07-09 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.2.2...4.3.0) + +### Added + +- AIX has no facter network support [#296](https://github.com/puppetlabs/puppetlabs-stdlib/pull/296) ([hunner](https://github.com/hunner)) +- Start synchronizing module files [#290](https://github.com/puppetlabs/puppetlabs-stdlib/pull/290) ([cmurphy](https://github.com/cmurphy)) +- stdlib 4 isn't compatible with PE 3.2 [#286](https://github.com/puppetlabs/puppetlabs-stdlib/pull/286) ([hunner](https://github.com/hunner)) +- Increase resilience if lookup var comes back with nil object [#284](https://github.com/puppetlabs/puppetlabs-stdlib/pull/284) ([cyberious](https://github.com/cyberious)) +- Add windows support and work around issue with SCP_TO on windows systems [#283](https://github.com/puppetlabs/puppetlabs-stdlib/pull/283) ([cyberious](https://github.com/cyberious)) +- Add windows Nodesets and remove Beaker from Gemfile [#278](https://github.com/puppetlabs/puppetlabs-stdlib/pull/278) ([cyberious](https://github.com/cyberious)) +- Add private() function [#270](https://github.com/puppetlabs/puppetlabs-stdlib/pull/270) ([raphink](https://github.com/raphink)) + +### Fixed + +- Gotta single quote yer typewriter buttons [#293](https://github.com/puppetlabs/puppetlabs-stdlib/pull/293) ([hunner](https://github.com/hunner)) +- Need quotes for spaces in path [#292](https://github.com/puppetlabs/puppetlabs-stdlib/pull/292) ([hunner](https://github.com/hunner)) +- has_ip_network doesn't work on windows either [#291](https://github.com/puppetlabs/puppetlabs-stdlib/pull/291) ([hunner](https://github.com/hunner)) +- Disable windows network stuff and quote path [#289](https://github.com/puppetlabs/puppetlabs-stdlib/pull/289) ([hunner](https://github.com/hunner)) +- Not enough escape velocity [#288](https://github.com/puppetlabs/puppetlabs-stdlib/pull/288) ([hunner](https://github.com/hunner)) +- Fix pe facts and slashes [#287](https://github.com/puppetlabs/puppetlabs-stdlib/pull/287) ([hunner](https://github.com/hunner)) +- Windows needs a tmpdir path [#281](https://github.com/puppetlabs/puppetlabs-stdlib/pull/281) ([hunner](https://github.com/hunner)) +- Augeas isn't present on windows [#280](https://github.com/puppetlabs/puppetlabs-stdlib/pull/280) ([hunner](https://github.com/hunner)) +- (FM-1587) Fix test issues on solaris 10 [#276](https://github.com/puppetlabs/puppetlabs-stdlib/pull/276) ([hunner](https://github.com/hunner)) + +## [4.2.2](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.2.2) - 2014-06-05 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/3.2.2...4.2.2) + +## [3.2.2](https://github.com/puppetlabs/puppetlabs-stdlib/tree/3.2.2) - 2014-06-05 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.2.1...3.2.2) + +### Added + +- (PUP-2571) add 'before' functionality to file_line [#256](https://github.com/puppetlabs/puppetlabs-stdlib/pull/256) ([stbenjam](https://github.com/stbenjam)) +- (MODULES-905) Add bool2str() and camelcase() for string manipulation [#255](https://github.com/puppetlabs/puppetlabs-stdlib/pull/255) ([mckern](https://github.com/mckern)) + +### Fixed + +- Further fixes to tests for 14.04. [#265](https://github.com/puppetlabs/puppetlabs-stdlib/pull/265) ([apenney](https://github.com/apenney)) +- Fixes for PE3.3. [#264](https://github.com/puppetlabs/puppetlabs-stdlib/pull/264) ([apenney](https://github.com/apenney)) +- (MODULES-905) Narrow the confinement in bool2str [#258](https://github.com/puppetlabs/puppetlabs-stdlib/pull/258) ([mckern](https://github.com/mckern)) +- Revert "Merge pull request #256 from stbenjam/2571-before" [#257](https://github.com/puppetlabs/puppetlabs-stdlib/pull/257) ([apenney](https://github.com/apenney)) + +## [4.2.1](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.2.1) - 2014-05-09 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.2.0...4.2.1) + +## [4.2.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.2.0) - 2014-05-08 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/3.2.1...4.2.0) + +### Added + +- Adding more spec coverage [#247](https://github.com/puppetlabs/puppetlabs-stdlib/pull/247) ([hunner](https://github.com/hunner)) +- Add more specs [#244](https://github.com/puppetlabs/puppetlabs-stdlib/pull/244) ([hunner](https://github.com/hunner)) +- Add beaker tests for functions. [#243](https://github.com/puppetlabs/puppetlabs-stdlib/pull/243) ([hunner](https://github.com/hunner)) +- Add beaker framework. [#234](https://github.com/puppetlabs/puppetlabs-stdlib/pull/234) ([apenney](https://github.com/apenney)) +- Allow concat to take non-array second parameters [#222](https://github.com/puppetlabs/puppetlabs-stdlib/pull/222) ([mfoo](https://github.com/mfoo)) + +### Fixed + +- Fix the stdlib functions that fail tests [#251](https://github.com/puppetlabs/puppetlabs-stdlib/pull/251) ([hunner](https://github.com/hunner)) +- Add the missing shebangs and fix the wrong ones [#248](https://github.com/puppetlabs/puppetlabs-stdlib/pull/248) ([averi](https://github.com/averi)) +- Fix the validate_augeas beaker tests [#245](https://github.com/puppetlabs/puppetlabs-stdlib/pull/245) ([hunner](https://github.com/hunner)) +- Adjust the regular expression for facts. [#242](https://github.com/puppetlabs/puppetlabs-stdlib/pull/242) ([apenney](https://github.com/apenney)) +- Make sure location_for is used when installing Puppet. [#233](https://github.com/puppetlabs/puppetlabs-stdlib/pull/233) ([apenney](https://github.com/apenney)) +- Readd location_for [#232](https://github.com/puppetlabs/puppetlabs-stdlib/pull/232) ([apenney](https://github.com/apenney)) +- hash example has misplaced comas [#221](https://github.com/puppetlabs/puppetlabs-stdlib/pull/221) ([jtreminio](https://github.com/jtreminio)) + +## [3.2.1](https://github.com/puppetlabs/puppetlabs-stdlib/tree/3.2.1) - 2014-03-03 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.1.0...3.2.1) + +### Added + +- (PUP-1459) Add support for root_home on OS X 10.9 [#215](https://github.com/puppetlabs/puppetlabs-stdlib/pull/215) ([blkperl](https://github.com/blkperl)) +- (#23381) add is_bool() function [#211](https://github.com/puppetlabs/puppetlabs-stdlib/pull/211) ([jhoblitt](https://github.com/jhoblitt)) +- Add rake tasks to validate and lint files and check with Travis [#208](https://github.com/puppetlabs/puppetlabs-stdlib/pull/208) ([ghoneycutt](https://github.com/ghoneycutt)) +- (#16498) Added unit test for loadyaml function. [#185](https://github.com/puppetlabs/puppetlabs-stdlib/pull/185) ([lmello](https://github.com/lmello)) +- Add delete_values() and delete_undef_values() functions [#166](https://github.com/puppetlabs/puppetlabs-stdlib/pull/166) ([ptomulik](https://github.com/ptomulik)) +- Adding base64 function [#159](https://github.com/puppetlabs/puppetlabs-stdlib/pull/159) ([fiddyspence](https://github.com/fiddyspence)) +- [#20862] Add functions to validate ipv4 and ipv6 addresses [#158](https://github.com/puppetlabs/puppetlabs-stdlib/pull/158) ([wfarr](https://github.com/wfarr)) +- (#20684) Add array comparison functions, difference, intersection and un... [#155](https://github.com/puppetlabs/puppetlabs-stdlib/pull/155) ([AlexCline](https://github.com/AlexCline)) +- add a "step" argument to range() [#56](https://github.com/puppetlabs/puppetlabs-stdlib/pull/56) ([hakamadare](https://github.com/hakamadare)) + +### Fixed + +- calling rspec directly makes is_function_available.rb not pass ruby -c [#203](https://github.com/puppetlabs/puppetlabs-stdlib/pull/203) ([dreamlibrarian](https://github.com/dreamlibrarian)) +- Fix the tests on osx [#200](https://github.com/puppetlabs/puppetlabs-stdlib/pull/200) ([bobtfish](https://github.com/bobtfish)) +- delete_undef_values function fix bug #20681 [#184](https://github.com/puppetlabs/puppetlabs-stdlib/pull/184) ([lmello](https://github.com/lmello)) +- delete_values() fix bug #20681. [#182](https://github.com/puppetlabs/puppetlabs-stdlib/pull/182) ([lmello](https://github.com/lmello)) +- Minor grammar fix [#181](https://github.com/puppetlabs/puppetlabs-stdlib/pull/181) ([nibalizer](https://github.com/nibalizer)) +- bug # 20681 delete() function should not remove elements from original list [#178](https://github.com/puppetlabs/puppetlabs-stdlib/pull/178) ([lmello](https://github.com/lmello)) +- (maint) fix RST formatting of has_interface_with code examples [#175](https://github.com/puppetlabs/puppetlabs-stdlib/pull/175) ([floatingatoll](https://github.com/floatingatoll)) +- minor corrections to delete_values() [#170](https://github.com/puppetlabs/puppetlabs-stdlib/pull/170) ([ptomulik](https://github.com/ptomulik)) +- Fix validate_slength, arg.length should be args[0].length [#169](https://github.com/puppetlabs/puppetlabs-stdlib/pull/169) ([hdeheer](https://github.com/hdeheer)) +- ensure_resource: fix documentation typo [#165](https://github.com/puppetlabs/puppetlabs-stdlib/pull/165) ([bootc](https://github.com/bootc)) +- Trivial documentation fix for upcase function. [#157](https://github.com/puppetlabs/puppetlabs-stdlib/pull/157) ([rohanrns](https://github.com/rohanrns)) + +## [4.1.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.1.0) - 2013-05-10 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.0.2...4.1.0) + +### Added + +- (#20548) Allow an array of resource titles to be passed into the ensure_... [#152](https://github.com/puppetlabs/puppetlabs-stdlib/pull/152) ([AlexCline](https://github.com/AlexCline)) +- Add a dirname function [#150](https://github.com/puppetlabs/puppetlabs-stdlib/pull/150) ([raphink](https://github.com/raphink)) + +## [4.0.2](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.0.2) - 2013-04-12 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.0.1...4.0.2) + +### Added + +- adds compatibility matrix [#144](https://github.com/puppetlabs/puppetlabs-stdlib/pull/144) ([ghoneycutt](https://github.com/ghoneycutt)) + +## [4.0.1](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.0.1) - 2013-04-11 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/4.0.0...4.0.1) + +## [4.0.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/4.0.0) - 2013-04-11 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/3.2.0...4.0.0) + +### Added + +- Add floor function implementation and unit tests [#135](https://github.com/puppetlabs/puppetlabs-stdlib/pull/135) ([willaerk](https://github.com/willaerk)) +- (#19272) Add has_element() function [#130](https://github.com/puppetlabs/puppetlabs-stdlib/pull/130) ([jhoblitt](https://github.com/jhoblitt)) +- Add validate_augeas command [#114](https://github.com/puppetlabs/puppetlabs-stdlib/pull/114) ([raphink](https://github.com/raphink)) + +### Fixed + +- (19864) num2bool match fix [#139](https://github.com/puppetlabs/puppetlabs-stdlib/pull/139) ([hakamadare](https://github.com/hakamadare)) +- (maint) Fix getparam() spec failure on MRI 1.8 [#125](https://github.com/puppetlabs/puppetlabs-stdlib/pull/125) ([jeffmccune](https://github.com/jeffmccune)) +- Fix typo in travis configuration [#122](https://github.com/puppetlabs/puppetlabs-stdlib/pull/122) ([jeffmccune](https://github.com/jeffmccune)) +- maint: style guideline fixes [#112](https://github.com/puppetlabs/puppetlabs-stdlib/pull/112) ([dalen](https://github.com/dalen)) + +## [3.2.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/3.2.0) - 2012-11-28 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/2.6.0...3.2.0) + +## [2.6.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/2.6.0) - 2012-11-28 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/3.1.1...2.6.0) + +## [3.1.1](https://github.com/puppetlabs/puppetlabs-stdlib/tree/3.1.1) - 2012-10-25 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/2.5.1...3.1.1) + +### Fixed + +- (maint) Fix spec failures resulting from Facter API changes between 1.x and 2.x [#100](https://github.com/puppetlabs/puppetlabs-stdlib/pull/100) ([jeffmccune](https://github.com/jeffmccune)) + +## [2.5.1](https://github.com/puppetlabs/puppetlabs-stdlib/tree/2.5.1) - 2012-10-25 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/3.1.0...2.5.1) + +## [3.1.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/3.1.0) - 2012-10-25 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/2.5.0...3.1.0) + +## [2.5.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/2.5.0) - 2012-10-25 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/3.0.1...2.5.0) + +### Added + +- Add pe facts to stdlib [#99](https://github.com/puppetlabs/puppetlabs-stdlib/pull/99) ([haus](https://github.com/haus)) + +## [3.0.1](https://github.com/puppetlabs/puppetlabs-stdlib/tree/3.0.1) - 2012-10-11 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/3.0.0...3.0.1) + +### Fixed + +- (Maint) Fix mis-use of rvalue functions as statements [#91](https://github.com/puppetlabs/puppetlabs-stdlib/pull/91) ([jeffmccune](https://github.com/jeffmccune)) +- Revert "Merge branch 'hkenney-ticket/master/2157_remove_facts_dot_d'" [#89](https://github.com/puppetlabs/puppetlabs-stdlib/pull/89) ([jeffmccune](https://github.com/jeffmccune)) + +## [3.0.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/3.0.0) - 2012-08-16 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/2.4.0...3.0.0) + +### Added + +- Add function ensure_resource and defined_with_params [#86](https://github.com/puppetlabs/puppetlabs-stdlib/pull/86) ([bodepd](https://github.com/bodepd)) + +### Fixed + +- Ensure resource attempt 2 [#87](https://github.com/puppetlabs/puppetlabs-stdlib/pull/87) ([bodepd](https://github.com/bodepd)) + +## [2.4.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/2.4.0) - 2012-08-14 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/2.3.3...2.4.0) + +### Added + +- Add support for a 'match' parameter to file_line [#75](https://github.com/puppetlabs/puppetlabs-stdlib/pull/75) ([cprice404](https://github.com/cprice404)) + +### Fixed + +- Fix up 2.3.x for new scope [#80](https://github.com/puppetlabs/puppetlabs-stdlib/pull/80) ([jeffmccune](https://github.com/jeffmccune)) +- (#2157) Make facts_dot_d compatible with external facts [#77](https://github.com/puppetlabs/puppetlabs-stdlib/pull/77) ([HAIL9000](https://github.com/HAIL9000)) + +## [2.3.3](https://github.com/puppetlabs/puppetlabs-stdlib/tree/2.3.3) - 2012-05-23 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/2.3.2...2.3.3) + +### Fixed + +- fix regression in #11017 properly [#70](https://github.com/puppetlabs/puppetlabs-stdlib/pull/70) ([duritong](https://github.com/duritong)) + +## [2.3.2](https://github.com/puppetlabs/puppetlabs-stdlib/tree/2.3.2) - 2012-05-10 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/2.1.3...2.3.2) + +### Fixed + +- Make file_line default to ensure => present [#69](https://github.com/puppetlabs/puppetlabs-stdlib/pull/69) ([jeffmccune](https://github.com/jeffmccune)) + +## [2.1.3](https://github.com/puppetlabs/puppetlabs-stdlib/tree/2.1.3) - 2012-03-29 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/2.3.1...2.1.3) + +## [2.3.1](https://github.com/puppetlabs/puppetlabs-stdlib/tree/2.3.1) - 2012-03-13 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/2.3.0...2.3.1) + +### Fixed + +- (#13091) Fix LoadError exception with puppet apply [#50](https://github.com/puppetlabs/puppetlabs-stdlib/pull/50) ([jeffmccune](https://github.com/jeffmccune)) + +## [2.3.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/2.3.0) - 2012-03-12 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v2.2.1...2.3.0) + +### Added + +- (#12357) Add ability to display an error message from validate_re [#47](https://github.com/puppetlabs/puppetlabs-stdlib/pull/47) ([jeffmccune](https://github.com/jeffmccune)) +- (#12357) Add validate_absolute_path() function [#46](https://github.com/puppetlabs/puppetlabs-stdlib/pull/46) ([jeffmccune](https://github.com/jeffmccune)) +- (#12776) Added validate_slength function and rspec test [#37](https://github.com/puppetlabs/puppetlabs-stdlib/pull/37) ([fiddyspence](https://github.com/fiddyspence)) +- implement #11017 - make file_line type ensurable [#36](https://github.com/puppetlabs/puppetlabs-stdlib/pull/36) ([duritong](https://github.com/duritong)) +- New str2saltedsha512 function for OS X Passwords [#27](https://github.com/puppetlabs/puppetlabs-stdlib/pull/27) ([glarizza](https://github.com/glarizza)) +- (#11607) Add Rakefile to enable spec testing [#26](https://github.com/puppetlabs/puppetlabs-stdlib/pull/26) ([jeffmccune](https://github.com/jeffmccune)) + +### Fixed + +- (#12357) Fix broken compatibility with Puppet 2.6 [#49](https://github.com/puppetlabs/puppetlabs-stdlib/pull/49) ([jeffmccune](https://github.com/jeffmccune)) +- (#12357) Fix root_home fact on Windows [#45](https://github.com/puppetlabs/puppetlabs-stdlib/pull/45) ([jeffmccune](https://github.com/jeffmccune)) +- (#12357) Make facter_dot_d look in Puppet[:confdir]/facts.d [#44](https://github.com/puppetlabs/puppetlabs-stdlib/pull/44) ([jeffmccune](https://github.com/jeffmccune)) +- (#11873) time function spec failure on Fixnum matcher [#28](https://github.com/puppetlabs/puppetlabs-stdlib/pull/28) ([kbarber](https://github.com/kbarber)) + +## [v2.2.1](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v2.2.1) - 2011-12-30 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v2.1.2...v2.2.1) + +## [v2.1.2](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v2.1.2) - 2011-12-30 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v2.2.0...v2.1.2) + +### Added + +- (#10802) add new function get_module_path [#25](https://github.com/puppetlabs/puppetlabs-stdlib/pull/25) ([bodepd](https://github.com/bodepd)) + +## [v2.2.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v2.2.0) - 2011-11-08 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v2.1.1...v2.2.0) + +### Added + +- (#9859) Add root_home fact and tests [#17](https://github.com/puppetlabs/puppetlabs-stdlib/pull/17) ([jeffmccune](https://github.com/jeffmccune)) +- (#8925) Added new function called 'get_certificate' for retrieving [#13](https://github.com/puppetlabs/puppetlabs-stdlib/pull/13) ([kbarber](https://github.com/kbarber)) + +### Fixed + +- (#10285) Refactor json to use pson instead. [#19](https://github.com/puppetlabs/puppetlabs-stdlib/pull/19) ([nanliu](https://github.com/nanliu)) + +## [v2.1.1](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v2.1.1) - 2011-08-18 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v2.1.0...v2.1.1) + +## [v2.1.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v2.1.0) - 2011-08-17 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v2.0.0...v2.1.0) + +### Added + +- (#9080) Add facts from /etc/puppetlabs/facts.d [#14](https://github.com/puppetlabs/puppetlabs-stdlib/pull/14) ([jeffmccune](https://github.com/jeffmccune)) + +## [v2.0.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v2.0.0) - 2011-08-08 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v1.1.0...v2.0.0) + +## [v1.1.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v1.1.0) - 2011-08-04 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v1.0.0...v1.1.0) + +## [v1.0.0](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v1.0.0) - 2011-08-04 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/v0.1.7...v1.0.0) + +## [v0.1.7](https://github.com/puppetlabs/puppetlabs-stdlib/tree/v0.1.7) - 2011-06-21 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/0.1.6...v0.1.7) + +## [0.1.6](https://github.com/puppetlabs/puppetlabs-stdlib/tree/0.1.6) - 2011-06-15 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/0.1.5...0.1.6) + +## [0.1.5](https://github.com/puppetlabs/puppetlabs-stdlib/tree/0.1.5) - 2011-06-03 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/0.1.4...0.1.5) + +## [0.1.4](https://github.com/puppetlabs/puppetlabs-stdlib/tree/0.1.4) - 2011-05-26 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/0.1.3...0.1.4) + +## [0.1.3](https://github.com/puppetlabs/puppetlabs-stdlib/tree/0.1.3) - 2011-05-25 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/0.1.2...0.1.3) + +## [0.1.2](https://github.com/puppetlabs/puppetlabs-stdlib/tree/0.1.2) - 2011-05-24 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/0.1.1...0.1.2) + +## [0.1.1](https://github.com/puppetlabs/puppetlabs-stdlib/tree/0.1.1) - 2011-05-24 + +[Full Changelog](https://github.com/puppetlabs/puppetlabs-stdlib/compare/b305bbeac7a0560a271f34026f936b88b88da477...0.1.1) diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 000000000..87a41832c --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,3 @@ +# Setting ownership to the modules team +# include Trusted Contributors +* @puppetlabs/modules @alexjfisher @b4ldr @bastelfreak @ekohl @smortex @seanmil diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f1cbde4bb..e7a3a7c3f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,220 +1,3 @@ -Checklist (and a short version for the impatient) -================================================= - - * Commits: - - - Make commits of logical units. - - - Check for unnecessary whitespace with "git diff --check" before - committing. - - - Commit using Unix line endings (check the settings around "crlf" in - git-config(1)). - - - Do not check in commented out code or unneeded files. - - - The first line of the commit message should be a short - description (50 characters is the soft limit, excluding ticket - number(s)), and should skip the full stop. - - - Associate the issue in the message. The first line should include - the issue number in the form "(#XXXX) Rest of message". - - - The body should provide a meaningful commit message, which: - - - uses the imperative, present tense: "change", not "changed" or - "changes". - - - includes motivation for the change, and contrasts its - implementation with the previous behavior. - - - Make sure that you have tests for the bug you are fixing, or - feature you are adding. - - - Make sure the test suites passes after your commit: - `bundle exec rspec spec/acceptance` More information on [testing](#Testing) below - - - When introducing a new feature, make sure it is properly - documented in the README.md - - * Submission: - - * Pre-requisites: - - - Make sure you have a [GitHub account](https://github.com/join) - - - [Create a ticket](https://tickets.puppetlabs.com/secure/CreateIssue!default.jspa), or [watch the ticket](https://tickets.puppetlabs.com/browse/) you are patching for. - - * Preferred method: - - - Fork the repository on GitHub. - - - Push your changes to a topic branch in your fork of the - repository. (the format ticket/1234-short_description_of_change is - usually preferred for this project). - - - Submit a pull request to the repository in the puppetlabs - organization. - -The long version -================ - - 1. Make separate commits for logically separate changes. - - Please break your commits down into logically consistent units - which include new or changed tests relevant to the rest of the - change. The goal of doing this is to make the diff easier to - read for whoever is reviewing your code. In general, the easier - your diff is to read, the more likely someone will be happy to - review it and get it into the code base. - - If you are going to refactor a piece of code, please do so as a - separate commit from your feature or bug fix changes. - - We also really appreciate changes that include tests to make - sure the bug is not re-introduced, and that the feature is not - accidentally broken. - - Describe the technical detail of the change(s). If your - description starts to get too long, that is a good sign that you - probably need to split up your commit into more finely grained - pieces. - - Commits which plainly describe the things which help - reviewers check the patch and future developers understand the - code are much more likely to be merged in with a minimum of - bike-shedding or requested changes. Ideally, the commit message - would include information, and be in a form suitable for - inclusion in the release notes for the version of Puppet that - includes them. - - Please also check that you are not introducing any trailing - whitespace or other "whitespace errors". You can do this by - running "git diff --check" on your changes before you commit. - - 2. Sending your patches - - To submit your changes via a GitHub pull request, we _highly_ - recommend that you have them on a topic branch, instead of - directly on "master". - It makes things much easier to keep track of, especially if - you decide to work on another thing before your first change - is merged in. - - GitHub has some pretty good - [general documentation](http://help.github.com/) on using - their site. They also have documentation on - [creating pull requests](http://help.github.com/send-pull-requests/). - - In general, after pushing your topic branch up to your - repository on GitHub, you can switch to the branch in the - GitHub UI and click "Pull Request" towards the top of the page - in order to open a pull request. - - - 3. Update the related GitHub issue. - - If there is a GitHub issue associated with the change you - submitted, then you should update the ticket to include the - location of your branch, along with any other commentary you - may wish to make. - -Testing -======= - -Getting Started ---------------- - -Our puppet modules provide [`Gemfile`](./Gemfile)s which can tell a ruby -package manager such as [bundler](http://bundler.io/) what Ruby packages, -or Gems, are required to build, develop, and test this software. - -Please make sure you have [bundler installed](http://bundler.io/#getting-started) -on your system, then use it to install all dependencies needed for this project, -by running - -```shell -% bundle install -Fetching gem metadata from https://rubygems.org/........ -Fetching gem metadata from https://rubygems.org/.. -Using rake (10.1.0) -Using builder (3.2.2) --- 8><-- many more --><8 -- -Using rspec-system-puppet (2.2.0) -Using serverspec (0.6.3) -Using rspec-system-serverspec (1.0.0) -Using bundler (1.3.5) -Your bundle is complete! -Use `bundle show [gemname]` to see where a bundled gem is installed. -``` - -NOTE some systems may require you to run this command with sudo. - -If you already have those gems installed, make sure they are up-to-date: - -```shell -% bundle update -``` - -With all dependencies in place and up-to-date we can now run the tests: - -```shell -% rake spec -``` - -This will execute all the [rspec tests](http://rspec-puppet.com/) tests -under [spec/defines](./spec/defines), [spec/classes](./spec/classes), -and so on. rspec tests may have the same kind of dependencies as the -module they are testing. While the module defines in its [Modulefile](./Modulefile), -rspec tests define them in [.fixtures.yml](./fixtures.yml). - -Some puppet modules also come with [beaker](https://github.com/puppetlabs/beaker) -tests. These tests spin up a virtual machine under -[VirtualBox](https://www.virtualbox.org/)) with, controlling it with -[Vagrant](http://www.vagrantup.com/) to actually simulate scripted test -scenarios. In order to run these, you will need both of those tools -installed on your system. - -You can run them by issuing the following command - -```shell -% rake spec_clean -% rspec spec/acceptance -``` - -This will now download a pre-fabricated image configured in the [default node-set](./spec/acceptance/nodesets/default.yml), -install puppet, copy this module and install its dependencies per [spec/spec_helper_acceptance.rb](./spec/spec_helper_acceptance.rb) -and then run all the tests under [spec/acceptance](./spec/acceptance). - -Writing Tests -------------- - -XXX getting started writing tests. - -If you have commit access to the repository -=========================================== - -Even if you have commit access to the repository, you will still need to -go through the process above, and have someone else review and merge -in your changes. The rule is that all changes must be reviewed by a -developer on the project (that did not write the code) to ensure that -all changes go through a code review process. - -Having someone other than the author of the topic branch recorded as -performing the merge is the record that they performed the code -review. - - -Additional Resources -==================== - -* [Getting additional help](http://puppetlabs.com/community/get-help) - -* [Writing tests](http://projects.puppetlabs.com/projects/puppet/wiki/Development_Writing_Tests) - -* [Patchwork](https://patchwork.puppetlabs.com) - -* [General GitHub documentation](http://help.github.com/) - -* [GitHub pull request documentation](http://help.github.com/send-pull-requests/) +# Contributing to Puppet modules +Check out our [Contributing to Supported Modules Blog Post](https://puppetlabs.github.io/iac/docs/contributing_to_a_module.html) to find all the information that you will need. diff --git a/Gemfile b/Gemfile index 8221514c0..6dd3b77cc 100644 --- a/Gemfile +++ b/Gemfile @@ -1,61 +1,83 @@ source ENV['GEM_SOURCE'] || 'https://rubygems.org' -def location_for(place, fake_version = nil) - if place =~ /^(git[:@][^#]*)#(.*)/ - [fake_version, { :git => $1, :branch => $2, :require => false }].compact - elsif place =~ /^file:\/\/(.*)/ - ['>= 0', { :path => File.expand_path($1), :require => false }] - else - [place, { :require => false }] - end -end +def location_for(place_or_version, fake_version = nil) + git_url_regex = %r{\A(?(https?|git)[:@][^#]*)(#(?.*))?} + file_url_regex = %r{\Afile:\/\/(?.*)} -group :development, :unit_tests do - # rspec must be v2 for ruby 1.8.7 - if RUBY_VERSION >= '1.8.7' and RUBY_VERSION < '1.9' - gem 'rspec', '~> 2.0' + if place_or_version && (git_url = place_or_version.match(git_url_regex)) + [fake_version, { git: git_url[:url], branch: git_url[:branch], require: false }].compact + elsif place_or_version && (file_url = place_or_version.match(file_url_regex)) + ['>= 0', { path: File.expand_path(file_url[:path]), require: false }] else - gem 'rspec', '~> 3.1.0', :require => false + [place_or_version, { require: false }] end - - gem 'rake', '~> 10.1.0', :require => false - gem 'rspec-puppet', '~> 2.2', :require => false - gem 'mocha', :require => false - # keep for its rake task for now - gem 'puppetlabs_spec_helper', :require => false - gem 'puppet-lint', :require => false - gem 'metadata-json-lint', :require => false - gem 'pry', :require => false - gem 'simplecov', :require => false end -beaker_version = ENV['BEAKER_VERSION'] -beaker_rspec_version = ENV['BEAKER_RSPEC_VERSION'] +group :development do + gem "json", '= 2.6.1', require: false if Gem::Requirement.create(['>= 3.1.0', '< 3.1.3']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) + gem "json", '= 2.6.3', require: false if Gem::Requirement.create(['>= 3.2.0', '< 4.0.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) + gem "racc", '~> 1.4.0', require: false if Gem::Requirement.create(['>= 2.7.0', '< 3.0.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) + gem "deep_merge", '~> 1.2.2', require: false + gem "voxpupuli-puppet-lint-plugins", '~> 5.0', require: false + gem "facterdb", '~> 2.1', require: false if Gem::Requirement.create(['< 3.0.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) + gem "facterdb", '~> 3.0', require: false if Gem::Requirement.create(['>= 3.0.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) + gem "metadata-json-lint", '~> 4.0', require: false + gem "json-schema", '< 5.1.1', require: false + gem "rspec-puppet-facts", '~> 4.0', require: false if Gem::Requirement.create(['< 3.0.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) + gem "rspec-puppet-facts", '~> 5.0', require: false if Gem::Requirement.create(['>= 3.0.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) + gem "dependency_checker", '~> 1.0.0', require: false + gem "parallel_tests", '= 3.12.1', require: false + gem "pry", '~> 0.10', require: false + gem "simplecov-console", '~> 0.9', require: false + gem "puppet-debugger", '~> 1.6', require: false + gem "rubocop", '~> 1.50.0', require: false + gem "rubocop-performance", '= 1.16.0', require: false + gem "rubocop-rspec", '= 2.19.0', require: false + gem "rb-readline", '= 0.5.5', require: false, platforms: [:mswin, :mingw, :x64_mingw] + gem "bigdecimal", '< 3.2.2', require: false, platforms: [:mswin, :mingw, :x64_mingw] +end +group :development, :release_prep do + gem "puppet-strings", '~> 4.0', require: false + gem "puppetlabs_spec_helper", '~> 8.0', require: false + gem "puppet-blacksmith", '~> 7.0', require: false +end group :system_tests do - if beaker_version - gem 'beaker', *location_for(beaker_version) - end - if beaker_rspec_version - gem 'beaker-rspec', *location_for(beaker_rspec_version) - else - gem 'beaker-rspec', :require => false - end - gem 'serverspec', :require => false - gem 'beaker-puppet_install_helper', :require => false + gem "puppet_litmus", '~> 2.0', require: false, platforms: [:ruby, :x64_mingw] if !ENV['PUPPET_FORGE_TOKEN'].to_s.empty? + gem "puppet_litmus", '~> 1.0', require: false, platforms: [:ruby, :x64_mingw] if ENV['PUPPET_FORGE_TOKEN'].to_s.empty? + gem "CFPropertyList", '< 3.0.7', require: false, platforms: [:mswin, :mingw, :x64_mingw] + gem "serverspec", '~> 2.41', require: false end -facterversion = ENV['GEM_FACTER_VERSION'] || ENV['FACTER_GEM_VERSION'] -if facterversion - gem 'facter', *location_for(facterversion) +gems = {} +puppet_version = ENV.fetch('PUPPET_GEM_VERSION', nil) +facter_version = ENV.fetch('FACTER_GEM_VERSION', nil) +hiera_version = ENV.fetch('HIERA_GEM_VERSION', nil) + +# If PUPPET_FORGE_TOKEN is set then use authenticated source for both puppet and facter, since facter is a transitive dependency of puppet +# Otherwise, do as before and use location_for to fetch gems from the default source +if !ENV['PUPPET_FORGE_TOKEN'].to_s.empty? + gems['puppet'] = ['~> 8.11', { require: false, source: 'https://rubygems-puppetcore.puppet.com' }] + gems['facter'] = ['~> 4.11', { require: false, source: 'https://rubygems-puppetcore.puppet.com' }] else - gem 'facter', :require => false + gems['puppet'] = location_for(puppet_version) + gems['facter'] = location_for(facter_version) if facter_version end -puppetversion = ENV['GEM_PUPPET_VERSION'] || ENV['PUPPET_GEM_VERSION'] -if puppetversion - gem 'puppet', *location_for(puppetversion) -else - gem 'puppet', :require => false +gems['hiera'] = location_for(hiera_version) if hiera_version + +gems.each do |gem_name, gem_params| + gem gem_name, *gem_params end -# vim:ft=ruby +# Evaluate Gemfile.local and ~/.gemfile if they exist +extra_gemfiles = [ + "#{__FILE__}.local", + File.join(Dir.home, '.gemfile'), +] + +extra_gemfiles.each do |gemfile| + if File.file?(gemfile) && File.readable?(gemfile) + eval(File.read(gemfile), binding) + end +end +# vim: syntax=ruby diff --git a/HISTORY.md b/HISTORY.md new file mode 100644 index 000000000..1889aef8f --- /dev/null +++ b/HISTORY.md @@ -0,0 +1,1067 @@ +## 5.0.0 +### Summary +This is a major release which removes support for the Scientific 5 and Debian 7 OS, as well as a removal of the `Stdlib::(Ipv4|IPv6|Ip_address)` data types in favour of `Stdlib::IP::*`. + +**In addition it contains a substantial piece of work centered around updating functions that have now been migrated into Puppet itself. Please note that this will be the last major release to support Puppet 2 and Puppet 3 and that they will soon be removed.** + +#### Fixed +- Docs URLs corrected. +- Docs clarified that `Stdlib::Unixpath` only matches absolute paths. +- `dirname()` now fails when passed an empty string. +- `basename()` documentation clarified. +- Corrected documentation of `count()` wrt matches and empty string. +- Corrected example in `getparam()` and added note about equivalent in puppet. +- Fixed URL to use 'latest' instead of '5.5' for `Hash.new` function. + +#### Added +- Support added for symbolic file nodes. +- `loadjson()` and `loadyml()` now compatible with HTTPS files. +- `loadjson()` and `loadyml()` now compatible with HTTP basic auth files. +- `any2array` now returns and empty array when given an empty string. +- Support has now been added for Ubuntu 18.04. +- `seeded_rand_string()` function has been added. + +#### Changed +- PDK update `1.5.0` has been applied. +- `size()` function deprecated for Puppet 6 and above. +- `wrt` functions moved to Puppet as of Puppet 6. +- `sprintf_hash` has had notification put in place to show that as of Puppet 4.10.10 it's functionality is supported by the puppet core. +- Added note that `abs()` is in puppet since 6.0.0. +- Added information to `base64` function about Binary data type. +- Added note to `camelcase()` that function is now in puppet. +- Added note to `capitalize()` that function is now in puppet. +- Added note to `ceiling()` that function is now in puppet. +- Added note to `chomp()` that function is now in puppet. +- Added note to `chop()` that function is now in puppet. +- Added note how to do equivalence of `clamp()` function in puppet 6. +- Added note that `concat()` can be done with + since puppet 4.0.0. +- Added note to `convert_base()` how to do this with puppet core. +- Added equivalent puppet core way of doing `count()`. +- Added docs for equivalent puppet language for `delete_regexp()`. +- Added docs for equivalent language constructs for `delete_at()`. +- Added puppet 4 equivalent for `delete_undef()` function. +- Added equivalent puppet language for `delete_values()`. +- Updated `delete()` function with docs about equivalent language. +- Added docs that - between arrays is the same as `difference()`. +- Added note to `downcase()` that function is now in puppet. +- Added note to `empty()` that function is now in puppet. +- Added note to `flatten()` that function is now in puppet. +- Added note to `floor()` that function is now in puppet. +- Added note to `get_module_path()` that puppet has similar function. +- Amended documentation for `getvar()`. +- Add note to `grep()` that `filter()` in puppet does the same. +- Updated `has_key()` with equivalent puppet lang expresion. +- Updated the `hash()` function to show equivalent expression. +- Added note about more formatting options with `String()` in puppet. +- Added note to `join()` that it is in puppet since 5.4.0. +- Added note to `keys()` that it is in puppet since 5.4.0. +- Added note to `lstrip()`, `rstrip()`, `strip()` and `upcase()` that they are in puppet since 6.0.0. +- Updated `member()` with equivalent language expression example. +- Updated `merge()` with puppt language equivalent example. +- Updated `min()` and `max()` with note that they are in puppet. +- Updated `num2bool()` with information that Boolean can convert. +- Updated `prefix()` function with equivalent operation in puppet. +- Updated `range()` with information that Integer can be used. +- Updated `reject()` with equivalent filter() call. +- Added note to `reverse()` that the `reverse_each()` Puppet function does the same as it. +- Added note to `round()` that it has moved to puppet in 6.0.0. +- Added note to `size()` that `length()` is in puppet since 5.4.0. +- Added note to `sort()` that is has moved to Puppet in 6.0.0. +- Updated `str2bool()` with a note that Boolean can handle conversion. +- Added note to `strftime()` that it moved to puppet in 4.8.0. +- Added note to `suffix()` that the same can be done with `map()`. +- Updated `time()` to mention Timespan and Timestamp data types. +- Added note to `values_at()` for equivalent slice operation in language. +- Added note to `values()` that it moved to puppet in 5.5.0. +- Corrected docs for `keys()` - in puppet since 5.5.0. +- Added note to `length()` that function moved to puppet. +- Updated README.md with deprecations for functions moved to puppet. +- Updated documentation of `values_at()`. +- Updated README with note from `time()` about data types for time. +- Updated README for `strintf_hash()` (supported by builtin sprintf). +- Updated README with deprecation of `hash()` function (use data type). +- Updated README `suffix` with equiv example for `map`. +- Updated README with `reject` equivalent call to `filter`. +- Updated README with `range` equiv use of type system + `each`. +- Updated README with `prefix` equiv func using `map`. +- Updated README for `num2bool` with info about Boolean type. +- Updated README `str2bool` with information about `Boolean` equivalent. +- Updated README `merge` with info about `+` operator equivalent. +- Updated README `member` with equivalent alternative in language. +- Updated README `join_keys_to_values` with link to String.new. +- Updated README `has_key` shows deprecation in favor of `in`. +- Updated README `grep` adds information about `filter`. +- Updated README and `getvar.rb` as getvar has moved to puppet. +- Updated README for `getparam` to be the same as in function. +- Updated README `get_module_path` with info about built in variant. +- Updated README `difference` to mention `-` operator equiv. +- Updated README `delete` with built-in alternatives. +- Updated README `delete_values` with builtin equiv. +- Updated README `delete_undef` & `delete_regexp` with builtin equiv. +- Updated README `delete_at` with equivalent built-in examples. +- Updated README `coun`t to show built-in equiv. +- Updated README `convert_base` with built-in equiv. +- Updated README `concat` with built-in equiv using + and <<. +- Updated README `base_64` with built-in equiv using Binary type. +- Skipped tests for `abs` if puppet version < 6.0.0. +- Skipped tests for `min` and `max` if puppet version < 6.0.0. +- Skipped tests for `floor` if puppet version < 6.0.0. +- Skipped tests for `ceiling` if puppet version < 6.0.0. +- Skipped tests for `round` if puppet version < 6.0.0. +- Skipped tests for `upcase` if puppet version < 6.0.0. +- Skipped tests for `downcase` if puppet version < 6.0.0. +- Skipped tests for `capitalize` if puppet version < 6.0.0. +- Skipped tests for `camelcase` if puppet version < 6.0.0. +- Skipped tests for strip functions if puppet version < 6.0.0. +- Skipped tests for `chop` and `chomp` if puppet version < 6.0.0. +- Skipped tests for `sort` if puppet version < 6.0.0. +- Removed extra space in `describe` for `abs` test. +- Updated README and `any2array` with built-in equiv Array.new. +- Updated README and `any2bool` with built-in equiv Boolean.new. +- Updated README and `bool2num` with built-in equiv Numeric.new. +- Updated README and `bool2str` with built-in equiv String.new. +- Corrected equivalent example for `count`. +- Updated README and made mention of `filter` in `delete` a link. +- Updated docs and tests for `strftime`. +- Updated all acceptance test using Puppet.version. +- Change 'puppet' to 'Puppet' in function doc strings. +- HTTP type checks are now case insensitive. + +#### Removed +- Support has been removed for `Scientific 5` and `Debian 7` operating systems. +- `Stdlib::(Ipv4|IPv6|Ip_address)` have been removed. + +## Supported Release 4.25.1 +### Summary + +This is a patch which includes a roll up of small fixes. In Puppet 5.5.0 `flatten()`, `length(),` `empty(),` `join(),` `keys(),` and `values()` are now built into Puppet. Please note that the Puppet implementation of the functions will take precedence over the functions in 'puppetlabs-stdlib'. + +#### Fixed +- Remove unneeded execute permission from test files. +- Puppet 5.5.0 function deprecation [MODULES-6894](https://tickets.puppetlabs.com/browse/MODULES-6894). + +## Supported Release 4.25.0 +### Summary + +This is quite a feature heavy release, it makes this module PDK-compliant for easier maintenance and includes a roll up of maintenance changes. + +#### Added +- PDK conversion [MODULES-6332](https://tickets.puppetlabs.com/browse/MODULES-6332). +- Update `join_keys_to_values` with an undef statement. +- Type alias `Stdlib::Fqdn` matches paths on a fully qualified domain name. +- Type alias `Stdlib::Host` matches a valid host, this can be a valid 'ipv4', 'ipv6' or 'fqdn'. +- Type alias `Stdlib::Port` matches a valid TCP/UDP Port number. +- Type alias `Stdlib::Filesource` matches paths valid values for the source parameter of the puppet file type. +- Type alias `Stdlib::IP::Address` matches any IP address, including both IPv4 and IPv6 addresses, +- Type alias `Stdlib::IP::Address::V4` matches any string consisting of a valid IPv4 address, this is extended by 'CIDR' and 'nosubnet'. +- Type alias `Stdlib::IP::Address::V6` matches any string consisting of a valid IPv6 address, this is extended by 'Full', 'Alternate' and 'Compressed'. +- Type alias `Stdlib::IP::Address::V6::Nosubnet`matches any string consisting of a valid IPv6 address with no subnet, this is extended by 'Full', 'Alternate' and 'Compressed'. +- Type alias `Stdlib::Port` matches a valid TCP/UDP Port number this is then extended to 'Privileged' which are ports less than 1024 and 'Unprivileged' which are ports greater than 1024. + +## Supported Release 4.24.0 +### Summary + +This release includes a roll up of minor changes and a new feature which provides the ability to skip undef values `to_json_pretty()`. +We have also reverted a change that was previously made and resulted in breaking compatibility with Ruby 1.8.7. + +#### Added +- Ability to skip undef values in `to_json_pretty()`. +- Fix type3x function in stdlib ([MODULES-6216](https://tickets.puppet.com/browse/MODULES-6216)) + +#### Changed +- Indentation for `sync.yml` was fixed. +- Updated type alias tests and dropped superfluous wrapper classes +- Revert to old ruby 1.X style of hash ([MODULES-6139](https://tickets.puppet.com/browse/MODULES-6139)) +- `rubocop.yml` not managed by msync ([MODULES-6201](https://tickets.puppet.com/browse/MODULES-6201)) + +## Supported Release 4.23.0 +### Summary + +This release is in order to implement Rubocop changes throughout the module. + +#### Added +- Standard and translated readme's have been updated. +- Rubocop has been implemented in the module and a wide variety of changes have been made to the code. +- Modulesync changes have been merged into the code. + +#### Fixed +- Minor fix to the readme. + +## Supported Release 4.22.0 +### Summary + +This is a clean release in preparation of putting the module through the rubocop process. + +#### Added +- Support has been added for Debian 9 +- 'Stdlib::Mode type' has been added to the module. +- A type for 'ensure' has been added to the service resources. +- A new function 'sprintf_hash' has been added to allow the use of named references. + +#### Removed +- Support has been removed for: RedHat 4, CentOS 4, OracleLinux 4, Scientific 4, SLES 10 SP4, Windows Server 2003, Windows Server 2003 R2 and Windows 8. + +#### Fixed +- The 'ruby_spec.rb' test file has been altered s that it properly checks results. +- Example syntax in 'file_line.rb' has been fixed. + +## Supported Release 4.21.0 +### Summary + +This is a small feature release that includes a revamped, albeit backwards-compatible file_line type. + +#### Added +- `replace_all_matches_not_matching_line` parameter in file_line +- additional tests and documentation for file_line + +#### Removed +- duplicate spec test for absolute_path + +#### Fixed +- Unixpath type to allow "/" as valid path +- file_line behavior that caused infinite appending of `line` to a file ([MODULES-5651](https://tickets.puppet.com/browse/MODULES-5651)) + +## Supported Release 4.20.0 +### Summary + +This release adds new functions and updated README translations. + +#### Added +- `to_json`, `to_json_pretty`, and `to_yaml` functions +- new Japanese README translations + +#### Fixed +- compatibility issue with older versions of Puppet and the `pw_hash` function ([MODULES-5546](https://tickets.puppet.com/browse/MODULES-5546)) + +#### Removed +- support for EOL platform Debian 6 (Squeeze) + +## Supported Release 4.19.0 +### Summary + +This release adds new functions and better documentation/fixes for existing functions with a noteworthy fix for file_line. + +#### Added +- Add validate_domain_name function +- Add the round function +- Add type for MAC address +- Add support for sensitive data type to pw_hash ([MODULES-4908](https://tickets.puppet.com/browse/MODULES-4908)) +- Add new function, fact() (FACT-932) + +#### Fixed +- Fixes for the file_line provider ([MODULES-5003](https://tickets.puppet.com/browse/MODULES-5003)) +- Add documentation for email functions ([MODULES-5382](https://tickets.puppet.com/browse/MODULES-5382)) +- unique function is deprecated for puppet version > 5. (FM-6239) +- Fix headers in CHANGELOG.md so that headers render correctly +- ensure_packages, converge ensure values 'present' and 'installed' + +#### Changed +- Removes listed support for EOL Ubuntu versions + +## Supported Release 4.18.0 +### Summary + +Small release that reverts the Puppet version requirement lower bound to again include Puppet 2.7+ and bumps the upper bound to now include Puppet 5. + +#### Fixed +- Reverts lower bound of Puppet requirement to 2.7.20 + +## Supported Release 4.17.1 +### Summary + +Small release to address a bug (PUP-7650). Also pushes the Puppet version compatibility to 4.7.0. + +#### Bugfixes +- (MODULES-5095) Workaround for PUP-7650 +- (FM-6197) Formatting fixes for file_line resource + + +## Supported Release 4.17.0 +### Summary +This release adds support for internationalization. It also contains Japanese translations for the README, summary and description of the metadata.json and major cleanups in the README. Additional folders have been introduced called locales and readmes where translation files can be found. A number of features and bug fixes are also included in this release. It also adds a new function `glob()` for expanding file lists. Also works around an issue that appeared in puppet 4.6.0 involving types being declared multiple times. + +#### Features +- Addition of POT file / folder structure for i18n. +- Addition of Internationalized READMEs. +- `glob()` function + +### Fixed +- Occasional duplicate type definitions when using `defined_with_params()` +- `file_line` encoding issue on ruby 1.8 (unsupported) +- Huge readme refresh + +## Supported Release 4.16.0 +### Summary + +This release sees a massive update to all unit tests to test UTF8 characters. There are also multiple cleanups in preparation for internationalization. Alongside this, improvements to ipv6 support, a new length function compatible with Puppet 4, and an update to path types. Also contains multiple bug fixes around functionality and tests. + +#### Features +- Addition of coverage in all unit tests for functions, data and resource types for UTF8 for i18n. +- All strings within the readme and functions that are split over two lines have been combined in preparation for i18n parser/decorator. +- Improvement on the ipv6 support for type - Improves regex to catch some valid (but lesser known) ipv6 strings, mostly those which are a mix of ipv6 strings and embedded ipv6 numbers. +- Adds a new parameter `encoding` to allow non UTF-8 files to specify a file encoding. This prevents receiving the error message "invalid byte sequence in UTF-8" when special characters that are not UTF-8 encoded appear in the input stream, such as the copyright symbol. +- Addition of the new length function. Returns the length of a given string, array or hash. To eventually replace the deprecated size() function as can handle the new type functionality introduced in Puppet 4. +- Permit double slash in absolute/Unix path types. + +#### Bugfixes +- Fix unsupported data type error with rspec-puppet server. +- Now allows test module metadata.json to be read by Puppet. +- Fix acceptance test failure "Hiera is not a class". +- Removal of unsupported platforms and future parser setting in acceptance tests. +- Regex for tuple checking has been loosened. +- Ensure_packages function - Now only tries to apply the resource if not defined. +- (MODULES-4528) Use versioncmp to check Puppet version for 4.10.x compat. +- Adds comments to warn for UTF8 incompatibility of the functions that may not be compatible with UTF8 with Ruby < 2.4.0. + +## Supported Release 4.15.0 +### Summary + +This release introduces multiple new functions, a new fact and the addition of Ubuntu Xenial support. Also includes a bugfix and documentation update. + +#### Features +- Addition of puppet_server fact to return agents server. +- Addition of a pry function. +- Addition of tests for ensure_resources. +- Addition of FQDN UUID generation function. +- Addition of Ubuntu Xenial to OS Support. + +#### Bugfixes +- Ensure_packages now works with Ruby < 2.0. +- Updated the documentation of str2bool function. + +## Supported Release 4.14.0 +### Summary + +Adds several new features and updates, especially around refining the deprecation and validate_legacy functions. Also includes a Gemfile update around an issue with parallel_tests dependancy for different versions of Ruby. + +#### Features +- Deprecation function now uses puppet stacktrace if available. +- join_key_to_values function now handles array values. If values are arrays, multiple keys are added for each element. +- Updated Gemfile to deal with parallel_tests Ruby dependancy (MODULES-3983). +- Updated/Fixed ipv4 regex validator (MODULES-3980). +- Deprecation clarification added to README. + +#### Bugfixes +- README typo fixes. +- Use .dup to duplicate classes for modification (MODULES-3829). +- Fixes spec failures that were caused by a change in the tested error message in validate_legacy_spec. +- Broken link to validate_legacy docs fixed. +- Updates deprecation tests to include future parser. + +## Supported Release 4.13.1 +### Summary + +This bugfix release addresses the `undefined method 'optional_repeated_param'` error messages seen by users of puppet 3.7. + +It also improves the user experience around function deprecations by emitting one warning per function(-name) instead of only one deprecation overall. This allows users to identify all deprecated functions used in one agent run, with less back-and-forth. + +#### Bugfixes + +* Emit deprecations warnings for each function, instead of once per process. (MODULES-3961) +* Use a universally available API for the v4 deprecation stubs of `is_*` and `validate_*`. (MODULES-3962) +* Make `getvar()` compatible to ruby 1.8.7. (MODULES-3969) +* Add v4 deprecation stubs for the `is_` counterparts of the deprecated functions to emit the deprecations warnings in all cases. + + +## Supported Release 4.13.0 +### Summary + +This version of stdlib deprecates a whole host of functions, and provides stepping stones to move to Puppet 4 type validations. Be sure to check out the new `deprecation()` and `validate_legacy()` functions to migrate off the deprecated v3-style data validations. + +Many thanks to all community contributors: bob, Dmitry Ilyin, Dominic Cleal, Joris, Joseph Yaworski, Loic Antoine-Gombeaud, Maksym Melnychok, Michiel Brandenburg, Nate Potter, Romain TartiĆØre, Stephen Benjamin, and Steve Moore, as well as anyone contributing in the code review process and by submitting issues. + +Special thanks to [Voxpupuli's](https://voxpupuli.org/) Igor Galić for donating the puppet-tea types to kickstart this part of stdlib. + + +#### Deprecations +* `validate_absolute_path`, `validate_array`, `validate_bool`, `validate_hash`, `validate_integer`, `validate_ip_address`, `validate_ipv4_address`, `validate_ipv6_address`, `validate_numeric`, `validate_re`, `validate_slength`, `validate_string`, and their `is_` counter parts are now deprecated on Puppet 4. See the `validate_legacy()` description in the README for help on migrating away from those functions. +* The `dig` function is provided by core puppet since 4.5.0 with slightly different calling convention. The stdlib version can still be accessed as `dig44` for now. + + +#### Features +* Add Puppet 4 data types for Unix, and Windows paths, and URLs. +* Add `deprecation` function to warn users of functionality that will be removed soon. +* Add `validate_legacy` function to help with migrating to Puppet 4 data types. + +* Add `any2bool` function, a combination of of `string2bool` and `num2bool`. +* Add `delete_regex` function to delete array elements matching a regular expression. +* Add `puppet_environmentpath` fact to expose the `environmentpath` setting. +* Add `regexpescape` function to safely insert arbitrary strings into regular expressions. +* Add `shell_escape`, `shell_join`, and `shell_split` functions for safer working with shell scripts.. + +* The `delete` function now also accepts regular expressions as search term. +* The `loadyaml` function now accepts a default value, which is returned when there is an error loading the file. + +#### Bugfixes +* Fix `file_line.match_for_absence` implementation and description to actually work. (MODULES-3590) +* Fix `getparam` so that it can now also return `false`. (MODULES-3933) +* Fix the fixture setup for testing and adjust `load_module_metadata` and `loadjson` tests. +* Fix `defined_with_params` to handle `undef` correctly on all puppet versions. (PUP-6422, MODULES-3543) +* Fix `file_line.path` validation to use puppet's built in `absolute_path?` matcher. + +#### Minor Improvements +* README changes: improved descriptions of `deep_merge`, `delete`, `ensure_packages`, `file_line.after`, `range`, and `validate_numeric`. +* The `getvar` function now returns nil in all situations where the variable is not found. +* Update the `dig44` function with better `undef`, `nil`, and `false` handling. +* Better wording on `str2bool` argument validation error message. + + +### Known issues +* The `validate_legacy` function relies on internal APIs from Puppet 4.4.0 (PE 2016.1) onwards, and doesn't work on earlier versions. +* Puppet 4.5.0 (PE 2016.2) has a number of improvements around data types - especially error handling - that make working with them much nicer. + +## Supported Release 4.12.0 +### Summary + +This release provides several new functions, bugfixes, modulesync changes, and some documentation updates. + +#### Features +- Adds `clamp`. This function keeps values within a specified range. +- Adds `validate_x509_rsa_key_pair`. This function validates an x509 RSA certificate and key pair. +- Adds `dig`. This function performs a deep lookup in nested hashes or arrays. +- Extends the `base64` support to fit `rfc2045` and `rfc4648`. +- Adds `is_ipv6_address` and `is_ipv4_address`. These functions validate the specified ipv4 or ipv6 addresses. +- Adds `enclose_ipv6`. This function encloses IPv6 addresses in square brackets. +- Adds `ensure_resources`. This function takes a list of resources and creates them if they do not exist. +- Extends `suffix` to support applying a suffix to keys in a hash. +- Apply modulesync changes. +- Add validate_email_address function. + +#### Bugfixes +- Fixes `fqdn_rand_string` tests, since Puppet 4.4.0 and later have a higher `fqdn_rand` ceiling. +- (MODULES-3152) Adds a check to `package_provider` to prevent failures if Gem is not installed. +- Fixes to README.md. +- Fixes catch StandardError rather than the gratuitous Exception +- Fixes file_line attribute validation. +- Fixes concat with Hash arguments. + +## Supported Release 4.11.0 +### Summary + +Provides a validate_absolute_paths and Debian 8 support. There is a fix to the is_package_provider fact and a test improvement. + +#### Features +- Adds new parser called is_absolute_path +- Supports Debian 8 + +#### Bugfixes +- Allow package_provider fact to resolve on PE 3.x + +#### Improvements +- ensures that the test passes independently of changes to rubygems for ensure_resource + +## 2015-12-15 - Supported Release 4.10.0 +### Summary + +Includes the addition of several new functions and considerable improvements to the existing functions, tests and documentation. Includes some bug fixes which includes compatibility, test and fact issues. + +#### Features +- Adds service_provider fact +- Adds is_a() function +- Adds package_provider fact +- Adds validate_ip_address function +- Adds seeded_rand function + +#### Bugfixes +- Fix backwards compatibility from an improvement to the parseyaml function +- Renaming of load_module_metadata test to include \_spec.rb +- Fix root_home fact on AIX 5.x, now '-c' rather than '-C' +- Fixed Gemfile to work with ruby 1.8.7 + +#### Improvements +- (MODULES-2462) Improvement of parseyaml function +- Improvement of str2bool function +- Improvement to readme +- Improvement of intersection function +- Improvement of validate_re function +- Improved speed on Facter resolution of service_provider +- empty function now handles numeric values +- Package_provider now prevents deprecation warning about the allow_virtual parameter +- load_module_metadata now succeeds on empty file +- Check added to ensure puppetversion value is not nil +- Improvement to bool2str to return a string of choice using boolean +- Improvement to naming convention in validate_ipv4_address function + +## Supported Release 4.9.1 +### Summary + +Small release for support of newer PE versions. This increments the version of PE in the metadata.json file. + +## 2015-09-08 - Supported Release 4.9.0 +### Summary + +This release adds new features including the new functions dos2unix, unix2dos, try_get_value, convert_base as well as other features and improvements. + +#### Features +- (MODULES-2370) allow `match` parameter to influence `ensure => absent` behavior +- (MODULES-2410) Add new functions dos2unix and unix2dos +- (MODULE-2456) Modify union to accept more than two arrays +- Adds a convert_base function, which can convert numbers between bases +- Add a new function "try_get_value" + +#### Bugfixes +- n/a + +#### Improvements +- (MODULES-2478) Support root_home fact on AIX through "lsuser" command +- Acceptance test improvements +- Unit test improvements +- Readme improvements + +## 2015-08-10 - Supported Release 4.8.0 +### Summary +This release adds a function for reading metadata.json from any module, and expands file\_line's abilities. + +#### Features +- New parameter `replace` on `file_line` +- New function `load_module_metadata()` to load metadata.json and return the content as a hash. +- Added hash support to `size()` + +#### Bugfixes +- Fix various docs typos +- Fix `file_line` resource on puppet < 3.3 + +## 2015-06-22 - Supported Release 4.7.0 +### Summary + +Adds Solaris 12 support along with improved Puppet 4 support. There are significant test improvements, and some minor fixes. + +#### Features +- Add support for Solaris 12 + +#### Bugfixes +- Fix for AIO Puppet 4 +- Fix time for ruby 1.8.7 +- Specify rspec-puppet version +- range() fix for typeerror and missing functionality +- Fix pw_hash() on JRuby < 1.7.17 +- fqdn_rand_string: fix argument error message +- catch and rescue from looking up non-existent facts +- Use puppet_install_helper, for Puppet 4 + +#### Improvements +- Enforce support for Puppet 4 testing +- fqdn_rotate/fqdn_rand_string acceptance tests and implementation +- Simplify mac address regex +- validate_integer, validate_numeric: explicitely reject hashes in arrays +- Readme edits +- Remove all the pops stuff for rspec-puppet +- Sync via modulesync +- Add validate_slength optional 3rd arg +- Move tests directory to examples directory + +## 2015-04-14 - Supported Release 4.6.0 +### Summary + +Adds functions and function argument abilities, and improves compatibility with the new puppet parser + +#### Features +- MODULES-444: `concat()` can now take more than two arrays +- `basename()` added to have Ruby File.basename functionality +- `delete()` can now take an array of items to remove +- `prefix()` can now take a hash +- `upcase()` can now take a hash or array of upcaseable things +- `validate_absolute_path()` can now take an array +- `validate_cmd()` can now use % in the command to embed the validation file argument in the string +- MODULES-1473: deprecate `type()` function in favor of `type3x()` +- MODULES-1473: Add `type_of()` to give better type information on future parser +- Deprecate `private()` for `assert_private()` due to future parser +- Adds `ceiling()` to take the ceiling of a number +- Adds `fqdn_rand_string()` to generate random string based on fqdn +- Adds `pw_hash()` to generate password hashes +- Adds `validate_integer()` +- Adds `validate_numeric()` (like `validate_integer()` but also accepts floats) + +#### Bugfixes +- Fix seeding of `fqdn_rotate()` +- `ensure_resource()` is more verbose on debug mode +- Stricter argument checking for `dirname()` +- Fix `is_domain_name()` to better match RFC +- Fix `uriescape()` when called with array +- Fix `file_line` resource when using the `after` attribute with `match` + +## 2015-01-14 - Supported Release 4.5.1 +### Summary + +This release changes the temporary facter_dot_d cache locations outside of the /tmp directory due to a possible security vunerability. CVE-2015-1029 + +#### Bugfixes +- Facter_dot_d cache will now be stored in puppet libdir instead of tmp + +## 2014-12-15 - Supported Release 4.5.0 +### Summary + +This release improves functionality of the member function and adds improved future parser support. + +#### Features +- MODULES-1329: Update member() to allow the variable to be an array. +- Sync .travis.yml, Gemfile, Rakefile, and CONTRIBUTING.md via modulesync + +#### Bugfixes +- Fix range() to work with numeric ranges with the future parser +- Accurately express SLES support in metadata.json (was missing 10SP4 and 12) +- Don't require `line` to match the `match` parameter + +## 2014-11-10 - Supported Release 4.4.0 +### Summary +This release has an overhauled readme, new private manifest function, and fixes many future parser bugs. + +#### Features +- All new shiny README +- New `private()` function for making private manifests (yay!) + +#### Bugfixes +- Code reuse in `bool2num()` and `zip()` +- Fix many functions to handle `generate()` no longer returning a string on new puppets +- `concat()` no longer modifies the first argument (whoops) +- strict variable support for `getvar()`, `member()`, `values_at`, and `has_interface_with()` +- `to_bytes()` handles PB and EB now +- Fix `tempfile` ruby requirement for `validate_augeas()` and `validate_cmd()` +- Fix `validate_cmd()` for windows +- Correct `validate_string()` docs to reflect non-handling of `undef` +- Fix `file_line` matching on older rubies + + +## 2014-07-15 - Supported Release 4.3.2 +### Summary + +This release merely updates metadata.json so the module can be uninstalled and +upgraded via the puppet module command. + +## 2014-07-14 - Supported Release 4.3.1 +### Summary +This supported release updates the metadata.json to work around upgrade behavior of the PMT. + +#### Bugfixes +- Synchronize metadata.json with PMT-generated metadata to pass checksums + +## 2014-06-27 - Supported Release 4.3.0 +### Summary +This release is the first supported release of the stdlib 4 series. It remains +backwards-compatible with the stdlib 3 series. It adds two new functions, one bugfix, and many testing updates. + +#### Features +- New `bool2str()` function +- New `camelcase()` function + +#### Bugfixes +- Fix `has_interface_with()` when interfaces fact is nil + +## 2014-06-04 - Release 4.2.2 +### Summary + +This release adds PE3.3 support in the metadata and fixes a few tests. + +## 2014-05-08 - Release - 4.2.1 +### Summary +This release moves a stray symlink that can cause problems. + +## 2014-05-08 - Release - 4.2.0 +### Summary +This release adds many new functions and fixes, and continues to be backwards compatible with stdlib 3.x + +#### Features +- New `base64()` function +- New `deep_merge()` function +- New `delete_undef_values()` function +- New `delete_values()` function +- New `difference()` function +- New `intersection()` function +- New `is_bool()` function +- New `pick_default()` function +- New `union()` function +- New `validate_ipv4_address` function +- New `validate_ipv6_address` function +- Update `ensure_packages()` to take an option hash as a second parameter. +- Update `range()` to take an optional third argument for range step +- Update `validate_slength()` to take an optional third argument for minimum length +- Update `file_line` resource to take `after` and `multiple` attributes + +#### Bugfixes +- Correct `is_string`, `is_domain_name`, `is_array`, `is_float`, and `is_function_available` for parsing odd types such as bools and hashes. +- Allow facts.d facts to contain `=` in the value +- Fix `root_home` fact on darwin systems +- Fix `concat()` to work with a second non-array argument +- Fix `floor()` to work with integer strings +- Fix `is_integer()` to return true if passed integer strings +- Fix `is_numeric()` to return true if passed integer strings +- Fix `merge()` to work with empty strings +- Fix `pick()` to raise the correct error type +- Fix `uriescape()` to use the default URI.escape list +- Add/update unit & acceptance tests. + + +## 2014-03-04 - Supported Release - 3.2.1 +### Summary +This is a supported release + +#### Bugfixes +- Fixed `is_integer`/`is_float`/`is_numeric` for checking the value of arithmatic expressions. + +#### Known bugs +* No known bugs + +--- + +##### 2013-05-06 - Jeff McCune - 4.1.0 + + * (#20582) Restore facter\_dot\_d to stdlib for PE users (3b887c8) + * (maint) Update Gemfile with GEM\_FACTER\_VERSION (f44d535) + +##### 2013-05-06 - Alex Cline - 4.1.0 + + * Terser method of string to array conversion courtesy of ethooz. (d38bce0) + +##### 2013-05-06 - Alex Cline 4.1.0 + + * Refactor ensure\_resource expectations (b33cc24) + +##### 2013-05-06 - Alex Cline 4.1.0 + + * Changed str-to-array conversion and removed abbreviation. (de253db) + +##### 2013-05-03 - Alex Cline 4.1.0 + + * (#20548) Allow an array of resource titles to be passed into the ensure\_resource function (e08734a) + +##### 2013-05-02 - RaphaĆ«l Pinson - 4.1.0 + + * Add a dirname function (2ba9e47) + +##### 2013-04-29 - Mark Smith-Guerrero - 4.1.0 + + * (maint) Fix a small typo in hash() description (928036a) + +##### 2013-04-12 - Jeff McCune - 4.0.2 + + * Update user information in gemspec to make the intent of the Gem clear. + +##### 2013-04-11 - Jeff McCune - 4.0.1 + + * Fix README function documentation (ab3e30c) + +##### 2013-04-11 - Jeff McCune - 4.0.0 + + * stdlib 4.0 drops support with Puppet 2.7 + * stdlib 4.0 preserves support with Puppet 3 + +##### 2013-04-11 - Jeff McCune - 4.0.0 + + * Add ability to use puppet from git via bundler (9c5805f) + +##### 2013-04-10 - Jeff McCune - 4.0.0 + + * (maint) Make stdlib usable as a Ruby GEM (e81a45e) + +##### 2013-04-10 - Erik DalĆ©n - 4.0.0 + + * Add a count function (f28550e) + +##### 2013-03-31 - Amos Shapira - 4.0.0 + + * (#19998) Implement any2array (7a2fb80) + +##### 2013-03-29 - Steve Huff - 4.0.0 + + * (19864) num2bool match fix (8d217f0) + +##### 2013-03-20 - Erik DalĆ©n - 4.0.0 + + * Allow comparisons of Numeric and number as String (ff5dd5d) + +##### 2013-03-26 - Richard Soderberg - 4.0.0 + + * add suffix function to accompany the prefix function (88a93ac) + +##### 2013-03-19 - Kristof Willaert - 4.0.0 + + * Add floor function implementation and unit tests (0527341) + +##### 2012-04-03 - Eric Shamow - 4.0.0 + + * (#13610) Add is\_function\_available to stdlib (961dcab) + +##### 2012-12-17 - Justin Lambert - 4.0.0 + + * str2bool should return a boolean if called with a boolean (5d5a4d4) + +##### 2012-10-23 - Uwe Stuehler - 4.0.0 + + * Fix number of arguments check in flatten() (e80207b) + +##### 2013-03-11 - Jeff McCune - 4.0.0 + + * Add contributing document (96e19d0) + +##### 2013-03-04 - RaphaĆ«l Pinson - 4.0.0 + + * Add missing documentation for validate\_augeas and validate\_cmd to README.markdown (a1510a1) + +##### 2013-02-14 - Joshua Hoblitt - 4.0.0 + + * (#19272) Add has\_element() function (95cf3fe) + +##### 2013-02-07 - RaphaĆ«l Pinson - 4.0.0 + + * validate\_cmd(): Use Puppet::Util::Execution.execute when available (69248df) + +##### 2012-12-06 - RaphaĆ«l Pinson - 4.0.0 + + * Add validate\_augeas function (3a97c23) + +##### 2012-12-06 - RaphaĆ«l Pinson - 4.0.0 + + * Add validate\_cmd function (6902cc5) + +##### 2013-01-14 - David Schmitt - 4.0.0 + + * Add geppetto project definition (b3fc0a3) + +##### 2013-01-02 - Jaka Hudoklin - 4.0.0 + + * Add getparam function to get defined resource parameters (20e0e07) + +##### 2013-01-05 - Jeff McCune - 4.0.0 + + * (maint) Add Travis CI Support (d082046) + +##### 2012-12-04 - Jeff McCune - 4.0.0 + + * Clarify that stdlib 3 supports Puppet 3 (3a6085f) + +##### 2012-11-30 - Erik DalĆ©n - 4.0.0 + + * maint: style guideline fixes (7742e5f) + +##### 2012-11-09 - James Fryman - 4.0.0 + + * puppet-lint cleanup (88acc52) + +##### 2012-11-06 - Joe Julian - 4.0.0 + + * Add function, uriescape, to URI.escape strings. Redmine #17459 (fd52b8d) + +##### 2012-09-18 - Chad Metcalf - 3.2.0 + + * Add an ensure\_packages function. (8a8c09e) + +##### 2012-11-23 - Erik DalĆ©n - 3.2.0 + + * (#17797) min() and max() functions (9954133) + +##### 2012-05-23 - Peter Meier - 3.2.0 + + * (#14670) autorequire a file\_line resource's path (dfcee63) + +##### 2012-11-19 - Joshua Harlan Lifton - 3.2.0 + + * Add join\_keys\_to\_values function (ee0f2b3) + +##### 2012-11-17 - Joshua Harlan Lifton - 3.2.0 + + * Extend delete function for strings and hashes (7322e4d) + +##### 2012-08-03 - Gary Larizza - 3.2.0 + + * Add the pick() function (ba6dd13) + +##### 2012-03-20 - Wil Cooley - 3.2.0 + + * (#13974) Add predicate functions for interface facts (f819417) + +##### 2012-11-06 - Joe Julian - 3.2.0 + + * Add function, uriescape, to URI.escape strings. Redmine #17459 (70f4a0e) + +##### 2012-10-25 - Jeff McCune - 3.1.1 + + * (maint) Fix spec failures resulting from Facter API changes (97f836f) + +##### 2012-10-23 - Matthaus Owens - 3.1.0 + + * Add PE facts to stdlib (cdf3b05) + +##### 2012-08-16 - Jeff McCune - 3.0.1 + + * Fix accidental removal of facts\_dot\_d.rb in 3.0.0 release + +##### 2012-08-16 - Jeff McCune - 3.0.0 + + * stdlib 3.0 drops support with Puppet 2.6 + * stdlib 3.0 preserves support with Puppet 2.7 + +##### 2012-08-07 - Dan Bode - 3.0.0 + + * Add function ensure\_resource and defined\_with\_params (ba789de) + +##### 2012-07-10 - Hailee Kenney - 3.0.0 + + * (#2157) Remove facter\_dot\_d for compatibility with external facts (f92574f) + +##### 2012-04-10 - Chris Price - 3.0.0 + + * (#13693) moving logic from local spec\_helper to puppetlabs\_spec\_helper (85f96df) + +##### 2012-10-25 - Jeff McCune - 2.5.1 + + * (maint) Fix spec failures resulting from Facter API changes (97f836f) + +##### 2012-10-23 - Matthaus Owens - 2.5.0 + + * Add PE facts to stdlib (cdf3b05) + +##### 2012-08-15 - Dan Bode - 2.5.0 + + * Explicitly load functions used by ensure\_resource (9fc3063) + +##### 2012-08-13 - Dan Bode - 2.5.0 + + * Add better docs about duplicate resource failures (97d327a) + +##### 2012-08-13 - Dan Bode - 2.5.0 + + * Handle undef for parameter argument (4f8b133) + +##### 2012-08-07 - Dan Bode - 2.5.0 + + * Add function ensure\_resource and defined\_with\_params (a0cb8cd) + +##### 2012-08-20 - Jeff McCune - 2.5.0 + + * Disable tests that fail on 2.6.x due to #15912 (c81496e) + +##### 2012-08-20 - Jeff McCune - 2.5.0 + + * (Maint) Fix mis-use of rvalue functions as statements (4492913) + +##### 2012-08-20 - Jeff McCune - 2.5.0 + + * Add .rspec file to repo root (88789e8) + +##### 2012-06-07 - Chris Price - 2.4.0 + + * Add support for a 'match' parameter to file\_line (a06c0d8) + +##### 2012-08-07 - Erik DalĆ©n - 2.4.0 + + * (#15872) Add to\_bytes function (247b69c) + +##### 2012-07-19 - Jeff McCune - 2.4.0 + + * (Maint) use PuppetlabsSpec::PuppetInternals.scope (main) (deafe88) + +##### 2012-07-10 - Hailee Kenney - 2.4.0 + + * (#2157) Make facts\_dot\_d compatible with external facts (5fb0ddc) + +##### 2012-03-16 - Steve Traylen - 2.4.0 + + * (#13205) Rotate array/string randomley based on fqdn, fqdn\_rotate() (fef247b) + +##### 2012-05-22 - Peter Meier - 2.3.3 + + * fix regression in #11017 properly (f0a62c7) + +##### 2012-05-10 - Jeff McCune - 2.3.3 + + * Fix spec tests using the new spec\_helper (7d34333) + +##### 2012-05-10 - Puppet Labs - 2.3.2 + + * Make file\_line default to ensure => present (1373e70) + * Memoize file\_line spec instance variables (20aacc5) + * Fix spec tests using the new spec\_helper (1ebfa5d) + * (#13595) initialize\_everything\_for\_tests couples modules Puppet ver (3222f35) + * (#13439) Fix MRI 1.9 issue with spec\_helper (15c5fd1) + * (#13439) Fix test failures with Puppet 2.6.x (665610b) + * (#13439) refactor spec helper for compatibility with both puppet 2.7 and server (82194ca) + * (#13494) Specify the behavior of zero padded strings (61891bb) + +##### 2012-03-29 Puppet Labs - 2.1.3 + +* (#11607) Add Rakefile to enable spec testing +* (#12377) Avoid infinite loop when retrying require json + +##### 2012-03-13 Puppet Labs - 2.3.1 + +* (#13091) Fix LoadError bug with puppet apply and puppet\_vardir fact + +##### 2012-03-12 Puppet Labs - 2.3.0 + +* Add a large number of new Puppet functions +* Backwards compatibility preserved with 2.2.x + +##### 2011-12-30 Puppet Labs - 2.2.1 + +* Documentation only release for the Forge + +##### 2011-12-30 Puppet Labs - 2.1.2 + +* Documentation only release for PE 2.0.x + +##### 2011-11-08 Puppet Labs - 2.2.0 + +* #10285 - Refactor json to use pson instead. +* Maint - Add watchr autotest script +* Maint - Make rspec tests work with Puppet 2.6.4 +* #9859 - Add root\_home fact and tests + +##### 2011-08-18 Puppet Labs - 2.1.1 + +* Change facts.d paths to match Facter 2.0 paths. +* /etc/facter/facts.d +* /etc/puppetlabs/facter/facts.d + +##### 2011-08-17 Puppet Labs - 2.1.0 + +* Add R.I. Pienaar's facts.d custom facter fact +* facts defined in /etc/facts.d and /etc/puppetlabs/facts.d are + automatically loaded now. + +##### 2011-08-04 Puppet Labs - 2.0.0 + +* Rename whole\_line to file\_line +* This is an API change and as such motivating a 2.0.0 release according to semver.org. + +##### 2011-08-04 Puppet Labs - 1.1.0 + +* Rename append\_line to whole\_line +* This is an API change and as such motivating a 1.1.0 release. + +##### 2011-08-04 Puppet Labs - 1.0.0 + +* Initial stable release +* Add validate\_array and validate\_string functions +* Make merge() function work with Ruby 1.8.5 +* Add hash merging function +* Add has\_key function +* Add loadyaml() function +* Add append\_line native + +##### 2011-06-21 Jeff McCune - 0.1.7 + +* Add validate\_hash() and getvar() functions + +##### 2011-06-15 Jeff McCune - 0.1.6 + +* Add anchor resource type to provide containment for composite classes + +##### 2011-06-03 Jeff McCune - 0.1.5 + +* Add validate\_bool() function to stdlib + +##### 0.1.4 2011-05-26 Jeff McCune + +* Move most stages after main + +##### 0.1.3 2011-05-25 Jeff McCune + +* Add validate\_re() function + +##### 0.1.2 2011-05-24 Jeff McCune + +* Update to add annotated tag + +##### 0.1.1 2011-05-24 Jeff McCune + +* Add stdlib::stages class with a standard set of stages diff --git a/LICENSE b/LICENSE index ec0587c0d..d64569567 100644 --- a/LICENSE +++ b/LICENSE @@ -1,19 +1,202 @@ -Copyright (C) 2011 Puppet Labs Inc -and some parts: + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ -Copyright (C) 2011 Krzysztof Wilczynski + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION -Puppet Labs can be contacted at: info@puppetlabs.com + 1. Definitions. -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. - http://www.apache.org/licenses/LICENSE-2.0 + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/NOTICE b/NOTICE new file mode 100644 index 000000000..3c8c03ab6 --- /dev/null +++ b/NOTICE @@ -0,0 +1,23 @@ +stdlib puppet module + +Copyright (C) 2011-2016 Puppet Labs, Inc. + +and some parts: + +Copyright (C) 2011 Krzysztof Wilczynski + + +Puppet Labs can be contacted at: info@puppetlabs.com + + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/README.markdown b/README.markdown deleted file mode 100644 index 526b57353..000000000 --- a/README.markdown +++ /dev/null @@ -1,1265 +0,0 @@ -#stdlib - -####Table of Contents - -1. [Overview](#overview) -2. [Module Description - What the module does and why it is useful](#module-description) -3. [Setup - The basics of getting started with stdlib](#setup) -4. [Usage - Configuration options and additional functionality](#usage) -5. [Reference - An under-the-hood peek at what the module is doing and how](#reference) -5. [Limitations - OS compatibility, etc.](#limitations) -6. [Development - Guide for contributing to the module](#development) - -##Overview - -Adds a standard library of resources for Puppet modules. - -##Module Description - -This module provides a standard library of resources for the development of Puppet modules. Puppet modules make heavy use of this standard library. The stdlib module adds the following resources to Puppet: - - * Stages - * Facts - * Functions - * Defined resource types - * Types - * Providers - -> *Note:* As of version 3.7, Puppet Enterprise no longer includes the stdlib module. If you're running Puppet Enterprise, you should install the most recent release of stdlib for compatibility with Puppet modules. - -##Setup - -Installing the stdlib module adds the functions, facts, and resources of this standard library to Puppet. - -##Usage - -After you've installed stdlib, all of its functions, facts, and resources are available for module use or development. - -If you want to use a standardized set of run stages for Puppet, `include stdlib` in your manifest. - -* `stdlib`: Most of stdlib's features are automatically loaded by Puppet. To use standardized run stages in Puppet, declare this class in your manifest with `include stdlib`. - - When declared, stdlib declares all other classes in the module. The only other class currently included in the module is `stdlib::stages`. - -The `stdlib::stages` class declares various run stages for deploying infrastructure, language runtimes, and application layers. The high level stages are (in order): - - * setup - * main - * runtime - * setup_infra - * deploy_infra - * setup_app - * deploy_app - * deploy - - Sample usage: - - ~~~ - node default { - include stdlib - class { java: stage => 'runtime' } - } - ~~~ - -## Reference - -### Classes - -#### Public Classes - - The stdlib class has no parameters. - -#### Private Classes - -* `stdlib::stages`: Manages a standard set of run stages for Puppet. It is managed by the stdlib class and should not be declared independently. - -### Types - -#### `file_line` - -Ensures that a given line is contained within a file. The implementation -matches the full line, including whitespace at the beginning and end. If -the line is not contained in the given file, Puppet will append the line to -the end of the file to ensure the desired state. Multiple resources may -be declared to manage multiple lines in the same file. - -Example: - - file_line { 'sudo_rule': - path => '/etc/sudoers', - line => '%sudo ALL=(ALL) ALL', - } - - file_line { 'sudo_rule_nopw': - path => '/etc/sudoers', - line => '%sudonopw ALL=(ALL) NOPASSWD: ALL', - } - -In this example, Puppet will ensure both of the specified lines are -contained in the file /etc/sudoers. - -Match Example: - - file_line { 'bashrc_proxy': - ensure => present, - path => '/etc/bashrc', - line => 'export HTTP_PROXY=http://squid.puppetlabs.vm:3128', - match => '^export\ HTTP_PROXY\=', - } - -In this code example match will look for a line beginning with export -followed by HTTP_PROXY and replace it with the value in line. - -Match Example With `ensure => absent`: - - file_line { 'bashrc_proxy': - ensure => absent, - path => '/etc/bashrc', - line => 'export HTTP_PROXY=http://squid.puppetlabs.vm:3128', - match => '^export\ HTTP_PROXY\=', - match_for_absence => true, - } - -In this code example match will look for a line beginning with export -followed by HTTP_PROXY and delete it. If multiple lines match, an -error will be raised unless the `multiple => true` parameter is set. - -**Autorequires:** If Puppet is managing the file that will contain the line -being managed, the file_line resource will autorequire that file. - -##### Parameters -All parameters are optional, unless otherwise noted. - -* `after`: Specifies the line after which Puppet will add any new lines. (Existing lines are added in place.) Valid options: String. Default: Undefined. -* `ensure`: Ensures whether the resource is present. Valid options: 'present', 'absent'. Default: 'present'. -* `line`: **Required.** Sets the line to be added to the file located by the `path` parameter. Valid options: String. Default: Undefined. -* `match`: Specifies a regular expression to run against existing lines in the file; if a match is found, it is replaced rather than adding a new line. A regex comparison is performed against the line value and if it does not match an exception will be raised. Valid options: String containing a regex. Default: Undefined. -* `match_for_absence`: An optional value to determine if match should be applied when `ensure => absent`. If set to true and match is set, the line that matches match will be deleted. If set to false (the default), match is ignored when `ensure => absent` and the value of `line` is used instead. Default: false. -* `multiple`: Determines if `match` and/or `after` can change multiple lines. If set to false, an exception will be raised if more than one line matches. Valid options: 'true', 'false'. Default: Undefined. -* `name`: Sets the name to use as the identity of the resource. This is necessary if you want the resource namevar to differ from the supplied `title` of the resource. Valid options: String. Default: Undefined. -* `path`: **Required.** Defines the file in which Puppet will ensure the line specified by `line`. Must be an absolute path to the file. -* `replace`: Defines whether the resource will overwrite an existing line that matches the `match` parameter. If set to false and a line is found matching the `match` param, the line will not be placed in the file. Valid options: true, false, yes, no. Default: true - -### Functions - -#### `abs` - -Returns the absolute value of a number; for example, '-34.56' becomes '34.56'. Takes a single integer and float value as an argument. *Type*: rvalue. - -#### `any2array` - -Converts any object to an array containing that object. Empty argument lists are converted to an empty array. Arrays are left untouched. Hashes are converted to arrays of alternating keys and values. *Type*: rvalue. - -#### `base64` - -Converts a string to and from base64 encoding. Requires an action ('encode', 'decode') and either a plain or base64-encoded string. *Type*: rvalue. - -#### `basename` - -Returns the `basename` of a path (optionally stripping an extension). For example: - * ('/path/to/a/file.ext') returns 'file.ext' - * ('relative/path/file.ext') returns 'file.ext' - * ('/path/to/a/file.ext', '.ext') returns 'file' - -*Type*: rvalue. - -#### `bool2num` - -Converts a boolean to a number. Converts values: - * 'false', 'f', '0', 'n', and 'no' to 0. - * 'true', 't', '1', 'y', and 'yes' to 1. - Requires a single boolean or string as an input. *Type*: rvalue. - -#### `bool2str` - -Converts a boolean to a string using optionally supplied arguments. The optional -second and third arguments represent what true and false will be converted to -respectively. If only one argument is given, it will be converted from a boolean -to a string containing 'true' or 'false'. - -*Examples:* -~~~ -bool2str(true) => 'true' -bool2str(true, 'yes', 'no') => 'yes' -bool2str(false, 't', 'f') => 'f' -~~~ - -Requires a single boolean as input. *Type*: rvalue. - -#### `capitalize` - -Capitalizes the first character of a string or array of strings, and lower-cases the remaining characters of each string. Requires either a single string or an array as an input. *Type*: rvalue. - -#### `ceiling` - -Returns the smallest integer greater than or equal to the argument. Takes a single numeric value as an argument. *Type*: rvalue. - -#### `chomp` - -Removes the record separator from the end of a string or an array of strings; for example, 'hello\n' becomes 'hello'. Requires a single string or array as an input. *Type*: rvalue. - -#### `chop` - -Returns a new string with the last character removed. If the string ends with '\r\n', both characters are removed. Applying `chop` to an empty string returns an empty string. If you want to merely remove record separators, then you should use the `chomp` function. Requires a string or an array of strings as input. *Type*: rvalue. - -#### `concat` - -Appends the contents of multiple arrays onto the first array given. For example: - * `concat(['1','2','3'],'4')` returns ['1','2','3','4']. - * `concat(['1','2','3'],'4',['5','6','7'])` returns ['1','2','3','4','5','6','7']. - *Type*: rvalue. - -#### `convert_base` - -Converts a given integer or base 10 string representing an integer to a specified base, as a string. For example: - * `convert_base(5, 2)` results in: '101' - * `convert_base('254', '16')` results in: 'fe' - -#### `count` - -If called with only an array, it counts the number of elements that are **not** nil/undef. If called with a second argument, counts the number of elements in an array that matches the second argument. *Type*: rvalue. - -#### `defined_with_params` - -Takes a resource reference and an optional hash of attributes. Returns 'true' if a resource with the specified attributes has already been added to the catalog. Returns 'false' otherwise. - - ~~~ - user { 'dan': - ensure => present, - } - - if ! defined_with_params(User[dan], {'ensure' => 'present' }) { - user { 'dan': ensure => present, } - } - ~~~ - -*Type*: rvalue. - -#### `delete` - -Deletes all instances of a given element from an array, substring from a string, or key from a hash. For example, `delete(['a','b','c','b'], 'b')` returns ['a','c']; `delete('abracadabra', 'bra')` returns 'acada'. `delete({'a' => 1,'b' => 2,'c' => 3},['b','c'])` returns {'a'=> 1}. *Type*: rvalue. - -#### `delete_at` - -Deletes a determined indexed value from an array. For example, `delete_at(['a','b','c'], 1)` returns ['a','c']. *Type*: rvalue. - -#### `delete_values` - -Deletes all instances of a given value from a hash. For example, `delete_values({'a'=>'A','b'=>'B','c'=>'C','B'=>'D'}, 'B')` returns {'a'=>'A','c'=>'C','B'=>'D'} *Type*: rvalue. - -#### `delete_undef_values` - -Deletes all instances of the undef value from an array or hash. For example, `$hash = delete_undef_values({a=>'A', b=>'', c=>undef, d => false})` returns {a => 'A', b => '', d => false}. *Type*: rvalue. - -#### `difference` - -Returns the difference between two arrays. The returned array is a copy of the original array, removing any items that also appear in the second array. For example, `difference(["a","b","c"],["b","c","d"])` returns ["a"]. *Type*: rvalue. - -#### `dirname` - -Returns the `dirname` of a path. For example, `dirname('/path/to/a/file.ext')` returns '/path/to/a'. *Type*: rvalue. - -#### `dos2unix` - -Returns the Unix version of the given string. Very useful when using a File resource with a cross-platform template. *Type*: rvalue. - -~~~ -file{$config_file: - ensure => file, - content => dos2unix(template('my_module/settings.conf.erb')), -} -~~~ - -See also [unix2dos](#unix2dos). - -#### `downcase` - -Converts the case of a string or of all strings in an array to lowercase. *Type*: rvalue. - -#### `empty` - -Returns true if the argument is an array or hash that contains no elements, or an empty string. Returns false when the argument is a numerical value. *Type*: rvalue. - -#### `ensure_packages` - -Takes a list of packages and only installs them if they don't already exist. It optionally takes a hash as a second parameter to be passed as the third argument to the `ensure_resource()` function. *Type*: statement. - -#### `ensure_resource` - -Takes a resource type, title, and a hash of attributes that describe the resource(s). - -~~~ -user { 'dan': - ensure => present, -} -~~~ - -This example only creates the resource if it does not already exist: - - `ensure_resource('user', 'dan', {'ensure' => 'present' })` - -If the resource already exists, but does not match the specified parameters, this function attempts to recreate the resource, leading to a duplicate resource definition error. - -An array of resources can also be passed in, and each will be created with the type and parameters specified if it doesn't already exist. - - `ensure_resource('user', ['dan','alex'], {'ensure' => 'present'})` - -*Type*: statement. - -#### `flatten` - -Flattens deeply nested arrays and returns a single flat array as a result. For example, `flatten(['a', ['b', ['c']]])` returns ['a','b','c']. *Type*: rvalue. - -#### `floor` - -Takes a single numeric value as an argument, and returns the largest integer less than or equal to the argument. *Type*: rvalue. - -#### `fqdn_rand_string` - -Generates a random alphanumeric string using an optionally-specified character set (default is alphanumeric), combining the `$fqdn` fact and an optional seed for repeatable randomness. - -*Usage:* -~~~ -fqdn_rand_string(LENGTH, [CHARSET], [SEED]) -~~~ -*Examples:* -~~~ -fqdn_rand_string(10) -fqdn_rand_string(10, 'ABCDEF!@#$%^') -fqdn_rand_string(10, '', 'custom seed') -~~~ - -*Type*: rvalue. - -#### `fqdn_rotate` - -Rotates an array or string a random number of times, combining the `$fqdn` fact and an optional seed for repeatable randomness. - -*Usage:* -~~~ -fqdn_rotate(VALUE, [SEED]) -~~~ -*Examples:* -~~~ -fqdn_rotate(['a', 'b', 'c', 'd']) -fqdn_rotate('abcd') -fqdn_rotate([1, 2, 3], 'custom seed') -~~~ - -*Type*: rvalue. - -#### `get_module_path` - -Returns the absolute path of the specified module for the current environment. - - `$module_path = get_module_path('stdlib')` - -*Type*: rvalue. - -#### `getparam` - -Takes a resource reference and the name of the parameter, and returns the value of the resource's parameter. - -For example, the following returns 'param_value': - - ~~~ - define example_resource($param) { - } - - example_resource { "example_resource_instance": - param => "param_value" - } - - getparam(Example_resource["example_resource_instance"], "param") - ~~~ - -*Type*: rvalue. - -#### `getvar` - -Looks up a variable in a remote namespace. - -For example: - - ~~~ - $foo = getvar('site::data::foo') - # Equivalent to $foo = $site::data::foo - ~~~ - -This is useful if the namespace itself is stored in a string: - - ~~~ - $datalocation = 'site::data' - $bar = getvar("${datalocation}::bar") - # Equivalent to $bar = $site::data::bar - ~~~ - -*Type*: rvalue. - -#### `grep` - -Searches through an array and returns any elements that match the provided regular expression. For example, `grep(['aaa','bbb','ccc','aaaddd'], 'aaa')` returns ['aaa','aaaddd']. *Type*: rvalue. - -#### `has_interface_with` - -Returns a boolean based on kind and value: - * macaddress - * netmask - * ipaddress - * network - -*Examples:* - - ~~~ - has_interface_with("macaddress", "x:x:x:x:x:x") - has_interface_with("ipaddress", "127.0.0.1") => true - ~~~ - -If no kind is given, then the presence of the interface is checked: - - ~~~ - has_interface_with("lo") => true - ~~~ - -*Type*: rvalue. - -#### `has_ip_address` - -Returns 'true' if the client has the requested IP address on some interface. This function iterates through the `interfaces` fact and checks the `ipaddress_IFACE` facts, performing a simple string comparison. *Type*: rvalue. - -#### `has_ip_network` - -Returns 'true' if the client has an IP address within the requested network. This function iterates through the `interfaces` fact and checks the `network_IFACE` facts, performing a simple string comparision. *Type*: rvalue. - -#### `has_key` - -Determines if a hash has a certain key value. - -*Example*: - - ~~~ - $my_hash = {'key_one' => 'value_one'} - if has_key($my_hash, 'key_two') { - notice('we will not reach here') - } - if has_key($my_hash, 'key_one') { - notice('this will be printed') - } - ~~~ - -*Type*: rvalue. - -#### `hash` - -Converts an array into a hash. For example, `hash(['a',1,'b',2,'c',3])` returns {'a'=>1,'b'=>2,'c'=>3}. *Type*: rvalue. - -#### `intersection` - -Returns an array an intersection of two. For example, `intersection(["a","b","c"],["b","c","d"])` returns ["b","c"]. *Type*: rvalue. - -#### `is_a` - -Boolean check to determine whether a variable is of a given data type. This is equivalent to the `=~` type checks. This function is only available in Puppet 4, or when using the "future" parser. - - ~~~ - foo = 3 - $bar = [1,2,3] - $baz = 'A string!' - - if $foo.is_a(Integer) { - notify { 'foo!': } - } - if $bar.is_a(Array) { - notify { 'bar!': } - } - if $baz.is_a(String) { - notify { 'baz!': } - } - ~~~ - -See the documentation for "The Puppet Type System" for more information about types. -See the `assert_type()` function for flexible ways to assert the type of a value. - -#### `is_array` - -Returns 'true' if the variable passed to this function is an array. *Type*: rvalue. - -#### `is_bool` - -Returns 'true' if the variable passed to this function is a boolean. *Type*: rvalue. - -#### `is_domain_name` - -Returns 'true' if the string passed to this function is a syntactically correct domain name. *Type*: rvalue. - -#### `is_float` - -Returns 'true' if the variable passed to this function is a float. *Type*: rvalue. - -#### `is_function_available` - -Accepts a string as an argument and determines whether the Puppet runtime has access to a function by that name. It returns 'true' if the function exists, 'false' if not. *Type*: rvalue. - -#### `is_hash` - -Returns 'true' if the variable passed to this function is a hash. *Type*: rvalue. - -#### `is_integer` - -Returns 'true' if the variable returned to this string is an integer. *Type*: rvalue. - -#### `is_ip_address` - -Returns 'true' if the string passed to this function is a valid IP address. *Type*: rvalue. - -#### `is_mac_address` - -Returns 'true' if the string passed to this function is a valid MAC address. *Type*: rvalue. - -#### `is_numeric` - -Returns 'true' if the variable passed to this function is a number. *Type*: rvalue. - -#### `is_string` - -Returns 'true' if the variable passed to this function is a string. *Type*: rvalue. - -#### `join` - -Joins an array into a string using a separator. For example, `join(['a','b','c'], ",")` results in: "a,b,c". *Type*: rvalue. - -#### `join_keys_to_values` - -Joins each key of a hash to that key's corresponding value with a separator. Keys and values are cast to strings. The return value is an array in which each element is one joined key/value pair. For example, `join_keys_to_values({'a'=>1,'b'=>2}, " is ")` results in ["a is 1","b is 2"]. *Type*: rvalue. - -#### `keys` - -Returns the keys of a hash as an array. *Type*: rvalue. - -#### `loadyaml` - -Loads a YAML file containing an array, string, or hash, and returns the data in the corresponding native data type. For example: - - ~~~ - $myhash = loadyaml('/etc/puppet/data/myhash.yaml') - ~~~ - -*Type*: rvalue. - -#### `load_module_metadata` - -Loads the metadata.json of a target module. Can be used to determine module version and authorship for dynamic support of modules. - - ~~~ - $metadata = load_module_metadata('archive') - notify { $metadata['author']: } - ~~~ - -If you do not want to fail the catalog compilation if the metadata file for a module is not present: - - ~~~ - $metadata = load_module_metadata('mysql', true) - if empty($metadata) { - notify { "This module does not have a metadata.json file.": } - } - ~~~ - -*Type*: rvalue. - -#### `lstrip` - -Strips spaces to the left of a string. *Type*: rvalue. - -#### `max` - -Returns the highest value of all arguments. Requires at least one argument. *Type*: rvalue. - -#### `member` - -This function determines if a variable is a member of an array. The variable can be either a string, array, or fixnum. For example, `member(['a','b'], 'b')` and `member(['a','b','c'], ['b','c'])` return 'true', while `member(['a','b'], 'c')` and `member(['a','b','c'], ['c','d'])` return 'false'. *Note*: This function does not support nested arrays. If the first argument contains nested arrays, it will not recurse through them. - -*Type*: rvalue. - -#### `merge` - -Merges two or more hashes together and returns the resulting hash. - -*Example*: - - ~~~ - $hash1 = {'one' => 1, 'two' => 2} - $hash2 = {'two' => 'dos', 'three' => 'tres'} - $merged_hash = merge($hash1, $hash2) - # The resulting hash is equivalent to: - # $merged_hash = {'one' => 1, 'two' => 'dos', 'three' => 'tres'} - ~~~ - -When there is a duplicate key, the key in the rightmost hash "wins." *Type*: rvalue. - -#### `min` - -Returns the lowest value of all arguments. Requires at least one argument. *Type*: rvalue. - -#### `num2bool` - -Converts a number or a string representation of a number into a true boolean. Zero or anything non-numeric becomes 'false'. Numbers greater than 0 become 'true'. *Type*: rvalue. - -#### `parsejson` - -Converts a string of JSON into the correct Puppet structure. *Type*: rvalue. -The optional second argument will be returned if the data was not correct. - -#### `parseyaml` - -Converts a string of YAML into the correct Puppet structure. *Type*: rvalue. -The optional second argument will be returned if the data was not correct. - -#### `pick` - -From a list of values, returns the first value that is not undefined or an empty string. Takes any number of arguments, and raises an error if all values are undefined or empty. - - ~~~ - $real_jenkins_version = pick($::jenkins_version, '1.449') - ~~~ - -*Type*: rvalue. - -#### `pick_default` - -Will return the first value in a list of values. Contrary to the 'pick()' function, the 'pick_default()' does not fail if all arguments are empty. This allows it to use an empty value as default. *Type*: rvalue. - -#### `prefix` - -Applies a prefix to all elements in an array, or to the keys in a hash. -For example: -* `prefix(['a','b','c'], 'p')` returns ['pa','pb','pc'] -* `prefix({'a'=>'b','b'=>'c','c'=>'d'}, 'p')` returns {'pa'=>'b','pb'=>'c','pc'=>'d'}. - -*Type*: rvalue. - -#### `assert_private` - -Sets the current class or definition as private. Calling the class or definition from outside the current module will fail. - -For example, `assert_private()` called in class `foo::bar` outputs the following message if class is called from outside module `foo`: - - ~~~ - Class foo::bar is private - ~~~ - - To specify the error message you want to use: - - ~~~ - assert_private("You're not supposed to do that!") - ~~~ - -*Type*: statement. - -#### `pw_hash` - -Hashes a password using the crypt function. Provides a hash usable on most POSIX systems. - -The first argument to this function is the password to hash. If it is undef or an empty string, this function returns undef. - -The second argument to this function is which type of hash to use. It will be converted into the appropriate crypt(3) hash specifier. Valid hash types are: - -|Hash type |Specifier| -|---------------------|---------| -|MD5 |1 | -|SHA-256 |5 | -|SHA-512 (recommended)|6 | - -The third argument to this function is the salt to use. - -*Type*: rvalue. - -**Note:** this uses the Puppet master's implementation of crypt(3). If your environment contains several different operating systems, ensure that they are compatible before using this function. - -#### `range` - -Extrapolates a range as an array when given in the form of '(start, stop)'. For example, `range("0", "9")` returns [0,1,2,3,4,5,6,7,8,9]. Zero-padded strings are converted to integers automatically, so `range("00", "09")` returns [0,1,2,3,4,5,6,7,8,9]. - -Non-integer strings are accepted; `range("a", "c")` returns ["a","b","c"], and `range("host01", "host10")` returns ["host01", "host02", ..., "host09", "host10"]. - -Passing a third argument will cause the generated range to step by that interval, e.g. `range("0", "9", "2")` returns ["0","2","4","6","8"]. - -*Type*: rvalue. - -#### `reject` - -Searches through an array and rejects all elements that match the provided regular expression. For example, `reject(['aaa','bbb','ccc','aaaddd'], 'aaa')` returns ['bbb','ccc']. *Type*: rvalue. - -#### `reverse` - -Reverses the order of a string or array. *Type*: rvalue. - -#### `rstrip` - -Strips spaces to the right of the string. *Type*: rvalue. - -#### `shuffle` - -Randomizes the order of a string or array elements. *Type*: rvalue. - -#### `size` - -Returns the number of elements in a string, an array or a hash. *Type*: rvalue. - -#### `sort` - -Sorts strings and arrays lexically. *Type*: rvalue. - -#### `squeeze` - -Returns a new string where runs of the same character that occur in this set are replaced by a single character. *Type*: rvalue. - -#### `str2bool` - -Converts certain strings to a boolean. This attempts to convert strings that contain the values '1', 't', 'y', and 'yes' to 'true'. Strings that contain values '0', 'f', 'n', and 'no', or are an an empty string or undefined are converted to 'false'. Any other value will cause an error. *Type*: rvalue. - -#### `str2saltedsha512` - -Converts a string to a salted-SHA512 password hash, used for OS X versions >= 10.7. Given any string, this function returns a hex version of a salted-SHA512 password hash, which can be inserted into your Puppet -manifests as a valid password attribute. *Type*: rvalue. - -#### `strftime` - -Returns formatted time. For example, `strftime("%s")` returns the time since Unix epoch, and `strftime("%Y-%m-%d")` returns the date. *Type*: rvalue. - - *Format:* - - * `%a`: The abbreviated weekday name ('Sun') - * `%A`: The full weekday name ('Sunday') - * `%b`: The abbreviated month name ('Jan') - * `%B`: The full month name ('January') - * `%c`: The preferred local date and time representation - * `%C`: Century (20 in 2009) - * `%d`: Day of the month (01..31) - * `%D`: Date (%m/%d/%y) - * `%e`: Day of the month, blank-padded ( 1..31) - * `%F`: Equivalent to %Y-%m-%d (the ISO 8601 date format) - * `%h`: Equivalent to %b - * `%H`: Hour of the day, 24-hour clock (00..23) - * `%I`: Hour of the day, 12-hour clock (01..12) - * `%j`: Day of the year (001..366) - * `%k`: Hour, 24-hour clock, blank-padded ( 0..23) - * `%l`: Hour, 12-hour clock, blank-padded ( 0..12) - * `%L`: Millisecond of the second (000..999) - * `%m`: Month of the year (01..12) - * `%M`: Minute of the hour (00..59) - * `%n`: Newline (\n) - * `%N`: Fractional seconds digits, default is 9 digits (nanosecond) - * `%3N`: Millisecond (3 digits) - * `%6N`: Microsecond (6 digits) - * `%9N`: Nanosecond (9 digits) - * `%p`: Meridian indicator ('AM' or 'PM') - * `%P`: Meridian indicator ('am' or 'pm') - * `%r`: Time, 12-hour (same as %I:%M:%S %p) - * `%R`: Time, 24-hour (%H:%M) - * `%s`: Number of seconds since the Unix epoch, 1970-01-01 00:00:00 UTC. - * `%S`: Second of the minute (00..60) - * `%t`: Tab character ( ) - * `%T`: Time, 24-hour (%H:%M:%S) - * `%u`: Day of the week as a decimal, Monday being 1. (1..7) - * `%U`: Week number of the current year, starting with the first Sunday as the first day of the first week (00..53) - * `%v`: VMS date (%e-%b-%Y) - * `%V`: Week number of year according to ISO 8601 (01..53) - * `%W`: Week number of the current year, starting with the first Monday as the first day of the first week (00..53) - * `%w`: Day of the week (Sunday is 0, 0..6) - * `%x`: Preferred representation for the date alone, no time - * `%X`: Preferred representation for the time alone, no date - * `%y`: Year without a century (00..99) - * `%Y`: Year with century - * `%z`: Time zone as hour offset from UTC (e.g. +0900) - * `%Z`: Time zone name - * `%%`: Literal '%' character - -#### `strip` - -Removes leading and trailing whitespace from a string or from every string inside an array. For example, `strip(" aaa ")` results in "aaa". *Type*: rvalue. - -#### `suffix` - -Applies a suffix to all elements in an array. For example, `suffix(['a','b','c'], 'p')` returns ['ap','bp','cp']. *Type*: rvalue. - -#### `swapcase` - -Swaps the existing case of a string. For example, `swapcase("aBcD")` results in "AbCd". *Type*: rvalue. - -#### `time` - -Returns the current Unix epoch time as an integer. For example, `time()` returns something like '1311972653'. *Type*: rvalue. - -#### `to_bytes` - -Converts the argument into bytes, for example "4 kB" becomes "4096". Takes a single string value as an argument. *Type*: rvalue. - -#### `try_get_value` - -*Type*: rvalue. - -Looks up into a complex structure of arrays and hashes to extract a value by -its path in the structure. The path is a string of hash keys or array indexes -starting with zero, separated by the path separator character (default "/"). -The function will go down the structure by each path component and will try to -return the value at the end of the path. - -In addition to the required "path" argument the function accepts the default -argument. It will be returned if the path is not correct, no value was found or -a any other error have occurred. And the last argument can set the path -separator character. - -```ruby -$data = { - 'a' => { - 'b' => [ - 'b1', - 'b2', - 'b3', - ] - } -} - -$value = try_get_value($data, 'a/b/2') -# $value = 'b3' - -# with all possible options -$value = try_get_value($data, 'a/b/2', 'not_found', '/') -# $value = 'b3' - -# using the default value -$value = try_get_value($data, 'a/b/c/d', 'not_found') -# $value = 'not_found' - -# using custom separator -$value = try_get_value($data, 'a|b', [], '|') -# $value = ['b1','b2','b3'] -``` - -1. **$data** The data structure we are working with. -2. **'a/b/2'** The path string. -3. **'not_found'** The default value. It will be returned if nothing is found. - (optional, defaults to *undef*) -4. **'/'** The path separator character. - (optional, defaults to *'/'*) - -#### `type3x` - -Returns a string description of the type when passed a value. Type can be a string, array, hash, float, integer, or boolean. This function will be removed when Puppet 3 support is dropped and the new type system can be used. *Type*: rvalue. - -#### `type_of` - -Returns the literal type when passed a value. Requires the new parser. Useful for comparison of types with `<=` such as in `if type_of($some_value) <= Array[String] { ... }` (which is equivalent to `if $some_value =~ Array[String] { ... }`) *Type*: rvalue. - -#### `union` - -Returns a union of two or more arrays, without duplicates. For example, `union(["a","b","c"],["b","c","d"])` returns ["a","b","c","d"]. *Type*: rvalue. - -#### `unique` - -Removes duplicates from strings and arrays. For example, `unique("aabbcc")` returns 'abc', and `unique(["a","a","b","b","c","c"])` returns ["a","b","c"]. *Type*: rvalue. - -#### `unix2dos` - -Returns the DOS version of the given string. Very useful when using a File resource with a cross-platform template. *Type*: rvalue. - -~~~ -file{$config_file: - ensure => file, - content => unix2dos(template('my_module/settings.conf.erb')), -} -~~~ - -See also [dos2unix](#dos2unix). - -#### `upcase` - -Converts an object, array or hash of objects that respond to upcase to uppercase. For example, `upcase('abcd')` returns 'ABCD'. *Type*: rvalue. - -#### `uriescape` - -URLEncodes a string or array of strings. Requires either a single string or an array as an input. *Type*: rvalue. - -#### `validate_absolute_path` - -Validates that a given string represents an absolute path in the filesystem. Works for Windows and Unix style paths. - -The following values pass: - -~~~ -$my_path = 'C:/Program Files (x86)/Puppet Labs/Puppet' -validate_absolute_path($my_path) -$my_path2 = '/var/lib/puppet' -validate_absolute_path($my_path2) -$my_path3 = ['C:/Program Files (x86)/Puppet Labs/Puppet','C:/Program Files/Puppet Labs/Puppet'] -validate_absolute_path($my_path3) -$my_path4 = ['/var/lib/puppet','/usr/share/puppet'] -validate_absolute_path($my_path4) -~~~ - -The following values fail, causing compilation to abort: - -~~~ -validate_absolute_path(true) -validate_absolute_path('../var/lib/puppet') -validate_absolute_path('var/lib/puppet') -validate_absolute_path([ 'var/lib/puppet', '/var/foo' ]) -validate_absolute_path([ '/var/lib/puppet', 'var/foo' ]) -$undefined = undef -validate_absolute_path($undefined) -~~~ - -*Type*: statement. - -#### `validate_array` - -Validates that all passed values are array data structures. Aborts catalog compilation if any value fails this check. - -The following values pass: - -~~~ -$my_array = [ 'one', 'two' ] -validate_array($my_array) -~~~ - -The following values fail, causing compilation to abort: - -~~~ -validate_array(true) -validate_array('some_string') -$undefined = undef -validate_array($undefined) -~~~ - -*Type*: statement. - -#### `validate_augeas` - -Performs validation of a string using an Augeas lens. The first argument of this function should be the string to test, and the second argument should be the name of the Augeas lens to use. If Augeas fails to parse the string with the lens, the compilation aborts with a parse error. - -A third optional argument lists paths which should **not** be found in the file. The `$file` variable points to the location of the temporary file being tested in the Augeas tree. - -For example, to make sure your $passwdcontent never contains user `foo`: - -~~~ -validate_augeas($passwdcontent, 'Passwd.lns', ['$file/foo']) -~~~ - -To ensure that no users use the '/bin/barsh' shell: - -~~~ -validate_augeas($passwdcontent, 'Passwd.lns', ['$file/*[shell="/bin/barsh"]'] -~~~ - -You can pass a fourth argument as the error message raised and shown to the user: - -~~~ -validate_augeas($sudoerscontent, 'Sudoers.lns', [], 'Failed to validate sudoers content with Augeas') -~~~ - -*Type*: statement. - -#### `validate_bool` - -Validates that all passed values are either true or false. Aborts catalog compilation if any value fails this check. - -The following values will pass: - -~~~ -$iamtrue = true -validate_bool(true) -validate_bool(true, true, false, $iamtrue) -~~~ - -The following values will fail, causing compilation to abort: - -~~~ -$some_array = [ true ] -validate_bool("false") -validate_bool("true") -validate_bool($some_array) -~~~ - -*Type*: statement. - -#### `validate_cmd` - -Performs validation of a string with an external command. The first argument of this function should be a string to test, and the second argument should be a path to a test command taking a % as a placeholder for the file path (will default to the end of the command if no % placeholder given). If the command is launched against a tempfile containing the passed string, or returns a non-null value, compilation will abort with a parse error. - -If a third argument is specified, this will be the error message raised and seen by the user. - -~~~ -# Defaults to end of path -validate_cmd($sudoerscontent, '/usr/sbin/visudo -c -f', 'Visudo failed to validate sudoers content') -~~~ -~~~ -# % as file location -validate_cmd($haproxycontent, '/usr/sbin/haproxy -f % -c', 'Haproxy failed to validate config content') -~~~ - -*Type*: statement. - -#### `validate_hash` - -Validates that all passed values are hash data structures. Aborts catalog compilation if any value fails this check. - - The following values will pass: - - ~~~ - $my_hash = { 'one' => 'two' } - validate_hash($my_hash) - ~~~ - - The following values will fail, causing compilation to abort: - - ~~~ - validate_hash(true) - validate_hash('some_string') - $undefined = undef - validate_hash($undefined) - ~~~ - -*Type*: statement. - -#### `validate_integer` - -Validates that the first argument is an integer (or an array of integers). Aborts catalog compilation if any of the checks fail. - - The second argument is optional and passes a maximum. (All elements of) the first argument has to be less or equal to this max. - - The third argument is optional and passes a minimum. (All elements of) the first argument has to be greater or equal to this min. - If, and only if, a minimum is given, the second argument may be an empty string or undef, which will be handled to just check - if (all elements of) the first argument are greater or equal to the given minimum. - - It will fail if the first argument is not an integer or array of integers, and if arg 2 and arg 3 are not convertable to an integer. - - The following values will pass: - - ~~~ - validate_integer(1) - validate_integer(1, 2) - validate_integer(1, 1) - validate_integer(1, 2, 0) - validate_integer(2, 2, 2) - validate_integer(2, '', 0) - validate_integer(2, undef, 0) - $foo = undef - validate_integer(2, $foo, 0) - validate_integer([1,2,3,4,5], 6) - validate_integer([1,2,3,4,5], 6, 0) - ~~~ - - * Plus all of the above, but any combination of values passed as strings ('1' or "1"). - * Plus all of the above, but with (correct) combinations of negative integer values. - - The following values will fail, causing compilation to abort: - - ~~~ - validate_integer(true) - validate_integer(false) - validate_integer(7.0) - validate_integer({ 1 => 2 }) - $foo = undef - validate_integer($foo) - validate_integer($foobaridontexist) - - validate_integer(1, 0) - validate_integer(1, true) - validate_integer(1, '') - validate_integer(1, undef) - validate_integer(1, , 0) - validate_integer(1, 2, 3) - validate_integer(1, 3, 2) - validate_integer(1, 3, true) - ~~~ - - * Plus all of the above, but any combination of values passed as strings ('false' or "false"). - * Plus all of the above, but with incorrect combinations of negative integer values. - * Plus all of the above, but with non-integer items in arrays or maximum / minimum argument. - - *Type*: statement. - -#### `validate_ip_address` - -Validates that argument is an IP address, regardless of it is an IPv4 or an IPv6 -address. It validates as well IP address with netmask. It must be an String, as -well. - -The following values will pass: - - ~~~ - validate_ip_address('0.0.0.0') - validate_ip_address('8.8.8.8') - validate_ip_address('127.0.0.1') - validate_ip_address('194.232.104.150') - validate_ip_address('3ffe:0505:0002::') - validate_ip_address('::1/64') - validate_ip_address('fe80::a00:27ff:fe94:44d6/64') - validate_ip_address('8.8.8.8/32') - ~~~ - -The following values will fail, causing compilation to abort: - - ~~~ - validate_ip_address(1) - validate_ip_address(true) - validate_ip_address(0.0.0.256) - validate_ip_address('::1', {}) - validate_ip_address('0.0.0.0.0') - validate_ip_address('3.3.3') - validate_ip_address('23.43.9.22/64') - validate_ip_address('260.2.32.43') - ~~~ - - -#### `validate_numeric` - -Validates that the first argument is a numeric value (or an array of numeric values). Aborts catalog compilation if any of the checks fail. - - The second argument is optional and passes a maximum. (All elements of) the first argument has to be less or equal to this max. - - The third argument is optional and passes a minimum. (All elements of) the first argument has to be greater or equal to this min. - If, and only if, a minimum is given, the second argument may be an empty string or undef, which will be handled to just check - if (all elements of) the first argument are greater or equal to the given minimum. - - It will fail if the first argument is not a numeric (Integer or Float) or array of numerics, and if arg 2 and arg 3 are not convertable to a numeric. - - For passing and failing usage, see `validate_integer()`. It is all the same for validate_numeric, yet now floating point values are allowed, too. - -*Type*: statement. - -#### `validate_re` - -Performs simple validation of a string against one or more regular expressions. The first argument of this function should be the string to -test, and the second argument should be a stringified regular expression (without the // delimiters) or an array of regular expressions. If none of the regular expressions match the string passed in, compilation aborts with a parse error. - - You can pass a third argument as the error message raised and shown to the user. - - The following strings validate against the regular expressions: - - ~~~ - validate_re('one', '^one$') - validate_re('one', [ '^one', '^two' ]) - ~~~ - - The following string fails to validate, causing compilation to abort: - - ~~~ - validate_re('one', [ '^two', '^three' ]) - ~~~ - - To set the error message: - - ~~~ - validate_re($::puppetversion, '^2.7', 'The $puppetversion fact value does not match 2.7') - ~~~ - - Note: Compilation will also abort, if the first argument is not a String. Always use - quotes to force stringification: - - ~~~ - validate_re("${::operatingsystemmajrelease}", '^[57]$') - ~~~ - -*Type*: statement. - -#### `validate_slength` - -Validates that the first argument is a string (or an array of strings), and is less than or equal to the length of the second argument. It fails if the first argument is not a string or array of strings, or if arg 2 is not convertable to a number. Optionally, a minimum string length can be given as the third argument. - - The following values pass: - - ~~~ - validate_slength("discombobulate",17) - validate_slength(["discombobulate","moo"],17) - validate_slength(["discombobulate","moo"],17,3) - ~~~ - - The following values fail: - - ~~~ - validate_slength("discombobulate",1) - validate_slength(["discombobulate","thermometer"],5) - validate_slength(["discombobulate","moo"],17,10) - ~~~ - -*Type*: statement. - -#### `validate_string` - -Validates that all passed values are string data structures. Aborts catalog compilation if any value fails this check. - -The following values pass: - - ~~~ - $my_string = "one two" - validate_string($my_string, 'three') - ~~~ - - The following values fail, causing compilation to abort: - - ~~~ - validate_string(true) - validate_string([ 'some', 'array' ]) - ~~~ - -*Note:* validate_string(undef) will not fail in this version of the functions API (incl. current and future parser). - -Instead, use: - - ~~~ - if $var == undef { - fail('...') - } - ~~~ - -*Type*: statement. - -#### `values` - -Returns the values of a given hash. For example, given `$hash = {'a'=1, 'b'=2, 'c'=3} values($hash)` returns [1,2,3]. - -*Type*: rvalue. - -#### `values_at` - -Finds values inside an array based on location. The first argument is the array you want to analyze, and the second argument can be a combination of: - - * A single numeric index - * A range in the form of 'start-stop' (eg. 4-9) - * An array combining the above - - For example, `values_at(['a','b','c'], 2)` returns ['c']; `values_at(['a','b','c'], ["0-1"])` returns ['a','b']; and `values_at(['a','b','c','d','e'], [0, "2-3"])` returns ['a','c','d']. - -*Type*: rvalue. - -#### `zip` - -Takes one element from first array given and merges corresponding elements from second array given. This generates a sequence of n-element arrays, where *n* is one more than the count of arguments. For example, `zip(['1','2','3'],['4','5','6'])` results in ["1", "4"], ["2", "5"], ["3", "6"]. *Type*: rvalue. - -##Limitations - -As of Puppet Enterprise 3.7, the stdlib module is no longer included in PE. PE users should install the most recent release of stdlib for compatibility with Puppet modules. - -###Version Compatibility - -Versions | Puppet 2.6 | Puppet 2.7 | Puppet 3.x | Puppet 4.x | -:---------------|:-----:|:---:|:---:|:----: -**stdlib 2.x** | **yes** | **yes** | no | no -**stdlib 3.x** | no | **yes** | **yes** | no -**stdlib 4.x** | no | **yes** | **yes** | no -**stdlib 4.6+** | no | **yes** | **yes** | **yes** -**stdlib 5.x** | no | no | **yes** | **yes** - -**stdlib 5.x**: When released, stdlib 5.x will drop support for Puppet 2.7.x. Please see [this discussion](https://github.com/puppetlabs/puppetlabs-stdlib/pull/176#issuecomment-30251414). - -##Development - -Puppet Labs modules on the Puppet Forge are open projects, and community contributions are essential for keeping them great. We can’t access the huge number of platforms and myriad hardware, software, and deployment configurations that Puppet is intended to serve. We want to keep it as easy as possible to contribute changes so that our modules work in your environment. There are a few guidelines that we need contributors to follow so that we can have a chance of keeping on top of things. For more information, see our [module contribution guide.](https://docs.puppetlabs.com/forge/contributing.html) - -To report or research a bug with any part of this module, please go to -[http://tickets.puppetlabs.com/browse/PUP](http://tickets.puppetlabs.com/browse/PUP). - -##Contributors - -The list of contributors can be found at: https://github.com/puppetlabs/puppetlabs-stdlib/graphs/contributors diff --git a/README.md b/README.md new file mode 100644 index 000000000..1c56e5e35 --- /dev/null +++ b/README.md @@ -0,0 +1,593 @@ +# stdlib + +#### Table of Contents + +1. [Overview](#overview) +1. [Module Description](#module-description) +1. [Setup](#setup) +1. [Usage](#usage) +1. [Reference](#reference) + 1. [Data Types](#data-types) + 1. [Facts](#facts) +1. [Limitations](#limitations) +1. [License](#license) +1. [Development](#development) +1. [Contributors](#contributors) + +## Overview + +This module provides a standard library of resources for Puppet modules. + +## Module Description + +Puppet modules make heavy use of this standard library. The stdlib module adds the following resources to Puppet: + + * Stages + * Facts + * Functions + * Defined types + * Data types + * Providers + +> *Note:* As of version 3.7, Puppet Enterprise no longer includes the stdlib module. If you're running Puppet Enterprise, you should install the most recent release of stdlib for compatibility with Puppet modules. + +## Setup + +[Install](https://puppet.com/docs/puppet/latest/modules_installing.html) the stdlib module to add the functions, facts, and resources of this standard library to Puppet. + +If you are authoring a module that depends on stdlib, be sure to [specify dependencies](https://puppet.com/docs/puppet/latest/modules_installing.html) in your metadata.json. + +## Usage + +Most of stdlib's features are automatically loaded by Puppet. To use standardized run stages in Puppet, declare this class in your manifest with `include stdlib`. + +When declared, stdlib declares all other classes in the module. This currently consists of `stdlib::manage` and `stdlib::stages`. + +The `stdlib::stages` class declares various run stages for deploying infrastructure, language runtimes, and application layers. The high level stages are (in order): + + * setup + * main + * runtime + * setup_infra + * deploy_infra + * setup_app + * deploy_app + * deploy + +Sample usage: + +```puppet +node default { + include stdlib + class { java: stage => 'runtime' } +} +``` + +The `stdlib::manage` class provides an interface for generating trivial resource declarations via the `create_resources` parameter. Depending on your usage, you may want to set `hiera`'s `lookup_options` for the `stdlib::manage::create_resources:` element. + +```yaml +--- +stdlib::manage::create_resources: + file: + /etc/somefile: + ensure: file + owner: root + group: root + package: + badpackage: + ensure: absent +``` + +## Reference + +For information on the classes and types, see the [REFERENCE.md](https://github.com/puppetlabs/puppetlabs-stdlib/blob/main/REFERENCE.md). + + +### Data types + +#### `Stdlib::Absolutepath` + +A strict absolute path type. Uses a variant of Unixpath and Windowspath types. + +Acceptable input examples: + +```shell +/var/log +``` + +```shell +/usr2/username/bin:/usr/local/bin:/usr/bin:. +``` + +```shell +C:\\WINDOWS\\System32 +``` + +Unacceptable input example: + +```shell +../relative_path +``` + +#### `Stdlib::Ensure::Service` + +Matches acceptable ensure values for service resources. + +Acceptable input examples: + +```shell +stopped +running +``` + +Unacceptable input example: + +```shell +true +false +``` + +#### `Stdlib::HTTPSUrl` + +Matches HTTPS URLs. It is a case insensitive match. + +Acceptable input example: + +```shell +https://hello.com + +HTTPS://HELLO.COM +``` + +Unacceptable input example: + +```shell +httds://notquiteright.org` +``` + +#### `Stdlib::HTTPUrl` + +Matches both HTTPS and HTTP URLs. It is a case insensitive match. + +Acceptable input example: + +```shell +https://hello.com + +http://hello.com + +HTTP://HELLO.COM +``` + +Unacceptable input example: + +```shell +httds://notquiteright.org +``` + +#### `Stdlib::MAC` + +Matches MAC addresses defined in [RFC5342](https://tools.ietf.org/html/rfc5342). + +#### `Stdlib::Unixpath` + +Matches absolute paths on Unix operating systems. + +Acceptable input example: + +```shell +/usr2/username/bin:/usr/local/bin:/usr/bin: + +/var/tmp +``` + +Unacceptable input example: + +```shell +C:/whatever + +some/path + +../some/other/path +``` + +#### `Stdlib::Filemode` + +Matches octal file modes consisting of one to four numbers and symbolic file modes. + +Acceptable input examples: + +```shell +0644 +``` + +```shell +1777 +``` + +```shell +a=Xr,g=w +``` + +Unacceptable input examples: + +```shell +x=r,a=wx +``` + +```shell +0999 +``` + +#### `Stdlib::Windowspath` + +Matches paths on Windows operating systems. + +Acceptable input example: + +```shell +C:\\WINDOWS\\System32 + +C:\\ + +\\\\host\\windows +``` + +Valid values: A windows filepath. + +#### `Stdlib::Filesource` + +Matches paths valid values for the source parameter of the Puppet file type. + +Acceptable input example: + +```shell +http://example.com + +https://example.com + +file:///hello/bla +``` + +Valid values: A filepath. + +#### `Stdlib::Fqdn` + +Matches paths on fully qualified domain name. + +Acceptable input example: + +```shell +localhost + +example.com + +www.example.com +``` +Valid values: Domain name of a server. + +#### `Stdlib::Host` + +Matches a valid host which could be a valid ipv4, ipv6 or fqdn. + +Acceptable input example: + +```shell +localhost + +www.example.com + +192.0.2.1 +``` + +Valid values: An IP address or domain name. + +#### `Stdlib::Port` + +Matches a valid TCP/UDP Port number. + +Acceptable input examples: + +```shell +80 + +443 + +65000 +``` + +Valid values: An Integer. + +#### `Stdlib::Port::Privileged` + +Matches a valid TCP/UDP Privileged port i.e. < 1024. + +Acceptable input examples: + +```shell +80 + +443 + +1023 +``` + +Valid values: A number less than 1024. + +#### `Stdlib::Port::Unprivileged` + +Matches a valid TCP/UDP Privileged port i.e. >= 1024. + +Acceptable input examples: + +```shell +1024 + +1337 + +65000 + +``` + +Valid values: A number more than or equal to 1024. + +#### `Stdlib::Base32` + +Matches paths a valid base32 string. + +Acceptable input example: + +```shell +ASDASDDASD3453453 + +asdasddasd3453453= + +ASDASDDASD3453453== +``` + +Valid values: A base32 string. + +#### `Stdlib::Base64` + +Matches paths a valid base64 string. + +Acceptable input example: + +```shell +asdasdASDSADA342386832/746+= + +asdasdASDSADA34238683274/6+ + +asdasdASDSADA3423868327/46+== +``` + +Valid values: A base64 string. + +#### `Stdlib::Ipv4` + +This type is no longer available. To make use of this functionality, use [Stdlib::IP::Address::V4](https://github.com/puppetlabs/puppetlabs-stdlib#stdlibipaddressv4). + +#### `Stdlib::Ipv6` + +This type is no longer available. To make use of this functionality, use [Stdlib::IP::Address::V6](https://github.com/puppetlabs/puppetlabs-stdlib#stdlibipaddressv6). + +#### `Stdlib::Ip_address` + +This type is no longer available. To make use of this functionality, use [Stdlib::IP::Address](https://github.com/puppetlabs/puppetlabs-stdlib#stdlibipaddress) + +#### `Stdlib::IP::Address` + +Matches any IP address, including both IPv4 and IPv6 addresses. It will match them either with or without an address prefix as used in CIDR format IPv4 addresses. + +Examples: + +``` +'127.0.0.1' =~ Stdlib::IP::Address # true +'10.1.240.4/24' =~ Stdlib::IP::Address # true +'52.10.10.141' =~ Stdlib::IP::Address # true +'192.168.1' =~ Stdlib::IP::Address # false +'FEDC:BA98:7654:3210:FEDC:BA98:7654:3210' =~ Stdlib::IP::Address # true +'FF01:0:0:0:0:0:0:101' =~ Stdlib::IP::Address # true +``` + +#### `Stdlib::IP::Address::V4` + +Match any string consisting of an IPv4 address in the quad-dotted decimal format, with or without a CIDR prefix. It will not match any abbreviated form (for example, 192.168.1) because these are poorly documented and inconsistently supported. + +Examples: + +``` +'127.0.0.1' =~ Stdlib::IP::Address::V4 # true +'10.1.240.4/24' =~ Stdlib::IP::Address::V4 # true +'192.168.1' =~ Stdlib::IP::Address::V4 # false +'FEDC:BA98:7654:3210:FEDC:BA98:7654:3210' =~ Stdlib::IP::Address::V4 # false +'12AB::CD30:192.168.0.1' =~ Stdlib::IP::Address::V4 # false +``` + +Valid values: An IPv4 address. + +#### `Stdlib::IP::Address::V6` + +Match any string consisting of an IPv6 address in any of the documented formats in RFC 2373, with or without an address prefix. + +Examples: + +``` +'127.0.0.1' =~ Stdlib::IP::Address::V6 # false +'10.1.240.4/24' =~ Stdlib::IP::Address::V6 # false +'FEDC:BA98:7654:3210:FEDC:BA98:7654:3210' =~ Stdlib::IP::Address::V6 # true +'FF01:0:0:0:0:0:0:101' =~ Stdlib::IP::Address::V6 # true +'FF01::101' =~ Stdlib::IP::Address::V6 # true +``` + +Valid values: An IPv6 address. + +#### `Stdlib::IP::Address::Nosubnet` + +Match the same things as the `Stdlib::IP::Address` alias, except it will not match an address that includes an address prefix (for example, it will match '192.168.0.6' but not '192.168.0.6/24'). + +Valid values: An IP address with no subnet. + +#### `Stdlib::IP::Address::V4::CIDR` + +Match an IPv4 address in the CIDR format. It will only match if the address contains an address prefix (for example, it will match '192.168.0.6/24' +but not '192.168.0.6'). + +Valid values: An IPv4 address with a CIDR provided eg: '192.186.8.101/105'. This will match anything inclusive of '192.186.8.101' to '192.168.8.105'. + +#### `Stdlib::IP::Address::V4::Nosubnet` + +Match an IPv4 address only if the address does not contain an address prefix (for example, it will match '192.168.0.6' but not '192.168.0.6/24'). + +Valid values: An IPv4 address with no subnet. + +#### `Stdlib::IP::Address::V6::Full` + +Match an IPv6 address formatted in the "preferred form" as documented in section 2.2 of [RFC 2373](https://www.ietf.org/rfc/rfc2373.txt), with or without an address prefix as documented in section 2.3 of [RFC 2373](https://www.ietf.org/rfc/rfc2373.txt). + +#### `Stdlib::IP::Address::V6::Alternate` + +Match an IPv6 address formatted in the "alternative form" allowing for representing the last two 16-bit pieces of the address with a quad-dotted decimal, as documented in section 2.2.1 of [RFC 2373](https://www.ietf.org/rfc/rfc2373.txt). It will match addresses with or without an address prefix as documented in section 2.3 of [RFC 2373](https://www.ietf.org/rfc/rfc2373.txt). + +#### `Stdlib::IP::Address::V6::Compressed` + +Match an IPv6 address which may contain `::` used to compress zeros as documented in section 2.2.2 of [RFC 2373](https://www.ietf.org/rfc/rfc2373.txt). It will match addresses with or without an address prefix as documented in section 2.3 of [RFC 2373](https://www.ietf.org/rfc/rfc2373.txt). + +#### `Stdlib::IP::Address::V6::Nosubnet` + +Alias to allow `Stdlib::IP::Address::V6::Nosubnet::Full`, `Stdlib::IP::Address::V6::Nosubnet::Alternate` and `Stdlib::IP::Address::V6::Nosubnet::Compressed`. + +#### `Stdlib::IP::Address::V6::Nosubnet::Full` + +Match an IPv6 address formatted in the "preferred form" as documented in section 2.2 of [RFC 2373](https://www.ietf.org/rfc/rfc2373.txt). It will not match addresses with address prefix as documented in section 2.3 of [RFC 2373](https://www.ietf.org/rfc/rfc2373.txt). + +#### `Stdlib::IP::Address::V6::Nosubnet::Alternate` + +Match an IPv6 address formatted in the "alternative form" allowing for representing the last two 16-bit pieces of the address with a quad-dotted decimal, as documented in section 2.2.1 of [RFC 2373](https://www.ietf.org/rfc/rfc2373.txt). It will only match addresses without an address prefix as documented in section 2.3 of [RFC 2373](https://www.ietf.org/rfc/rfc2373.txt). + +#### `Stdlib::IP::Address::V6::Nosubnet::Compressed` + +Match an IPv6 address which may contain `::` used to compress zeros as documented in section 2.2.2 of [RFC 2373](https://www.ietf.org/rfc/rfc2373.txt). It will only match addresses without an address prefix as documented in section 2.3 of [RFC 2373](https://www.ietf.org/rfc/rfc2373.txt). + +#### `Stdlib::IP::Address::V6::CIDR` + +Match an IPv6 address in the CIDR format. It will only match if the address contains an address prefix (for example, it will match 'FF01:0:0:0:0:0:0:101/32', 'FF01::101/60', '::/0', +but not 'FF01:0:0:0:0:0:0:101', 'FF01::101', '::'). + +#### `Stdlib::ObjectStore` + +Matches cloud object store uris. + +Acceptable input example: + +```shell +s3://mybucket/path/to/file + +gs://bucket/file + +``` +Valid values: cloud object store uris. + + +#### `Stdlib::ObjectStore::GSUri` + +Matches Google Cloud object store uris. + +Acceptable input example: + +```shell + +gs://bucket/file + +gs://bucket/path/to/file + +``` +Valid values: Google Cloud object store uris. + + +#### `Stdlib::ObjectStore::S3Uri` + +Matches Amazon Web Services S3 object store uris. + +Acceptable input example: + +```shell +s3://bucket/file + +s3://bucket/path/to/file + +``` +Valid values: Amazon Web Services S3 object store uris. + +#### `Stdlib::Syslogfacility` + +An enum that defines all syslog facilities defined in [RFC5424](https://tools.ietf.org/html/rfc5424). This is based on work in the [voxpupuli/nrpe](https://github.com/voxpupuli/puppet-nrpe/commit/5700fd4f5bfc3e237195c8833039f9ed1045cd6b) module. + + +### Facts + +#### `package_provider` + +Returns the default provider Puppet uses to manage packages on this system. + +#### `is_pe` + +Returns whether Puppet Enterprise is installed. Does not report anything on platforms newer than PE 3.x. + +#### `pe_version` + +Returns the version of Puppet Enterprise installed. Does not report anything on platforms newer than PE 3.x. + +#### `pe_major_version` + +Returns the major version Puppet Enterprise that is installed. Does not report anything on platforms newer than PE 3.x. + +#### `pe_minor_version` + +Returns the minor version of Puppet Enterprise that is installed. Does not report anything on platforms newer than PE 3.x. + +#### `pe_patch_version` + +Returns the patch version of Puppet Enterprise that is installed. + +#### `puppet_vardir` + +Returns the value of the Puppet vardir setting for the node running Puppet or Puppet agent. + +#### `puppet_environmentpath` + +Returns the value of the Puppet environment path settings for the node running Puppet or Puppet agent. + +#### `puppet_server` + +Returns the Puppet agent's `server` value, which is the hostname of the Puppet server with which the agent should communicate. + +#### `root_home` + +Determines the root home directory. + +Determines the root home directory, which depends on your operating system. Generally this is '/root'. + +#### `service_provider` + +Returns the default provider Puppet uses to manage services on this system + +## Limitations + +As of Puppet Enterprise 3.7, the stdlib module is no longer included in PE. PE users should install the most recent release of stdlib for compatibility with Puppet modules. + +For an extensive list of supported operating systems, see [metadata.json](https://github.com/puppetlabs/puppetlabs-stdlib/blob/main/metadata.json) + +## License + +This codebase is licensed under the Apache2.0 licensing, however due to the nature of the codebase the open source dependencies may also use a combination of [AGPL](https://www.gnu.org/licenses/agpl-3.0.en.html), [BSD-2](https://opensource.org/license/bsd-2-claus), [BSD-3](https://opensource.org/license/bsd-3-claus), [GPL2.0](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html), [LGPL](https://opensource.org/license/lgpl-3-0/), [MIT](https://opensource.org/license/mit/) and [MPL](https://opensource.org/license/mpl-2-0/) Licensing. + +## Development + +Puppet modules on the Puppet Forge are open projects, and community contributions are essential for keeping them great. We can’t access the huge number of platforms and myriad hardware, software, and deployment configurations that Puppet is intended to serve. We want to keep it as easy as possible to contribute changes so that our modules work in your environment. There are a few guidelines that we need contributors to follow so that we can have a chance of keeping on top of things. For more information, see our [module contribution guide](https://github.com/puppetlabs/puppetlabs-stdlib/blob/main/CONTRIBUTING.md). + +To report or research a bug with any part of this module, please go to [https://github.com/puppetlabs/puppetlabs-stdlib/issues](https://github.com/puppetlabs/puppetlabs-stdlib/issues). + +## Contributors + +The list of contributors can be found at: [https://github.com/puppetlabs/puppetlabs-stdlib/graphs/contributors](https://github.com/puppetlabs/puppetlabs-stdlib/graphs/contributors). diff --git a/REFERENCE.md b/REFERENCE.md new file mode 100644 index 000000000..a472419bc --- /dev/null +++ b/REFERENCE.md @@ -0,0 +1,5910 @@ +# Reference + + + +## Table of Contents + +### Classes + +* [`stdlib`](#stdlib): This module manages stdlib. +* [`stdlib::manage`](#stdlib--manage): A simple place to define trivial resources +* [`stdlib::stages`](#stdlib--stages): This class manages a standard set of run stages for Puppet. It is managed by +the stdlib class, and should not be declared independently. + +### Resource types + +* [`anchor`](#anchor): A simple resource type intended to be used as an anchor in a composite class. +* [`file_line`](#file_line): Ensures that a given line is contained within a file. + +### Functions + +* [`any2array`](#any2array): This converts any object to an array containing that object. +* [`any2bool`](#any2bool): Converts 'anything' to a boolean. +* [`assert_private`](#assert_private): Sets the current class or definition as private. +* [`base64`](#base64): Base64 encode or decode a string based on the command and the string submitted +* [`basename`](#basename): Strips directory (and optional suffix) from a filename +* [`batch_escape`](#batch_escape): DEPRECATED. Use the namespaced function [`stdlib::batch_escape`](#stdlibbatch_escape) instead. +* [`bool2num`](#bool2num): Converts a boolean to a number. +* [`bool2str`](#bool2str): Converts a boolean to a string using optionally supplied arguments. +* [`clamp`](#clamp): Keeps value within the range [Min, X, Max] by sort based on integer value +(parameter order doesn't matter). +* [`concat`](#concat): Appends the contents of multiple arrays into array 1. +* [`convert_base`](#convert_base): Converts a given integer or base 10 string representing an integer to a +specified base, as a string. +* [`count`](#count): Counts the number of elements in array. +* [`deep_merge`](#deep_merge): Recursively merges two or more hashes together and returns the resulting hash. +* [`defined_with_params`](#defined_with_params): Takes a resource reference and an optional hash of attributes. +* [`delete`](#delete): Deletes all instances of a given element from an array, substring from a +string, or key from a hash. +* [`delete_at`](#delete_at): Deletes a determined indexed value from an array. +* [`delete_regex`](#delete_regex): Deletes all instances of a given element that match a regular expression +from an array or key from a hash. +* [`delete_undef_values`](#delete_undef_values): Returns a copy of input hash or array with all undefs deleted. +* [`delete_values`](#delete_values): Deletes all instances of a given value from a hash. +* [`deprecation`](#deprecation): Function to print deprecation warnings, Logs a warning once for a given key. +* [`difference`](#difference): This function returns the difference between two arrays. +* [`dirname`](#dirname): Returns the dirname of a path. +* [`dos2unix`](#dos2unix): Returns the Unix version of the given string. +* [`enclose_ipv6`](#enclose_ipv6): Takes an array of ip addresses and encloses the ipv6 addresses with square brackets. +* [`ensure_packages`](#ensure_packages): DEPRECATED. Use the namespaced function [`stdlib::ensure_packages`](#stdlibensure_packages) instead. +* [`ensure_resource`](#ensure_resource): Takes a resource type, title, and a list of attributes that describe a +resource. +* [`ensure_resources`](#ensure_resources): Takes a resource type, title (only hash), and a list of attributes that describe a +resource. +* [`fact`](#fact): Digs into the facts hash using dot-notation +* [`fqdn_rand_string`](#fqdn_rand_string): DEPRECATED. Use the namespaced function [`stdlib::fqdn_rand_string`](#stdlibfqdn_rand_string) instead. +* [`fqdn_rotate`](#fqdn_rotate): DEPRECATED. Use the namespaced function [`stdlib::fqdn_rotate`](#stdlibfqdn_rotate) instead. +* [`fqdn_uuid`](#fqdn_uuid): Returns a [RFC 4122](https://tools.ietf.org/html/rfc4122) valid version 5 UUID based +on an FQDN string under the DNS namespace +* [`get_module_path`](#get_module_path): Returns the absolute path of the specified module for the current +environment. +* [`getparam`](#getparam): Returns the value of a resource's parameter. +* [`glob`](#glob): Uses same patterns as Dir#glob. +* [`grep`](#grep): This function searches through an array and returns any elements that match +the provided regular expression. +* [`has_interface_with`](#has_interface_with): DEPRECATED. Use the namespaced function [`stdlib::has_interface_with`](#stdlibhas_interface_with) instead. +* [`has_ip_address`](#has_ip_address): DEPRECATED. Use the namespaced function [`stdlib::has_ip_address`](#stdlibhas_ip_address) instead. +* [`has_ip_network`](#has_ip_network): DEPRECATED. Use the namespaced function [`stdlib::has_ip_network`](#stdlibhas_ip_network) instead. +* [`intersection`](#intersection): This function returns an array of the intersection of two. +* [`is_a`](#is_a): Boolean check to determine whether a variable is of a given data type. +This is equivalent to the `=~` type checks. +* [`join_keys_to_values`](#join_keys_to_values): This function joins each key of a hash to that key's corresponding value with a +separator. +* [`load_module_metadata`](#load_module_metadata): This function loads the metadata of a given module. +* [`loadjson`](#loadjson): Load a JSON file containing an array, string, or hash, and return the data +in the corresponding native data type. +* [`loadyaml`](#loadyaml): Load a YAML file containing an array, string, or hash, and return the data +in the corresponding native data type. +* [`member`](#member): This function determines if a variable is a member of an array. +* [`merge`](#merge): DEPRECATED. Use the namespaced function [`stdlib::merge`](#stdlibmerge) instead. +* [`merge`](#merge): Merges two or more hashes together and returns the resulting hash. +* [`num2bool`](#num2bool): This function converts a number or a string representation of a number into a +true boolean. +* [`os_version_gte`](#os_version_gte): DEPRECATED. Use the namespaced function [`stdlib::os_version_gte`](#stdlibos_version_gte) instead. +* [`parsehocon`](#parsehocon): DEPRECATED. Use the namespaced function [`stdlib::parsehocon`](#stdlibparsehocon) instead. +* [`parsejson`](#parsejson): This function accepts JSON as a string and converts it into the correct +Puppet structure. +* [`parsepson`](#parsepson): **Deprecated:** Starting Puppet 8, we no longer natively support PSON usage. This function should be removed once we stop supporting Puppet 7. + +This function accepts PSON, a Puppet variant of JSON, as a string and converts +it into the correct Puppet structure +* [`parseyaml`](#parseyaml): This function accepts YAML as a string and converts it into the correct +Puppet structure. +* [`pick`](#pick): This function will return +the first value in a list of values that is not undefined or an empty string. +* [`pick_default`](#pick_default): This function will return the first value in a list of values that is not undefined or an empty string. +* [`powershell_escape`](#powershell_escape): DEPRECATED. Use the namespaced function [`stdlib::powershell_escape`](#stdlibpowershell_escape) instead. +* [`prefix`](#prefix): This function applies a prefix to all elements in an array or a hash. +* [`pry`](#pry): This function invokes a pry debugging session in the current scope object. +* [`pw_hash`](#pw_hash): Hashes a password using the crypt function. Provides a hash usable +on most POSIX systems. +* [`range`](#range): When given range in the form of (start, stop) it will extrapolate a range as +an array. +* [`regexpescape`](#regexpescape): Regexp escape a string or array of strings. +Requires either a single string or an array as an input. +* [`reject`](#reject): This function searches through an array and rejects all elements that match +the provided regular expression. +* [`reverse`](#reverse): Reverses the order of a string or array. +* [`seeded_rand`](#seeded_rand): DEPRECATED. Use the namespaced function [`stdlib::seeded_rand`](#stdlibseeded_rand) instead. +* [`seeded_rand_string`](#seeded_rand_string): DEPRECATED. Use the namespaced function [`stdlib::seeded_rand_string`](#stdlibseeded_rand_string) instead. +* [`shell_escape`](#shell_escape): DEPRECATED. Use the namespaced function [`stdlib::shell_escape`](#stdlibshell_escape) instead. +* [`shell_join`](#shell_join): Builds a command line string from the given array of strings. Each array item is escaped for Bourne shell. All items are then joined together +* [`shell_split`](#shell_split): Splits a string into an array of tokens in the same way the Bourne shell does. +* [`shuffle`](#shuffle): @summary Randomizes the order of a string or array elements. +* [`squeeze`](#squeeze): Returns a new string where runs of the same character that occur in this set are replaced by a single character. +* [`stdlib::batch_escape`](#stdlib--batch_escape): Escapes a string so that it can be safely used in a batch shell command line. +* [`stdlib::crc32`](#stdlib--crc32): Run a CRC32 calculation against a given value. +* [`stdlib::deferrable_epp`](#stdlib--deferrable_epp): This function returns either a rendered template or a deferred function to render at runtime. If any of the values in the variables hash are +* [`stdlib::end_with`](#stdlib--end_with): Returns true if str ends with one of the prefixes given. Each of the prefixes should be a String. +* [`stdlib::ensure`](#stdlib--ensure): function to cast ensure parameter to resource specific value +* [`stdlib::ensure_packages`](#stdlib--ensure_packages): Takes a list of packages and only installs them if they don't already exist. +* [`stdlib::extname`](#stdlib--extname): Returns the Extension (the Portion of Filename in Path starting from the +last Period). +* [`stdlib::fqdn_rand_string`](#stdlib--fqdn_rand_string): Generates a random alphanumeric string. Combining the `$fqdn` fact and an +optional seed for repeatable randomness. +* [`stdlib::fqdn_rotate`](#stdlib--fqdn_rotate): Rotates an array or string a random number of times, combining the `fqdn` fact and an optional seed for repeatable randomness. +* [`stdlib::has_function`](#stdlib--has_function): Returns whether the Puppet runtime has access to a given function. +* [`stdlib::has_interface_with`](#stdlib--has_interface_with): Returns boolean based on network interfaces present and their attribute values. +* [`stdlib::has_ip_address`](#stdlib--has_ip_address): Returns true if the client has the requested IPv4 address on some interface. +* [`stdlib::has_ip_network`](#stdlib--has_ip_network): Returns true if the client has the requested IPv4 network on some interface. +* [`stdlib::ip_in_range`](#stdlib--ip_in_range): Returns true if the ipaddress is within the given CIDRs +* [`stdlib::merge`](#stdlib--merge): Merges two or more hashes together or hashes resulting from iteration, and returns +the resulting hash. +* [`stdlib::nested_values`](#stdlib--nested_values): Get list of nested values from given hash +This function will return list of nested Hash values and returns list of values in form of Array +* [`stdlib::os_version_gte`](#stdlib--os_version_gte): Checks if the OS version is at least a certain version. +* [`stdlib::parsehocon`](#stdlib--parsehocon): This function accepts HOCON as a string and converts it into the correct +Puppet structure +* [`stdlib::powershell_escape`](#stdlib--powershell_escape): Escapes a string so that it can be safely used in a PowerShell command line. +* [`stdlib::seeded_rand`](#stdlib--seeded_rand): Generates a random whole number greater than or equal to 0 and less than max, using the value of seed for repeatable randomness. +* [`stdlib::seeded_rand_string`](#stdlib--seeded_rand_string): Generates a consistent random string of specific length based on provided seed. +* [`stdlib::sha256`](#stdlib--sha256): Run a SHA256 calculation against a given value. +* [`stdlib::shell_escape`](#stdlib--shell_escape): Escapes a string so that it can be safely used in a Bourne shell command line. +* [`stdlib::sort_by`](#stdlib--sort_by): Sort an Array, Hash or String by mapping values through a given block. +* [`stdlib::start_with`](#stdlib--start_with): Returns true if str starts with one of the prefixes given. Each of the prefixes should be a String. +* [`stdlib::str2resource`](#stdlib--str2resource): This converts a string to a puppet resource. +* [`stdlib::time`](#stdlib--time): This function is deprecated. It implements the functionality of the original non-namespaced stdlib `time` function. +* [`stdlib::to_json`](#stdlib--to_json): Convert a data structure and output to JSON +* [`stdlib::to_json_pretty`](#stdlib--to_json_pretty): Convert data structure and output to pretty JSON +* [`stdlib::to_python`](#stdlib--to_python): Convert an object into a String containing its Python representation +* [`stdlib::to_ruby`](#stdlib--to_ruby): Convert an object into a String containing its Ruby representation +* [`stdlib::to_toml`](#stdlib--to_toml): Convert a data structure and output to TOML. +* [`stdlib::to_yaml`](#stdlib--to_yaml): Convert a data structure and output it as YAML +* [`stdlib::type_of`](#stdlib--type_of): Returns the type of the passed value. +* [`stdlib::validate_domain_name`](#stdlib--validate_domain_name): Validate that all values passed are syntactically correct domain names. +Fail compilation if any value fails this check. +* [`stdlib::validate_email_address`](#stdlib--validate_email_address): Validate that all values passed are valid email addresses. +Fail compilation if any value fails this check. +* [`stdlib::xml_encode`](#stdlib--xml_encode): Encode strings for XML files +* [`str2bool`](#str2bool): This converts a string to a boolean. +* [`str2saltedpbkdf2`](#str2saltedpbkdf2): Convert a string into a salted SHA512 PBKDF2 password hash like requred for OS X / macOS 10.8+ +* [`str2saltedsha512`](#str2saltedsha512): This converts a string to a salted-SHA512 password hash (which is used for +OS X versions >= 10.7). +* [`suffix`](#suffix): This function applies a suffix to all elements in an array, or to the keys +in a hash. +* [`swapcase`](#swapcase): This function will swap the existing case of a string. +* [`time`](#time): DEPRECATED. Use the native Puppet fuctionality instead of this function. eg `Integer(Timestamp().strftime('%s'))` +* [`to_bytes`](#to_bytes): Converts the argument into bytes, for example 4 kB becomes 4096. +* [`to_json`](#to_json): DEPRECATED. Use the namespaced function [`stdlib::to_json`](#stdlibto_json) instead. +* [`to_json_pretty`](#to_json_pretty): DEPRECATED. Use the namespaced function [`stdlib::to_json_pretty`](#stdlibto_json_pretty) instead. +* [`to_python`](#to_python): DEPRECATED. Use the namespaced function [`stdlib::to_python`](#stdlibto_python) instead. +* [`to_ruby`](#to_ruby): DEPRECATED. Use the namespaced function [`stdlib::to_ruby`](#stdlibto_ruby) instead. +* [`to_toml`](#to_toml): DEPRECATED. Use the namespaced function [`stdlib::to_toml`](#stdlibto_toml) instead. +* [`to_yaml`](#to_yaml): DEPRECATED. Use the namespaced function [`stdlib::to_yaml`](#stdlibto_yaml) instead. +* [`type_of`](#type_of): DEPRECATED. Use the namespaced function [`stdlib::type_of`](#stdlibtype_of) instead. +* [`union`](#union): This function returns a union of two or more arrays. +* [`unix2dos`](#unix2dos): Returns the DOS version of the given string. +* [`uriescape`](#uriescape): Urlencodes a string or array of strings. +Requires either a single string or an array as an input. +* [`validate_augeas`](#validate_augeas): Perform validation of a string using an Augeas lens +* [`validate_cmd`](#validate_cmd): Perform validation of a string with an external command. +* [`validate_domain_name`](#validate_domain_name): DEPRECATED. Use the namespaced function [`stdlib::validate_domain_name`](#stdlibvalidate_domain_name) instead. +* [`validate_email_address`](#validate_email_address): DEPRECATED. Use the namespaced function [`stdlib::validate_email_address`](#stdlibvalidate_email_address) instead. +* [`validate_legacy`](#validate_legacy): **Deprecated:** Validate a value against both the target_type (new). +* [`validate_x509_rsa_key_pair`](#validate_x509_rsa_key_pair): Validates a PEM-formatted X.509 certificate and RSA private key using +OpenSSL. +* [`values_at`](#values_at): Finds value inside an array based on location. +* [`zip`](#zip): Takes one element from first array and merges corresponding elements from second array. + +### Data types + +* [`Stdlib::Absolutepath`](#Stdlib--Absolutepath): A strict absolutepath type +* [`Stdlib::Base32`](#Stdlib--Base32): Type to match base32 String +* [`Stdlib::Base64`](#Stdlib--Base64): Type to match base64 String +* [`Stdlib::CreateResources`](#Stdlib--CreateResources): A type description used for the create_resources function +* [`Stdlib::Datasize`](#Stdlib--Datasize): Validate the size of data +* [`Stdlib::Dns::Zone`](#Stdlib--Dns--Zone): Validate a DNS zone name +* [`Stdlib::Email`](#Stdlib--Email): Validate an e-mail address +* [`Stdlib::Ensure::File`](#Stdlib--Ensure--File): Validate the value of the ensure parameter for a file +* [`Stdlib::Ensure::File::Directory`](#Stdlib--Ensure--File--Directory): Validate the ensure parameter of a "directory" file resource +* [`Stdlib::Ensure::File::File`](#Stdlib--Ensure--File--File): Validate the ensure parameter of a "file" file resource +* [`Stdlib::Ensure::File::Link`](#Stdlib--Ensure--File--Link): Validate the ensure parameter of a "link" file resource +* [`Stdlib::Ensure::Package`](#Stdlib--Ensure--Package): Validate the value of the ensure parameter for a package +* [`Stdlib::Ensure::Service`](#Stdlib--Ensure--Service): Validate the value of the ensure parameter of a service resource +* [`Stdlib::Filemode`](#Stdlib--Filemode): Validate a file mode +* [`Stdlib::Filesource`](#Stdlib--Filesource): Validate the source parameter on file types +* [`Stdlib::Fqdn`](#Stdlib--Fqdn): Validate a Fully Qualified Domain Name +* [`Stdlib::HTTPSUrl`](#Stdlib--HTTPSUrl): Validate a HTTPS URL +* [`Stdlib::HTTPUrl`](#Stdlib--HTTPUrl): Validate a HTTP(S) URL +* [`Stdlib::Host`](#Stdlib--Host): Validate a host (FQDN or IP address) +* [`Stdlib::Http::Method`](#Stdlib--Http--Method): Valid HTTP method verbs +* [`Stdlib::Http::Status`](#Stdlib--Http--Status): A valid HTTP status code per RFC9110 +* [`Stdlib::HttpStatus`](#Stdlib--HttpStatus): Validate a HTTP status code +* [`Stdlib::IP::Address`](#Stdlib--IP--Address): Validate an IP address +* [`Stdlib::IP::Address::CIDR`](#Stdlib--IP--Address--CIDR): Validate an IP address with subnet +* [`Stdlib::IP::Address::Nosubnet`](#Stdlib--IP--Address--Nosubnet): Validate an IP address without subnet +* [`Stdlib::IP::Address::V4`](#Stdlib--IP--Address--V4): Validate an IPv4 address +* [`Stdlib::IP::Address::V4::CIDR`](#Stdlib--IP--Address--V4--CIDR): lint:ignore:140chars +* [`Stdlib::IP::Address::V4::Nosubnet`](#Stdlib--IP--Address--V4--Nosubnet): lint:ignore:140chars +* [`Stdlib::IP::Address::V6`](#Stdlib--IP--Address--V6): Validate an IPv6 address +* [`Stdlib::IP::Address::V6::Alternative`](#Stdlib--IP--Address--V6--Alternative): lint:ignore:140chars +* [`Stdlib::IP::Address::V6::CIDR`](#Stdlib--IP--Address--V6--CIDR): lint:ignore:140chars +* [`Stdlib::IP::Address::V6::Compressed`](#Stdlib--IP--Address--V6--Compressed): Validate a compressed IPv6 address +* [`Stdlib::IP::Address::V6::Full`](#Stdlib--IP--Address--V6--Full): Validate a full IPv6 address +* [`Stdlib::IP::Address::V6::Nosubnet`](#Stdlib--IP--Address--V6--Nosubnet): Validate an IPv6 address without subnet +* [`Stdlib::IP::Address::V6::Nosubnet::Alternative`](#Stdlib--IP--Address--V6--Nosubnet--Alternative): lint:ignore:140chars +* [`Stdlib::IP::Address::V6::Nosubnet::Compressed`](#Stdlib--IP--Address--V6--Nosubnet--Compressed): Validate compressed IPv6 address without subnet +* [`Stdlib::IP::Address::V6::Nosubnet::Full`](#Stdlib--IP--Address--V6--Nosubnet--Full): Validate full IPv6 address without subnet +* [`Stdlib::MAC`](#Stdlib--MAC): A type for a MAC address +* [`Stdlib::ObjectStore`](#Stdlib--ObjectStore): Validate an ObjectStore +* [`Stdlib::ObjectStore::GSUri`](#Stdlib--ObjectStore--GSUri): Validate a Google Cloud object store URI +* [`Stdlib::ObjectStore::S3Uri`](#Stdlib--ObjectStore--S3Uri): Validate an Amazon Web Services S3 object store URI +* [`Stdlib::Port`](#Stdlib--Port): Validate a port number +* [`Stdlib::Port::Dynamic`](#Stdlib--Port--Dynamic): Validate a dynamic port number +* [`Stdlib::Port::Ephemeral`](#Stdlib--Port--Ephemeral): Validate an ephemeral port number +* [`Stdlib::Port::Privileged`](#Stdlib--Port--Privileged): Validate a priviliged port number +* [`Stdlib::Port::Registered`](#Stdlib--Port--Registered): Validate a registered port number +* [`Stdlib::Port::Unprivileged`](#Stdlib--Port--Unprivileged): Validate an unprivileged port number +* [`Stdlib::Port::User`](#Stdlib--Port--User): Validate a port number usable by a user +* [`Stdlib::Syslogfacility`](#Stdlib--Syslogfacility): Validate a syslog facility +* [`Stdlib::Unixpath`](#Stdlib--Unixpath): Validate a UNIX path +* [`Stdlib::Windowspath`](#Stdlib--Windowspath): Validate a Windows path +* [`Stdlib::Yes_no`](#Stdlib--Yes_no): Validate a yes / no value + +## Classes + +### `stdlib` + +Most of stdlib's features are automatically loaded by Puppet, but this class should be +declared in order to use the standardized run stages. + +Declares all other classes in the stdlib module. Currently, this consists +of stdlib::stages and stdlib::manage. + +### `stdlib::manage` + +Sometimes your systems require a single simple resource. +It can feel unnecessary to create a module for a single +resource. There are a number of possible patterns to +generate trivial resource definitions. This is an attempt +to create a single clear method for uncomplicated resources. +There is __limited__ support for `before`, `require`, `notify`, +and `subscribe`. + +#### Examples + +##### + +```puppet +class { 'stdlib::manage': + 'create_resources' => { + 'file' => { + '/etc/motd.d/hello' => { + 'content' => 'I say Hi', + 'notify' => 'Service[sshd]', + }, + '/etc/motd' => { + 'ensure' => 'file', + 'epp' => { + 'template' => 'profile/motd.epp', + } + }, + '/etc/information' => { + 'ensure' => 'file', + 'erb' => { + 'template' => 'profile/informaiton.erb', + } + } + }, + 'package' => { + 'example' => { + 'ensure' => 'installed', + 'subscribe' => ['Service[sshd]', 'Exec[something]'], + } + } + } +} +``` + +##### + +```puppet +stdlib::manage::create_resources: + file: + '/etc/motd.d/hello': + content: I say Hi + notify: 'Service[sshd]' + '/etc/motd': + ensure: 'file' + epp: + template: 'profile/motd.epp' + context: {} + '/etc/information': + ensure: 'file' + erb: + template: 'profile/information.erb' + package: + example: + ensure: installed + subscribe: + - 'Service[sshd]' + - 'Exec[something]' +``` + +#### Parameters + +The following parameters are available in the `stdlib::manage` class: + +* [`create_resources`](#-stdlib--manage--create_resources) + +##### `create_resources` + +Data type: `Hash[String, Hash]` + +A hash of resources to create +NOTE: functions, such as `template` or `epp`, are not directly evaluated + but processed as Puppet code based on epp and erb hash keys. + +Default value: `{}` + +### `stdlib::stages` + +Declares various run-stages for deploying infrastructure, +language runtimes, and application layers. + +The high level stages are (in order): + * setup + * main + * runtime + * setup_infra + * deploy_infra + * setup_app + * deploy_app + * deploy + +#### Examples + +##### + +```puppet +node default { + include ::stdlib + class { java: stage => 'runtime' } +} +``` + +## Resource types + +### `anchor` + +> Note: this has been replaced by core puppet `contain()` method. Please see https://puppet.com/docs/puppet/latest/lang_containment.html for more information. + +In Puppet 2.6, when a class declares another class, the resources in the +interior class are not contained by the exterior class. This interacts badly +with the pattern of composing complex modules from smaller classes, as it +makes it impossible for end users to specify order relationships between the +exterior class and other modules. + +The anchor type lets you work around this. By sandwiching any interior +classes between two no-op resources that _are_ contained by the exterior +class, you can ensure that all resources in the module are contained. + +``` +class ntp { + # These classes will have the correct order relationship with each + # other. However, without anchors, they won't have any order + # relationship to Class['ntp']. + class { 'ntp::package': } + -> class { 'ntp::config': } + -> class { 'ntp::service': } + + # These two resources "anchor" the composed classes within the ntp + # class. + anchor { 'ntp::begin': } -> Class['ntp::package'] + Class['ntp::service'] -> anchor { 'ntp::end': } +} +``` + +This allows the end user of the ntp module to establish require and before +relationships with Class['ntp']: + +``` +class { 'ntp': } -> class { 'mcollective': } +class { 'mcollective': } -> class { 'ntp': } +``` + +#### Parameters + +The following parameters are available in the `anchor` type. + +* [`name`](#-anchor--name) + +##### `name` + +namevar + +The name of the anchor resource. + +### `file_line` + +The implementation matches the full line, including whitespace at the +beginning and end. If the line is not contained in the given file, Puppet +will append the line to the end of the file to ensure the desired state. +Multiple resources may be declared to manage multiple lines in the same file. + +* Ensure Example +``` +file_line { 'sudo_rule': + path => '/etc/sudoers', + line => '%sudo ALL=(ALL) ALL', +} + +file_line { 'sudo_rule_nopw': + path => '/etc/sudoers', + line => '%sudonopw ALL=(ALL) NOPASSWD: ALL', +} +``` +In this example, Puppet will ensure both of the specified lines are +contained in the file /etc/sudoers. + +* Match Example + +``` +file_line { 'bashrc_proxy': + ensure => present, + path => '/etc/bashrc', + line => 'export HTTP_PROXY=http://squid.puppetlabs.vm:3128', + match => '^export HTTP_PROXY=', +} +``` + +In this code example match will look for a line beginning with export +followed by HTTP_PROXY and replace it with the value in line. + +* Examples With `ensure => absent`: + +This type has two behaviors when `ensure => absent` is set. + +One possibility is to set `match => ...` and `match_for_absence => true`, +as in the following example: + +``` +file_line { 'bashrc_proxy': + ensure => absent, + path => '/etc/bashrc', + match => '^export HTTP_PROXY=', + match_for_absence => true, +} +``` + +In this code example match will look for a line beginning with export +followed by HTTP_PROXY and delete it. If multiple lines match, an +error will be raised unless the `multiple => true` parameter is set. + +Note that the `line => ...` parameter would be accepted BUT IGNORED in +the above example. + +The second way of using `ensure => absent` is to specify a `line => ...`, +and no match: + +``` +file_line { 'bashrc_proxy': + ensure => absent, + path => '/etc/bashrc', + line => 'export HTTP_PROXY=http://squid.puppetlabs.vm:3128', +} +``` + +> *Note:* +When ensuring lines are absent this way, the default behavior +this time is to always remove all lines matching, and this behavior +can't be disabled. + +* Encoding example: + +``` +file_line { "XScreenSaver": + ensure => present, + path => '/root/XScreenSaver', + line => "*lock: 10:00:00", + match => '^*lock:', + encoding => "iso-8859-1", +} +``` + +Files with special characters that are not valid UTF-8 will give the +error message "invalid byte sequence in UTF-8". In this case, determine +the correct file encoding and specify the correct encoding using the +encoding attribute, the value of which needs to be a valid Ruby character +encoding. + +**Autorequires:** If Puppet is managing the file that will contain the line +being managed, the file_line resource will autorequire that file. + +#### Properties + +The following properties are available in the `file_line` type. + +##### `ensure` + +Valid values: `present`, `absent` + +Manage the state of this type. + +Default value: `present` + +##### `line` + +The line to be appended to the file or used to replace matches found by the match attribute. + +#### Parameters + +The following parameters are available in the `file_line` type. + +* [`after`](#-file_line--after) +* [`append_on_no_match`](#-file_line--append_on_no_match) +* [`encoding`](#-file_line--encoding) +* [`match`](#-file_line--match) +* [`match_for_absence`](#-file_line--match_for_absence) +* [`multiple`](#-file_line--multiple) +* [`name`](#-file_line--name) +* [`path`](#-file_line--path) +* [`provider`](#-file_line--provider) +* [`replace`](#-file_line--replace) +* [`replace_all_matches_not_matching_line`](#-file_line--replace_all_matches_not_matching_line) + +##### `after` + +An optional value used to specify the line after which we will add any new lines. (Existing lines are added in place) +This is also takes a regex. + +##### `append_on_no_match` + +Valid values: `true`, `false` + +If true, append line if match is not found. If false, do not append line if a match is not found + +Default value: `true` + +##### `encoding` + +For files that are not UTF-8 encoded, specify encoding such as iso-8859-1 + +Default value: `UTF-8` + +##### `match` + +An optional ruby regular expression to run against existing lines in the file. +If a match is found, we replace that line rather than adding a new line. +A regex comparison is performed against the line value and if it does not +match an exception will be raised. + +##### `match_for_absence` + +Valid values: `true`, `false` + +An optional value to determine if match should be applied when ensure => absent. +If set to true and match is set, the line that matches match will be deleted. +If set to false (the default), match is ignored when ensure => absent. +When `ensure => present`, match_for_absence is ignored. + +Default value: `false` + +##### `multiple` + +Valid values: `true`, `false` + +An optional value to determine if match can change multiple lines. +If set to false, an exception will be raised if more than one line matches + +##### `name` + +namevar + +An arbitrary name used as the identity of the resource. + +##### `path` + +The file Puppet will ensure contains the line specified by the line parameter. + +##### `provider` + +The specific backend to use for this `file_line` resource. You will seldom need to specify this --- Puppet will usually +discover the appropriate provider for your platform. + +##### `replace` + +Valid values: `true`, `false` + +If true, replace line that matches. If false, do not write line if a match is found + +Default value: `true` + +##### `replace_all_matches_not_matching_line` + +Valid values: `true`, `false` + +Configures the behavior of replacing all lines in a file which match the `match` parameter regular expression, +regardless of whether the specified line is already present in the file. + +Default value: `false` + +## Functions + +### `any2array` + +Type: Ruby 3.x API + +Empty argument lists are converted to an empty array. Arrays are left +untouched. Hashes are converted to arrays of alternating keys and values. + +> *Note:* + since Puppet 5.0.0 it is possible to create new data types for almost any + datatype using the type system and the built-in + [`Array.new`](https://puppet.com/docs/puppet/latest/function.html#conversion-to-array-and-tuple) + function is used to create a new Array.. + + ``` + $hsh = {'key' => 42, 'another-key' => 100} + notice(Array($hsh)) + ``` + +Would notice `[['key', 42], ['another-key', 100]]` + +The Array data type also has a special mode to "create an array if not already an array" + + ``` + notice(Array({'key' => 42, 'another-key' => 100}, true)) + ``` + +Would notice `[{'key' => 42, 'another-key' => 100}]`, as the `true` flag prevents the hash from being +transformed into an array. + +#### `any2array()` + +Empty argument lists are converted to an empty array. Arrays are left +untouched. Hashes are converted to arrays of alternating keys and values. + +> *Note:* + since Puppet 5.0.0 it is possible to create new data types for almost any + datatype using the type system and the built-in + [`Array.new`](https://puppet.com/docs/puppet/latest/function.html#conversion-to-array-and-tuple) + function is used to create a new Array.. + + ``` + $hsh = {'key' => 42, 'another-key' => 100} + notice(Array($hsh)) + ``` + +Would notice `[['key', 42], ['another-key', 100]]` + +The Array data type also has a special mode to "create an array if not already an array" + + ``` + notice(Array({'key' => 42, 'another-key' => 100}, true)) + ``` + +Would notice `[{'key' => 42, 'another-key' => 100}]`, as the `true` flag prevents the hash from being +transformed into an array. + +Returns: `Array` The new array containing the given object + +### `any2bool` + +Type: Ruby 3.x API + +In practise it does the following: +* Strings such as Y,y,1,T,t,TRUE,yes,'true' will return true +* Strings such as 0,F,f,N,n,FALSE,no,'false' will return false +* Booleans will just return their original value +* Number (or a string representation of a number) > 0 will return true, otherwise false +* undef will return false +* Anything else will return true + +Also see the built-in [`Boolean.new`](https://puppet.com/docs/puppet/latest/function.html#conversion-to-boolean) +function. + +#### `any2bool()` + +In practise it does the following: +* Strings such as Y,y,1,T,t,TRUE,yes,'true' will return true +* Strings such as 0,F,f,N,n,FALSE,no,'false' will return false +* Booleans will just return their original value +* Number (or a string representation of a number) > 0 will return true, otherwise false +* undef will return false +* Anything else will return true + +Also see the built-in [`Boolean.new`](https://puppet.com/docs/puppet/latest/function.html#conversion-to-boolean) +function. + +Returns: `Boolean` The boolean value of the object that was given + +### `assert_private` + +Type: Ruby 3.x API + +Calling the class or definition from outside the current module will fail. + +#### `assert_private()` + +Calling the class or definition from outside the current module will fail. + +Returns: `Any` set the current class or definition as private. + +### `base64` + +Type: Ruby 3.x API + +> **Note:* + Since Puppet 4.8.0, the Binary data type can be used to produce base 64 encoded strings. + See the `new()` function for the Binary and String types for documentation. Also see `binary_file()` + function for reading a file with binary (non UTF-8) content. + +#### Examples + +##### Example usage + +```puppet + +Encode and decode a string + + $encodestring = base64('encode', 'thestring') + $decodestring = base64('decode', 'dGhlc3RyaW5n') + +Explicitly define encode/decode method: default, strict, urlsafe + + $method = 'default' + $encodestring = base64('encode', 'thestring', $method) + $decodestring = base64('decode', 'dGhlc3RyaW5n', $method) + +Encode a string as if it was binary + + $encodestring = String(Binary('thestring', '%s')) + +Decode a Binary assuming it is an UTF-8 String + + $decodestring = String(Binary("dGhlc3RyaW5n"), "%s") +``` + +#### `base64()` + +> **Note:* + Since Puppet 4.8.0, the Binary data type can be used to produce base 64 encoded strings. + See the `new()` function for the Binary and String types for documentation. Also see `binary_file()` + function for reading a file with binary (non UTF-8) content. + +Returns: `String` The encoded/decoded + +##### Examples + +###### Example usage + +```puppet + +Encode and decode a string + + $encodestring = base64('encode', 'thestring') + $decodestring = base64('decode', 'dGhlc3RyaW5n') + +Explicitly define encode/decode method: default, strict, urlsafe + + $method = 'default' + $encodestring = base64('encode', 'thestring', $method) + $decodestring = base64('decode', 'dGhlc3RyaW5n', $method) + +Encode a string as if it was binary + + $encodestring = String(Binary('thestring', '%s')) + +Decode a Binary assuming it is an UTF-8 String + + $decodestring = String(Binary("dGhlc3RyaW5n"), "%s") +``` + +### `basename` + +Type: Ruby 3.x API + +Strips directory (and optional suffix) from a filename + +#### `basename()` + +The basename function. + +Returns: `String` The stripped filename + +### `batch_escape` + +Type: Ruby 4.x API + +DEPRECATED. Use the namespaced function [`stdlib::batch_escape`](#stdlibbatch_escape) instead. + +#### `batch_escape(Any *$args)` + +The batch_escape function. + +Returns: `Any` + +##### `*args` + +Data type: `Any` + + + +### `bool2num` + +Type: Ruby 3.x API + +Converts the values: + ``` + false, f, 0, n, and no to 0 + true, t, 1, y, and yes to 1 + ``` +Requires a single boolean or string as an input. + +> *Note:* + since Puppet 5.0.0 it is possible to create new data types for almost any + datatype using the type system and the built-in + [`Numeric.new`](https://puppet.com/docs/puppet/latest/function.html#conversion-to-numeric), + [`Integer.new`](https://puppet.com/docs/puppet/latest/function.html#conversion-to-integer), and + [`Float.new`](https://puppet.com/docs/puppet/latest/function.html#conversion-to-float) + function are used to convert to numeric values. + ``` + notice(Integer(false)) # Notices 0 + notice(Float(true)) # Notices 1.0 + ``` + +#### `bool2num()` + +Converts the values: + ``` + false, f, 0, n, and no to 0 + true, t, 1, y, and yes to 1 + ``` +Requires a single boolean or string as an input. + +> *Note:* + since Puppet 5.0.0 it is possible to create new data types for almost any + datatype using the type system and the built-in + [`Numeric.new`](https://puppet.com/docs/puppet/latest/function.html#conversion-to-numeric), + [`Integer.new`](https://puppet.com/docs/puppet/latest/function.html#conversion-to-integer), and + [`Float.new`](https://puppet.com/docs/puppet/latest/function.html#conversion-to-float) + function are used to convert to numeric values. + ``` + notice(Integer(false)) # Notices 0 + notice(Float(true)) # Notices 1.0 + ``` + +Returns: `Integer` The converted value as a number + +### `bool2str` + +Type: Ruby 3.x API + +The optional second and third arguments represent what true and false will be +converted to respectively. If only one argument is given, it will be +converted from a boolean to a string containing 'true' or 'false'. + +**Examples of usage** + + ``` + bool2str(true) => 'true' + bool2str(true, 'yes', 'no') => 'yes' + bool2str(false, 't', 'f') => 'f' + ``` + +Requires a single boolean as an input. + +> *Note:* + since Puppet 5.0.0 it is possible to create new data types for almost any + datatype using the type system and the built-in + [`String.new`](https://puppet.com/docs/puppet/latest/function.html#boolean-to-string) + function is used to convert to String with many different format options. + + ``` + notice(String(false)) # Notices 'false' + notice(String(true)) # Notices 'true' + notice(String(false, '%y')) # Notices 'yes' + notice(String(true, '%y')) # Notices 'no' + ``` + +#### `bool2str()` + +The optional second and third arguments represent what true and false will be +converted to respectively. If only one argument is given, it will be +converted from a boolean to a string containing 'true' or 'false'. + +**Examples of usage** + + ``` + bool2str(true) => 'true' + bool2str(true, 'yes', 'no') => 'yes' + bool2str(false, 't', 'f') => 'f' + ``` + +Requires a single boolean as an input. + +> *Note:* + since Puppet 5.0.0 it is possible to create new data types for almost any + datatype using the type system and the built-in + [`String.new`](https://puppet.com/docs/puppet/latest/function.html#boolean-to-string) + function is used to convert to String with many different format options. + + ``` + notice(String(false)) # Notices 'false' + notice(String(true)) # Notices 'true' + notice(String(false, '%y')) # Notices 'yes' + notice(String(true, '%y')) # Notices 'no' + ``` + +Returns: `Any` The converted value to string of the given Boolean + +### `clamp` + +Type: Ruby 3.x API + +Strings are converted and compared numerically. Arrays of values are flattened +into a list for further handling. + +> *Note:* + From Puppet 6.0.0 this can be done with only core Puppet like this: + `[$minval, $maxval, $value_to_clamp].sort[1]` + +#### Examples + +##### Example usage + +```puppet + +clamp('24', [575, 187])` returns 187. +clamp(16, 88, 661)` returns 88. +clamp([4, 3, '99'])` returns 4. +``` + +#### `clamp()` + +Strings are converted and compared numerically. Arrays of values are flattened +into a list for further handling. + +> *Note:* + From Puppet 6.0.0 this can be done with only core Puppet like this: + `[$minval, $maxval, $value_to_clamp].sort[1]` + +Returns: `Array[Integer]` The sorted Array + +##### Examples + +###### Example usage + +```puppet + +clamp('24', [575, 187])` returns 187. +clamp(16, 88, 661)` returns 88. +clamp([4, 3, '99'])` returns 4. +``` + +### `concat` + +Type: Ruby 3.x API + +> *Note:* + Since Puppet 4.0, you can use the `+`` operator for concatenation of arrays and + merge of hashes, and the `<<`` operator for appending: + +`['1','2','3'] + ['4','5','6'] + ['7','8','9']` returns `['1','2','3','4','5','6','7','8','9']` +`[1, 2, 3] << 4` returns `[1, 2, 3, 4]` +`[1, 2, 3] << [4, 5]` returns `[1, 2, 3, [4, 5]]` + +#### Examples + +##### Example usage + +```puppet + +concat(['1','2','3'],'4') returns ['1','2','3','4'] +concat(['1','2','3'],'4',['5','6','7']) returns ['1','2','3','4','5','6','7'] +``` + +#### `concat()` + +> *Note:* + Since Puppet 4.0, you can use the `+`` operator for concatenation of arrays and + merge of hashes, and the `<<`` operator for appending: + +`['1','2','3'] + ['4','5','6'] + ['7','8','9']` returns `['1','2','3','4','5','6','7','8','9']` +`[1, 2, 3] << 4` returns `[1, 2, 3, 4]` +`[1, 2, 3] << [4, 5]` returns `[1, 2, 3, [4, 5]]` + +Returns: `Array` The single concatenated array + +##### Examples + +###### Example usage + +```puppet + +concat(['1','2','3'],'4') returns ['1','2','3','4'] +concat(['1','2','3'],'4',['5','6','7']) returns ['1','2','3','4','5','6','7'] +``` + +### `convert_base` + +Type: Ruby 3.x API + +convert_base(5, 2)` results in: `'101'` +convert_base('254', '16')` results in: `'fe'` + +> *Note:* + Since Puppet 4.5.0 this can be done with the built-in + [`String.new`](https://puppet.com/docs/puppet/latest/function.html#integer-to-string) + function and its many formatting options: + + `$binary_repr = String(5, '%b')` return `"101"` + `$hex_repr = String(254, "%x")` return `"fe"` + `$hex_repr = String(254, "%#x")` return `"0xfe"` + + @return [String] The converted value as a S + +#### Examples + +##### Example usage + +```puppet + +``` + +#### `convert_base()` + +convert_base(5, 2)` results in: `'101'` +convert_base('254', '16')` results in: `'fe'` + +> *Note:* + Since Puppet 4.5.0 this can be done with the built-in + [`String.new`](https://puppet.com/docs/puppet/latest/function.html#integer-to-string) + function and its many formatting options: + + `$binary_repr = String(5, '%b')` return `"101"` + `$hex_repr = String(254, "%x")` return `"fe"` + `$hex_repr = String(254, "%#x")` return `"0xfe"` + + @return [String] The converted value as a S + +Returns: `Any` converted value as a string + +##### Examples + +###### Example usage + +```puppet + +``` + +### `count` + +Type: Ruby 3.x API + +Takes an array as first argument and an optional second argument. Counts the number of elements in array that is equal to the second argument. +If called with only an array, it counts the number of elements that are not nil/undef/empty-string. + +> *Note:* + equality is tested with a Ruby method and it is therefore subject to what Ruby considers + to be equal. For strings this means that equality is case sensitive. + +In Puppet core, counting can be done in general by using a combination of the core functions +filter() (since Puppet 4.0.0) and length() (since Puppet 5.5.0, before that in stdlib). + +Example below shows counting values that are not undef. + + ```notice([42, "hello", undef].filter |$x| { $x =~ NotUndef }.length)``` + +Would notice the value 2. + +#### `count()` + +Takes an array as first argument and an optional second argument. Counts the number of elements in array that is equal to the second argument. +If called with only an array, it counts the number of elements that are not nil/undef/empty-string. + +> *Note:* + equality is tested with a Ruby method and it is therefore subject to what Ruby considers + to be equal. For strings this means that equality is case sensitive. + +In Puppet core, counting can be done in general by using a combination of the core functions +filter() (since Puppet 4.0.0) and length() (since Puppet 5.5.0, before that in stdlib). + +Example below shows counting values that are not undef. + + ```notice([42, "hello", undef].filter |$x| { $x =~ NotUndef }.length)``` + +Would notice the value 2. + +Returns: `Integer` The amount of elements counted within the array + +### `deep_merge` + +Type: Ruby 3.x API + +Recursively merges two or more hashes together and returns the resulting hash. + +#### Examples + +##### Example usage + +```puppet + +$hash1 = {'one' => 1, 'two' => 2, 'three' => { 'four' => 4 } } +$hash2 = {'two' => 'dos', 'three' => { 'five' => 5 } } +$merged_hash = deep_merge($hash1, $hash2) + +The resulting hash is equivalent to: + +$merged_hash = { 'one' => 1, 'two' => 'dos', 'three' => { 'four' => 4, 'five' => 5 } } + +When there is a duplicate key that is a hash, they are recursively merged. +When there is a duplicate key that is not a hash, the key in the rightmost hash will "win." +``` + +#### `deep_merge()` + +The deep_merge function. + +Returns: `Hash` The merged + +##### Examples + +###### Example usage + +```puppet + +$hash1 = {'one' => 1, 'two' => 2, 'three' => { 'four' => 4 } } +$hash2 = {'two' => 'dos', 'three' => { 'five' => 5 } } +$merged_hash = deep_merge($hash1, $hash2) + +The resulting hash is equivalent to: + +$merged_hash = { 'one' => 1, 'two' => 'dos', 'three' => { 'four' => 4, 'five' => 5 } } + +When there is a duplicate key that is a hash, they are recursively merged. +When there is a duplicate key that is not a hash, the key in the rightmost hash will "win." +``` + +### `defined_with_params` + +Type: Ruby 3.x API + +Returns `true` if a resource with the specified attributes has already been added +to the catalog, and `false` otherwise. + + ``` + user { 'dan': + ensure => present, + } + + if ! defined_with_params(User[dan], {'ensure' => 'present' }) { + user { 'dan': ensure => present, } + } + ``` + +#### `defined_with_params()` + +Returns `true` if a resource with the specified attributes has already been added +to the catalog, and `false` otherwise. + + ``` + user { 'dan': + ensure => present, + } + + if ! defined_with_params(User[dan], {'ensure' => 'present' }) { + user { 'dan': ensure => present, } + } + ``` + +Returns: `Boolean` returns `true` or `false` + +### `delete` + +Type: Ruby 3.x API + +> *Note:* +From Puppet 4.0.0 the minus (-) operator deletes values from arrays and keys from a hash +`{'a'=>1,'b'=>2,'c'=>3} - ['b','c'])` +> +A global delete from a string can be performed with the +[`regsubst`](https://puppet.com/docs/puppet/latest/function.html#regsubst) function: +`'abracadabra'.regsubst(/bra/, '', 'G')` + +In general, the built-in [`filter`](https://puppet.com/docs/puppet/latest/function.html#filter) +function can filter out entries from arrays and hashes based on keys and/or values. + +#### Examples + +##### Example usage + +```puppet + +delete(['a','b','c','b'], 'b') +Would return: ['a','c'] + +delete({'a'=>1,'b'=>2,'c'=>3}, 'b') +Would return: {'a'=>1,'c'=>3} + +delete({'a'=>1,'b'=>2,'c'=>3}, ['b','c']) +Would return: {'a'=>1} + +delete('abracadabra', 'bra') +Would return: 'acada' + +['a', 'b', 'c', 'b'] - 'b' +Would return: ['a', 'c'] + +{'a'=>1,'b'=>2,'c'=>3} - ['b','c']) +Would return: {'a' => '1'} + +'abracadabra'.regsubst(/bra/, '', 'G') +Would return: 'acada' +``` + +#### `delete()` + +> *Note:* +From Puppet 4.0.0 the minus (-) operator deletes values from arrays and keys from a hash +`{'a'=>1,'b'=>2,'c'=>3} - ['b','c'])` +> +A global delete from a string can be performed with the +[`regsubst`](https://puppet.com/docs/puppet/latest/function.html#regsubst) function: +`'abracadabra'.regsubst(/bra/, '', 'G')` + +In general, the built-in [`filter`](https://puppet.com/docs/puppet/latest/function.html#filter) +function can filter out entries from arrays and hashes based on keys and/or values. + +Returns: `String` The filtered String, if one was given. + +##### Examples + +###### Example usage + +```puppet + +delete(['a','b','c','b'], 'b') +Would return: ['a','c'] + +delete({'a'=>1,'b'=>2,'c'=>3}, 'b') +Would return: {'a'=>1,'c'=>3} + +delete({'a'=>1,'b'=>2,'c'=>3}, ['b','c']) +Would return: {'a'=>1} + +delete('abracadabra', 'bra') +Would return: 'acada' + +['a', 'b', 'c', 'b'] - 'b' +Would return: ['a', 'c'] + +{'a'=>1,'b'=>2,'c'=>3} - ['b','c']) +Would return: {'a' => '1'} + +'abracadabra'.regsubst(/bra/, '', 'G') +Would return: 'acada' +``` + +### `delete_at` + +Type: Ruby 3.x API + +For example + ```delete_at(['a','b','c'], 1)``` + +Would return: `['a','c']` + +> *Note:* + Since Puppet 4 this can be done in general with the built-in + [`filter`](https://puppet.com/docs/puppet/latest/function.html#filter) function: + + ```['a', 'b', 'c'].filter |$pos, $val | { $pos != 1 }``` + +Or if a delete is wanted from the beginning or end of the array, by using the slice operator [ ]: + ``` + $array[0, -1] # the same as all the values + $array[2, -1] # all but the first 2 elements + $array[0, -3] # all but the last 2 elements + $array[1, -2] # all but the first and last element + ``` + +#### `delete_at()` + +For example + ```delete_at(['a','b','c'], 1)``` + +Would return: `['a','c']` + +> *Note:* + Since Puppet 4 this can be done in general with the built-in + [`filter`](https://puppet.com/docs/puppet/latest/function.html#filter) function: + + ```['a', 'b', 'c'].filter |$pos, $val | { $pos != 1 }``` + +Or if a delete is wanted from the beginning or end of the array, by using the slice operator [ ]: + ``` + $array[0, -1] # the same as all the values + $array[2, -1] # all but the first 2 elements + $array[0, -3] # all but the last 2 elements + $array[1, -2] # all but the first and last element + ``` + +Returns: `Array` The given array, now missing the tar + +### `delete_regex` + +Type: Ruby 3.x API + +Multiple regular expressions are assumed to be matched as an OR. + +> *Note:* +Since Puppet 4 this can be done in general with the built-in +[`filter`](https://puppet.com/docs/puppet/latest/function.html#filter) function: +["aaa", "aba", "aca"].filter |$val| { $val !~ /b/ } +Would return: ['aaa', 'aca'] + +#### Examples + +##### Example usage + +```puppet + +delete_regex(['a','b','c','b'], 'b') +Would return: ['a','c'] + +delete_regex(['a','b','c','b'], ['b', 'c']) +Would return: ['a'] + +delete_regex({'a'=>1,'b'=>2,'c'=>3}, 'b') +Would return: {'a'=>1,'c'=>3} + +delete_regex({'a'=>1,'b'=>2,'c'=>3}, '^a$') +Would return: {'b'=>2,'c'=>3} +``` + +#### `delete_regex()` + +Multiple regular expressions are assumed to be matched as an OR. + +> *Note:* +Since Puppet 4 this can be done in general with the built-in +[`filter`](https://puppet.com/docs/puppet/latest/function.html#filter) function: +["aaa", "aba", "aca"].filter |$val| { $val !~ /b/ } +Would return: ['aaa', 'aca'] + +Returns: `Array` The given array now missing all targeted values. + +##### Examples + +###### Example usage + +```puppet + +delete_regex(['a','b','c','b'], 'b') +Would return: ['a','c'] + +delete_regex(['a','b','c','b'], ['b', 'c']) +Would return: ['a'] + +delete_regex({'a'=>1,'b'=>2,'c'=>3}, 'b') +Would return: {'a'=>1,'c'=>3} + +delete_regex({'a'=>1,'b'=>2,'c'=>3}, '^a$') +Would return: {'b'=>2,'c'=>3} +``` + +### `delete_undef_values` + +Type: Ruby 3.x API + +> *Note:* +Since Puppet 4.0.0 the equivalent can be performed with the built-in +[`filter`](https://puppet.com/docs/puppet/latest/function.html#filter) function: +$array.filter |$val| { $val =~ NotUndef } +$hash.filter |$key, $val| { $val =~ NotUndef } + +#### Examples + +##### Example usage + +```puppet + +$hash = delete_undef_values({a=>'A', b=>'', c=>undef, d => false}) +Would return: {a => 'A', b => '', d => false} + +While: +$array = delete_undef_values(['A','',undef,false]) +Would return: ['A','',false] +``` + +#### `delete_undef_values()` + +> *Note:* +Since Puppet 4.0.0 the equivalent can be performed with the built-in +[`filter`](https://puppet.com/docs/puppet/latest/function.html#filter) function: +$array.filter |$val| { $val =~ NotUndef } +$hash.filter |$key, $val| { $val =~ NotUndef } + +Returns: `Array` The given array now issing of undefined values. + +##### Examples + +###### Example usage + +```puppet + +$hash = delete_undef_values({a=>'A', b=>'', c=>undef, d => false}) +Would return: {a => 'A', b => '', d => false} + +While: +$array = delete_undef_values(['A','',undef,false]) +Would return: ['A','',false] +``` + +### `delete_values` + +Type: Ruby 3.x API + +> *Note:* +Since Puppet 4.0.0 the equivalent can be performed with the +built-in [`filter`](https://puppet.com/docs/puppet/latest/function.html#filter) function: +$array.filter |$val| { $val != 'B' } +$hash.filter |$key, $val| { $val != 'B' } + +#### Examples + +##### Example usage + +```puppet + +delete_values({'a'=>'A','b'=>'B','c'=>'C','B'=>'D'}, 'B') +Would return: {'a'=>'A','c'=>'C','B'=>'D'} +``` + +#### `delete_values()` + +> *Note:* +Since Puppet 4.0.0 the equivalent can be performed with the +built-in [`filter`](https://puppet.com/docs/puppet/latest/function.html#filter) function: +$array.filter |$val| { $val != 'B' } +$hash.filter |$key, $val| { $val != 'B' } + +Returns: `Hash` The given hash now missing all instances of the targeted value + +##### Examples + +###### Example usage + +```puppet + +delete_values({'a'=>'A','b'=>'B','c'=>'C','B'=>'D'}, 'B') +Would return: {'a'=>'A','c'=>'C','B'=>'D'} +``` + +### `deprecation` + +Type: Ruby 4.x API + +Function to print deprecation warnings, Logs a warning once for a given key. + +#### `deprecation(String $key, String $message, Optional[Boolean] $use_strict_setting)` + +The deprecation function. + +Returns: `Any` + +##### `key` + +Data type: `String` + +The uniqueness key. This function logs once for any given key. + +##### `message` + +Data type: `String` + +Is the message text including any positional information that is formatted by the user/caller of the function. + +##### `use_strict_setting` + +Data type: `Optional[Boolean]` + +When `true`, (the default), the function is affected by the puppet setting 'strict', which can be set to :error +(outputs as an error message), :off (no message / error is displayed) and :warning +(default, outputs a warning). + +### `difference` + +Type: Ruby 3.x API + +The returned array is a copy of the original array, removing any items that +also appear in the second array. + +> *Note:* +Since Puppet 4 the minus (-) operator in the Puppet language does the same thing: +['a', 'b', 'c'] - ['b', 'c', 'd'] +Would return: `['a']` + +#### Examples + +##### Example usage + +```puppet + +difference(["a","b","c"],["b","c","d"]) +Would return: `["a"]` +``` + +#### `difference()` + +The returned array is a copy of the original array, removing any items that +also appear in the second array. + +> *Note:* +Since Puppet 4 the minus (-) operator in the Puppet language does the same thing: +['a', 'b', 'c'] - ['b', 'c', 'd'] +Would return: `['a']` + +Returns: `Array` The difference between the two given arrays + +##### Examples + +###### Example usage + +```puppet + +difference(["a","b","c"],["b","c","d"]) +Would return: `["a"]` +``` + +### `dirname` + +Type: Ruby 3.x API + +Returns the dirname of a path. + +#### `dirname()` + +The dirname function. + +Returns: `String` the given path's dirname + +### `dos2unix` + +Type: Ruby 3.x API + +Takes a single string argument. + +#### `dos2unix()` + +Takes a single string argument. + +Returns: `Any` The retrieved version + +### `enclose_ipv6` + +Type: Ruby 3.x API + +Takes an array of ip addresses and encloses the ipv6 addresses with square brackets. + +#### `enclose_ipv6()` + +The enclose_ipv6 function. + +Returns: `Any` encloses the ipv6 addresses with square brackets. + +### `ensure_packages` + +Type: Ruby 4.x API + +DEPRECATED. Use the namespaced function [`stdlib::ensure_packages`](#stdlibensure_packages) instead. + +#### `ensure_packages(Any *$args)` + +The ensure_packages function. + +Returns: `Any` + +##### `*args` + +Data type: `Any` + + + +### `ensure_resource` + +Type: Ruby 3.x API + +user { 'dan': + ensure => present, +} + +#### Examples + +##### Example usage + +```puppet + +Creates the resource if it does not already exist: + + ensure_resource('user', 'dan', {'ensure' => 'present' }) + +If the resource already exists but does not match the specified parameters, +this function will attempt to recreate the resource leading to a duplicate +resource definition error. + +An array of resources can also be passed in and each will be created with +the type and parameters specified if it doesn't already exist. + + ensure_resource('user', ['dan','alex'], {'ensure' => 'present'}) +``` + +#### `ensure_resource()` + +user { 'dan': + ensure => present, +} + +Returns: `Any` created or recreated the passed resource with the passed type and attributes + +##### Examples + +###### Example usage + +```puppet + +Creates the resource if it does not already exist: + + ensure_resource('user', 'dan', {'ensure' => 'present' }) + +If the resource already exists but does not match the specified parameters, +this function will attempt to recreate the resource leading to a duplicate +resource definition error. + +An array of resources can also be passed in and each will be created with +the type and parameters specified if it doesn't already exist. + + ensure_resource('user', ['dan','alex'], {'ensure' => 'present'}) +``` + +### `ensure_resources` + +Type: Ruby 3.x API + +An hash of resources should be passed in and each will be created with + the type and parameters specified if it doesn't already exist. + + ensure_resources('user', {'dan' => { gid => 'mygroup', uid => '600' }, 'alex' => { gid => 'mygroup' }}, {'ensure' => 'present'}) + + From Hiera Backend: + + userlist: + dan: + gid: 'mygroup' + uid: '600' + alex: + gid: 'mygroup' + + Call: + ensure_resources('user', hiera_hash('userlist'), {'ensure' => 'present'}) + +#### Examples + +##### Example usage + +```puppet + +user { 'dan': + gid => 'mygroup', + ensure => present, +} +``` + +#### `ensure_resources()` + +An hash of resources should be passed in and each will be created with + the type and parameters specified if it doesn't already exist. + + ensure_resources('user', {'dan' => { gid => 'mygroup', uid => '600' }, 'alex' => { gid => 'mygroup' }}, {'ensure' => 'present'}) + + From Hiera Backend: + + userlist: + dan: + gid: 'mygroup' + uid: '600' + alex: + gid: 'mygroup' + + Call: + ensure_resources('user', hiera_hash('userlist'), {'ensure' => 'present'}) + +Returns: `Any` created resources with the passed type and attributes + +##### Examples + +###### Example usage + +```puppet + +user { 'dan': + gid => 'mygroup', + ensure => present, +} +``` + +### `fact` + +Type: Ruby 4.x API + +Supports the use of dot-notation for referring to structured facts. If a fact requested +does not exist, returns Undef. + +#### Examples + +##### Example usage: + +```puppet +fact('osfamily') +fact('os.architecture') +``` + +##### Array indexing: + +```puppet +fact('mountpoints."/dev".options.1') +``` + +##### Fact containing a "." in the name: + +```puppet +fact('vmware."VRA.version"') +``` + +#### `fact(String $fact_name)` + +Supports the use of dot-notation for referring to structured facts. If a fact requested +does not exist, returns Undef. + +Returns: `Any` All information retrieved on the given fact_name + +##### Examples + +###### Example usage: + +```puppet +fact('osfamily') +fact('os.architecture') +``` + +###### Array indexing: + +```puppet +fact('mountpoints."/dev".options.1') +``` + +###### Fact containing a "." in the name: + +```puppet +fact('vmware."VRA.version"') +``` + +##### `fact_name` + +Data type: `String` + +The name of the fact to check + +### `fqdn_rand_string` + +Type: Ruby 4.x API + +DEPRECATED. Use the namespaced function [`stdlib::fqdn_rand_string`](#stdlibfqdn_rand_string) instead. + +#### `fqdn_rand_string(Any *$args)` + +The fqdn_rand_string function. + +Returns: `Any` + +##### `*args` + +Data type: `Any` + + + +### `fqdn_rotate` + +Type: Ruby 4.x API + +DEPRECATED. Use the namespaced function [`stdlib::fqdn_rotate`](#stdlibfqdn_rotate) instead. + +#### `fqdn_rotate(Any *$args)` + +The fqdn_rotate function. + +Returns: `Any` + +##### `*args` + +Data type: `Any` + + + +### `fqdn_uuid` + +Type: Ruby 3.x API + +Returns a [RFC 4122](https://tools.ietf.org/html/rfc4122) valid version 5 UUID based +on an FQDN string under the DNS namespace + +#### Examples + +##### Example Usage: + +```puppet +fqdn_uuid('puppetlabs.com') # Returns '9c70320f-6815-5fc5-ab0f-debe68bf764c' +fqdn_uuid('google.com') # Returns '64ee70a4-8cc1-5d25-abf2-dea6c79a +``` + +#### `fqdn_uuid()` + +The fqdn_uuid function. + +Returns: `Any` Returns a [RFC 4122](https://tools.ietf.org/html/rfc4122) valid version 5 UUID + +##### Examples + +###### Example Usage: + +```puppet +fqdn_uuid('puppetlabs.com') # Returns '9c70320f-6815-5fc5-ab0f-debe68bf764c' +fqdn_uuid('google.com') # Returns '64ee70a4-8cc1-5d25-abf2-dea6c79a +``` + +### `get_module_path` + +Type: Ruby 3.x API + +> *Note:* + that since Puppet 5.4.0 the built-in + [`module_directory`](https://puppet.com/docs/puppet/latest/function.html#module_directory) + function in Puppet does the same thing and will return the path to the first found module + if given multiple values or an array. + +#### Examples + +##### Example Usage: + +```puppet +$module_path = get_module_path('stdlib') +``` + +#### `get_module_path()` + +> *Note:* + that since Puppet 5.4.0 the built-in + [`module_directory`](https://puppet.com/docs/puppet/latest/function.html#module_directory) + function in Puppet does the same thing and will return the path to the first found module + if given multiple values or an array. + +Returns: `Any` Returns the absolute path of the specified module for the current +environment. + +##### Examples + +###### Example Usage: + +```puppet +$module_path = get_module_path('stdlib') +``` + +### `getparam` + +Type: Ruby 3.x API + +Takes a resource reference and name of the parameter and +returns value of resource's parameter. Note that user defined +resource types are evaluated lazily. + +Would notice: 'the value we are getting in this example' + +> **Note** that since Puppet 4.0.0 it is possible to get a parameter value by using its data type +and the [ ] operator. The example below is equivalent to a call to getparam(): + ```Example_resource['example_resource_instance']['param']`` + +#### Examples + +##### Example Usage: + +```puppet + +# define a resource type with a parameter +define example_resource($param) { +} + +# declare an instance of that type +example_resource { "example_resource_instance": + param => "'the value we are getting in this example''" +} + +# Because of order of evaluation, a second definition is needed +# that will be evaluated after the first resource has been declared +# +define example_get_param { + # This will notice the value of the parameter + notice(getparam(Example_resource["example_resource_instance"], "param")) +} + +# Declare an instance of the second resource type - this will call notice +example_get_param { 'show_notify': } +``` + +#### `getparam()` + +Takes a resource reference and name of the parameter and +returns value of resource's parameter. Note that user defined +resource types are evaluated lazily. + +Would notice: 'the value we are getting in this example' + +> **Note** that since Puppet 4.0.0 it is possible to get a parameter value by using its data type +and the [ ] operator. The example below is equivalent to a call to getparam(): + ```Example_resource['example_resource_instance']['param']`` + +Returns: `Any` value of a resource's parameter. + +##### Examples + +###### Example Usage: + +```puppet + +# define a resource type with a parameter +define example_resource($param) { +} + +# declare an instance of that type +example_resource { "example_resource_instance": + param => "'the value we are getting in this example''" +} + +# Because of order of evaluation, a second definition is needed +# that will be evaluated after the first resource has been declared +# +define example_get_param { + # This will notice the value of the parameter + notice(getparam(Example_resource["example_resource_instance"], "param")) +} + +# Declare an instance of the second resource type - this will call notice +example_get_param { 'show_notify': } +``` + +### `glob` + +Type: Ruby 3.x API + +Uses same patterns as Dir#glob. + +#### Examples + +##### Example Usage: + +```puppet +$confs = glob(['/etc/**/*.conf', '/opt/**/*.conf']) +``` + +#### `glob()` + +The glob function. + +Returns: `Any` Returns an Array of file entries of a directory or an Array of directories. + +##### Examples + +###### Example Usage: + +```puppet +$confs = glob(['/etc/**/*.conf', '/opt/**/*.conf']) +``` + +### `grep` + +Type: Ruby 3.x API + +> **Note:** that since Puppet 4.0.0, the built-in +[`filter`](https://puppet.com/docs/puppet/latest/function.html#filter) function does +the "same" - as any logic can be used to filter, as opposed to just regular expressions: +```['aaa', 'bbb', 'ccc', 'aaaddd']. filter |$x| { $x =~ 'aaa' }``` + +#### Examples + +##### Example Usage: + +```puppet +grep(['aaa','bbb','ccc','aaaddd'], 'aaa') # Returns ['aaa','aaaddd'] +``` + +#### `grep()` + +> **Note:** that since Puppet 4.0.0, the built-in +[`filter`](https://puppet.com/docs/puppet/latest/function.html#filter) function does +the "same" - as any logic can be used to filter, as opposed to just regular expressions: +```['aaa', 'bbb', 'ccc', 'aaaddd']. filter |$x| { $x =~ 'aaa' }``` + +Returns: `Any` array of elements that match the provided regular expression. + +##### Examples + +###### Example Usage: + +```puppet +grep(['aaa','bbb','ccc','aaaddd'], 'aaa') # Returns ['aaa','aaaddd'] +``` + +### `has_interface_with` + +Type: Ruby 4.x API + +DEPRECATED. Use the namespaced function [`stdlib::has_interface_with`](#stdlibhas_interface_with) instead. + +#### `has_interface_with(Any *$args)` + +The has_interface_with function. + +Returns: `Any` + +##### `*args` + +Data type: `Any` + + + +### `has_ip_address` + +Type: Ruby 4.x API + +DEPRECATED. Use the namespaced function [`stdlib::has_ip_address`](#stdlibhas_ip_address) instead. + +#### `has_ip_address(Any *$args)` + +The has_ip_address function. + +Returns: `Any` + +##### `*args` + +Data type: `Any` + + + +### `has_ip_network` + +Type: Ruby 4.x API + +DEPRECATED. Use the namespaced function [`stdlib::has_ip_network`](#stdlibhas_ip_network) instead. + +#### `has_ip_network(Any *$args)` + +The has_ip_network function. + +Returns: `Any` + +##### `*args` + +Data type: `Any` + + + +### `intersection` + +Type: Ruby 3.x API + +This function returns an array of the intersection of two. + +#### Examples + +##### Example Usage: + +```puppet +intersection(["a","b","c"],["b","c","d"]) # returns ["b","c"] +intersection(["a","b","c"],[1,2,3,4]) # returns [] (true, when evaluated as a Boolean) +``` + +#### `intersection()` + +The intersection function. + +Returns: `Any` an array of the intersection of two. + +##### Examples + +###### Example Usage: + +```puppet +intersection(["a","b","c"],["b","c","d"]) # returns ["b","c"] +intersection(["a","b","c"],[1,2,3,4]) # returns [] (true, when evaluated as a Boolean) +``` + +### `is_a` + +Type: Ruby 4.x API + +See the documentation for "The Puppet Type System" for more information about types. +See the `assert_type()` function for flexible ways to assert the type of a value. + +#### Examples + +##### Example Usage: + +```puppet +# check a data type + foo = 3 + $bar = [1,2,3] + $baz = 'A string!' + + if $foo.is_a(Integer) { + notify { 'foo!': } + } + if $bar.is_a(Array) { + notify { 'bar!': } + } + if $baz.is_a(String) { + notify { 'baz!': } + } +``` + +#### `is_a(Any $value, Type $type)` + +See the documentation for "The Puppet Type System" for more information about types. +See the `assert_type()` function for flexible ways to assert the type of a value. + +Returns: `Boolean` Return's `true` or `false`. + +##### Examples + +###### Example Usage: + +```puppet +# check a data type + foo = 3 + $bar = [1,2,3] + $baz = 'A string!' + + if $foo.is_a(Integer) { + notify { 'foo!': } + } + if $bar.is_a(Array) { + notify { 'bar!': } + } + if $baz.is_a(String) { + notify { 'baz!': } + } +``` + +##### `value` + +Data type: `Any` + +The value to be checked + +##### `type` + +Data type: `Type` + +The expected type + +### `join_keys_to_values` + +Type: Ruby 3.x API + +Keys are cast to strings. If values are arrays, multiple keys +are added for each element. The return value is an array in +which each element is one joined key/value pair. + +> **Note:** Since Puppet 5.0.0 - for more detailed control over the formatting (including indentations and +line breaks, delimiters around arrays and hash entries, between key/values in hash entries, and individual +formatting of values in the array) - see the `new` function for `String` and its formatting +options for `Array` and `Hash`. + +#### Examples + +##### Example Usage: + +```puppet +join_keys_to_values({'a'=>1,'b'=>2}, " is ") # Results in: ["a is 1","b is 2"] +join_keys_to_values({'a'=>1,'b'=>[2,3]}, " is ") # Results in: ["a is 1","b is 2","b is 3"] +``` + +#### `join_keys_to_values()` + +Keys are cast to strings. If values are arrays, multiple keys +are added for each element. The return value is an array in +which each element is one joined key/value pair. + +> **Note:** Since Puppet 5.0.0 - for more detailed control over the formatting (including indentations and +line breaks, delimiters around arrays and hash entries, between key/values in hash entries, and individual +formatting of values in the array) - see the `new` function for `String` and its formatting +options for `Array` and `Hash`. + +Returns: `Hash` The joined hash + +##### Examples + +###### Example Usage: + +```puppet +join_keys_to_values({'a'=>1,'b'=>2}, " is ") # Results in: ["a is 1","b is 2"] +join_keys_to_values({'a'=>1,'b'=>[2,3]}, " is ") # Results in: ["a is 1","b is 2","b is 3"] +``` + +### `load_module_metadata` + +Type: Ruby 3.x API + +This function loads the metadata of a given module. + +#### Examples + +##### Example Usage: + +```puppet +$metadata = load_module_metadata('archive') +notify { $metadata['author']: } +``` + +#### `load_module_metadata()` + +The load_module_metadata function. + +Returns: `Any` The modules metadata + +##### Examples + +###### Example Usage: + +```puppet +$metadata = load_module_metadata('archive') +notify { $metadata['author']: } +``` + +### `loadjson` + +Type: Ruby 3.x API + +The first parameter can be a file path or a URL. +The second parameter is the default value. It will be returned if the file +was not found or could not be parsed. + +#### Examples + +##### Example Usage: + +```puppet +$myhash = loadjson('/etc/puppet/data/myhash.json') +$myhash = loadjson('https://example.local/my_hash.json') +$myhash = loadjson('https://username:password@example.local/my_hash.json') +$myhash = loadjson('no-file.json', {'default' => 'val +``` + +#### `loadjson()` + +The first parameter can be a file path or a URL. +The second parameter is the default value. It will be returned if the file +was not found or could not be parsed. + +Returns: `Array|String|Hash` The data stored in the JSON file, the type depending on the type of data that was stored. + +##### Examples + +###### Example Usage: + +```puppet +$myhash = loadjson('/etc/puppet/data/myhash.json') +$myhash = loadjson('https://example.local/my_hash.json') +$myhash = loadjson('https://username:password@example.local/my_hash.json') +$myhash = loadjson('no-file.json', {'default' => 'val +``` + +### `loadyaml` + +Type: Ruby 3.x API + +The first parameter can be a file path or a URL. +The second parameter is the default value. It will be returned if the file +was not found or could not be parsed. + +#### Examples + +##### Example Usage: + +```puppet +$myhash = loadyaml('/etc/puppet/data/myhash.yaml') +$myhash = loadyaml('https://example.local/my_hash.yaml') +$myhash = loadyaml('https://username:password@example.local/my_hash.yaml') +$myhash = loadyaml('no-file.yaml', {'default' => 'val +``` + +#### `loadyaml()` + +The first parameter can be a file path or a URL. +The second parameter is the default value. It will be returned if the file +was not found or could not be parsed. + +Returns: `Array|String|Hash` The data stored in the YAML file, the type depending on the type of data that was stored. + +##### Examples + +###### Example Usage: + +```puppet +$myhash = loadyaml('/etc/puppet/data/myhash.yaml') +$myhash = loadyaml('https://example.local/my_hash.yaml') +$myhash = loadyaml('https://username:password@example.local/my_hash.yaml') +$myhash = loadyaml('no-file.yaml', {'default' => 'val +``` + +### `member` + +Type: Ruby 3.x API + +The variable can be a string, fixnum, or array. + +> **Note**: This function does not support nested arrays. If the first argument contains +nested arrays, it will not recurse through them. + +> *Note:* +Since Puppet 4.0.0 the same can be performed in the Puppet language. +For single values the operator `in` can be used: +`'a' in ['a', 'b'] # true` +For arrays by using operator `-` to compute a diff: +`['d', 'b'] - ['a', 'b', 'c'] == [] # false because 'd' is not subtracted` +`['a', 'b'] - ['a', 'b', 'c'] == [] # true because both 'a' and 'b' are subtracted` + +> **Note** that since Puppet 5.2.0, the general form to test the content of an array or +hash is to use the built-in [`any`](https://puppet.com/docs/puppet/latest/function.html#any) +and [`all`](https://puppet.com/docs/puppet/latest/function.html#all) functions. + +#### Examples + +##### **Usage** + +```puppet +member(['a','b'], 'b') # Returns: true +member(['a', 'b', 'c'], ['a', 'b']) # Returns: true +member(['a','b'], 'c') # Returns: false +member(['a', 'b', 'c'], ['d', 'b']) # Returns: false +``` + +#### `member()` + +The variable can be a string, fixnum, or array. + +> **Note**: This function does not support nested arrays. If the first argument contains +nested arrays, it will not recurse through them. + +> *Note:* +Since Puppet 4.0.0 the same can be performed in the Puppet language. +For single values the operator `in` can be used: +`'a' in ['a', 'b'] # true` +For arrays by using operator `-` to compute a diff: +`['d', 'b'] - ['a', 'b', 'c'] == [] # false because 'd' is not subtracted` +`['a', 'b'] - ['a', 'b', 'c'] == [] # true because both 'a' and 'b' are subtracted` + +> **Note** that since Puppet 5.2.0, the general form to test the content of an array or +hash is to use the built-in [`any`](https://puppet.com/docs/puppet/latest/function.html#any) +and [`all`](https://puppet.com/docs/puppet/latest/function.html#all) functions. + +Returns: `Any` Returns whether the given value was a member of the array + +##### Examples + +###### **Usage** + +```puppet +member(['a','b'], 'b') # Returns: true +member(['a', 'b', 'c'], ['a', 'b']) # Returns: true +member(['a','b'], 'c') # Returns: false +member(['a', 'b', 'c'], ['d', 'b']) # Returns: false +``` + +### `merge` + +Type: Ruby 4.x API + +DEPRECATED. Use the namespaced function [`stdlib::merge`](#stdlibmerge) instead. + +#### `merge(Any *$args, Optional[Variant[Callable[2,2], Callable[3,3]]] &$block)` + +The merge function. + +Returns: `Any` + +##### `*args` + +Data type: `Any` + + + +##### `&block` + +Data type: `Optional[Variant[Callable[2,2], Callable[3,3]]]` + + + +### `merge` + +Type: Ruby 3.x API + +When there is a duplicate key, the key in the rightmost hash will "win." + +Note that since Puppet 4.0.0 the same merge can be achieved with the + operator. + `$merged_hash = $hash1 + $h + +#### Examples + +##### **Usage** + +```puppet +$hash1 = {'one' => 1, 'two', => 2} +$hash2 = {'two' => 'dos', 'three', => 'tres'} +$merged_hash = merge($hash1, $hash2) # $merged_hash = {'one' => 1, 'two' => 'dos', 'three' => 'tres'} +``` + +#### `merge()` + +When there is a duplicate key, the key in the rightmost hash will "win." + +Note that since Puppet 4.0.0 the same merge can be achieved with the + operator. + `$merged_hash = $hash1 + $h + +Returns: `Hash` The merged hash + +##### Examples + +###### **Usage** + +```puppet +$hash1 = {'one' => 1, 'two', => 2} +$hash2 = {'two' => 'dos', 'three', => 'tres'} +$merged_hash = merge($hash1, $hash2) # $merged_hash = {'one' => 1, 'two' => 'dos', 'three' => 'tres'} +``` + +### `num2bool` + +Type: Ruby 3.x API + +> *Note:* that since Puppet 5.0.0 the same can be achieved with the Puppet Type System. +See the new() function in Puppet for the many available type conversions. + +#### `num2bool()` + +> *Note:* that since Puppet 5.0.0 the same can be achieved with the Puppet Type System. +See the new() function in Puppet for the many available type conversions. + +Returns: `Boolean` Boolean(0) # false for any zero or negative number +Boolean(1) # true for any positive number + +### `os_version_gte` + +Type: Ruby 4.x API + +DEPRECATED. Use the namespaced function [`stdlib::os_version_gte`](#stdlibos_version_gte) instead. + +#### `os_version_gte(Any *$args)` + +The os_version_gte function. + +Returns: `Any` + +##### `*args` + +Data type: `Any` + + + +### `parsehocon` + +Type: Ruby 4.x API + +DEPRECATED. Use the namespaced function [`stdlib::parsehocon`](#stdlibparsehocon) instead. + +#### `parsehocon(Any *$args)` + +The parsehocon function. + +Returns: `Any` + +##### `*args` + +Data type: `Any` + + + +### `parsejson` + +Type: Ruby 3.x API + +> *Note:* + The optional second argument can be used to pass a default value that will + be returned if the parsing of the JSON string failed or if the JSON parse + evaluated to nil. + +#### `parsejson()` + +> *Note:* + The optional second argument can be used to pass a default value that will + be returned if the parsing of the JSON string failed or if the JSON parse + evaluated to nil. + +Returns: `Any` convert JSON into Puppet structure + +### `parsepson` + +Type: Ruby 4.x API + +For more information on PSON please see the following link: +https://puppet.com/docs/puppet/7/http_api/pson.html + +#### Examples + +##### How to parse pson + +```puppet +$data = parsepson('{"a":"1","b":"2"}') +``` + +#### `parsepson(String[1] $pson_string, Optional[Any] $default)` + +For more information on PSON please see the following link: +https://puppet.com/docs/puppet/7/http_api/pson.html + +Returns: `Data` + +##### Examples + +###### How to parse pson + +```puppet +$data = parsepson('{"a":"1","b":"2"}') +``` + +##### `pson_string` + +Data type: `String[1]` + +A valid PSON string + +##### `default` + +Data type: `Optional[Any]` + +An optional default to return if parsing the pson_string fails + +### `parseyaml` + +Type: Ruby 3.x API + +> *Note:* + The optional second argument can be used to pass a default value that will + be returned if the parsing of YAML string have failed. + +#### `parseyaml()` + +> *Note:* + The optional second argument can be used to pass a default value that will + be returned if the parsing of YAML string have failed. + +Returns: `Any` converted YAML into Puppet structure + +### `pick` + +Type: Ruby 3.x API + +This function is similar to a coalesce function in SQL. + +Typically, this function is used to check for a value in the Puppet +Dashboard/Enterprise Console, and failover to a default value like the following: + +```$real_jenkins_version = pick($::jenkins_version, '1.449')``` + +> *Note:* + The value of $real_jenkins_version will first look for a top-scope variable + called 'jenkins_version' (note that parameters set in the Puppet Dashboard/ + Enterprise Console are brought into Puppet as top-scope variables), and, + failing that, will use a default value of 1.449. + +#### `pick()` + +This function is similar to a coalesce function in SQL. + +Typically, this function is used to check for a value in the Puppet +Dashboard/Enterprise Console, and failover to a default value like the following: + +```$real_jenkins_version = pick($::jenkins_version, '1.449')``` + +> *Note:* + The value of $real_jenkins_version will first look for a top-scope variable + called 'jenkins_version' (note that parameters set in the Puppet Dashboard/ + Enterprise Console are brought into Puppet as top-scope variables), and, + failing that, will use a default value of 1.449. + +Returns: `Any` the first value in a list of values that is not undefined or an empty string. + +### `pick_default` + +Type: Ruby 3.x API + +Typically, this function is used to check for a value in the Puppet +Dashboard/Enterprise Console, and failover to a default value like the +following: + + $real_jenkins_version = pick_default($::jenkins_version, '1.449') + +> *Note:* + The value of $real_jenkins_version will first look for a top-scope variable + called 'jenkins_version' (note that parameters set in the Puppet Dashboard/ + Enterprise Console are brought into Puppet as top-scope variables), and, + failing that, will use a default value of 1.449. + + Contrary to the pick() function, the pick_default does not fail if + all arguments are empty. This allows pick_default to use an empty value as + default. + +#### `pick_default()` + +Typically, this function is used to check for a value in the Puppet +Dashboard/Enterprise Console, and failover to a default value like the +following: + + $real_jenkins_version = pick_default($::jenkins_version, '1.449') + +> *Note:* + The value of $real_jenkins_version will first look for a top-scope variable + called 'jenkins_version' (note that parameters set in the Puppet Dashboard/ + Enterprise Console are brought into Puppet as top-scope variables), and, + failing that, will use a default value of 1.449. + + Contrary to the pick() function, the pick_default does not fail if + all arguments are empty. This allows pick_default to use an empty value as + default. + +Returns: `Any` This function is similar to a coalesce function in SQL in that it will return +the first value in a list of values that is not undefined or an empty string +If no value is found, it will return the last argument. + +### `powershell_escape` + +Type: Ruby 4.x API + +DEPRECATED. Use the namespaced function [`stdlib::powershell_escape`](#stdlibpowershell_escape) instead. + +#### `powershell_escape(Any *$args)` + +The powershell_escape function. + +Returns: `Any` + +##### `*args` + +Data type: `Any` + + + +### `prefix` + +Type: Ruby 3.x API + +> *Note:* since Puppet 4.0.0 the general way to modify values is in array is by using the map +function in Puppet. This example does the same as the example above: +['a', 'b', 'c'].map |$x| { "p${x}" } + +#### Examples + +##### **Usage** + +```puppet + +prefix(['a','b','c'], 'p') +Will return: ['pa','pb','pc'] +``` + +#### `prefix()` + +> *Note:* since Puppet 4.0.0 the general way to modify values is in array is by using the map +function in Puppet. This example does the same as the example above: +['a', 'b', 'c'].map |$x| { "p${x}" } + +Returns: `Hash` or [Array] The passed values now contains the passed prefix + +##### Examples + +###### **Usage** + +```puppet + +prefix(['a','b','c'], 'p') +Will return: ['pa','pb','pc'] +``` + +### `pry` + +Type: Ruby 3.x API + +This is useful for debugging manifest code at specific points during a compilation. + +#### Examples + +##### **Usage** + +```puppet + +`pry()` +``` + +#### `pry()` + +This is useful for debugging manifest code at specific points during a compilation. + +Returns: `Any` debugging information + +##### Examples + +###### **Usage** + +```puppet + +`pry()` +``` + +### `pw_hash` + +Type: Ruby 3.x API + +The first argument to this function is the password to hash. If it is +undef or an empty string, this function returns undef. + +The second argument to this function is which hash algorithm to use. It +will be converted into the appropriate crypt(3) hash specifier. Valid +hash types are: + +|Hash type|Prefix|Note | +|---------|------|---------------------| +|MD5 |1 | | +|SHA-256 |5 | | +|SHA-512 |6 |Recommended | +|bcrypt |2b | | +|bcrypt-a |2a |bug compatible | +|bcrypt-x |2x |bug compatible | +|bcrypt-y |2y |historic alias for 2b| + +The third argument to this function is the salt to use. For bcrypt-type hashes, +the first two characters of the salt represent a strength parameter, with a value +between 4 and 31 inclusive. + +> *Note:*: this uses the Puppet Server's implementation of crypt(3). If your + environment contains several different operating systems, ensure that they + are compatible before using this function. + +#### `pw_hash()` + +The first argument to this function is the password to hash. If it is +undef or an empty string, this function returns undef. + +The second argument to this function is which hash algorithm to use. It +will be converted into the appropriate crypt(3) hash specifier. Valid +hash types are: + +|Hash type|Prefix|Note | +|---------|------|---------------------| +|MD5 |1 | | +|SHA-256 |5 | | +|SHA-512 |6 |Recommended | +|bcrypt |2b | | +|bcrypt-a |2a |bug compatible | +|bcrypt-x |2x |bug compatible | +|bcrypt-y |2y |historic alias for 2b| + +The third argument to this function is the salt to use. For bcrypt-type hashes, +the first two characters of the salt represent a strength parameter, with a value +between 4 and 31 inclusive. + +> *Note:*: this uses the Puppet Server's implementation of crypt(3). If your + environment contains several different operating systems, ensure that they + are compatible before using this function. + +Returns: `String` Provides a crypt hash usable on most POSIX systems. + +### `range` + +Type: Ruby 3.x API + +NB Be explicit in including trailing zeros. Otherwise the underlying ruby function will fail. + +> *Note:* + Passing a third argument will cause the generated range to step by that + interval, e.g. + +The Puppet Language support Integer and Float ranges by using the type system. Those are suitable for +iterating a given number of times. + + Integer[0, 9].each |$x| { notice($x) } # notices 0, 1, 2, ... 9 + +#### Examples + +##### **Usage** + +```puppet +range("0", "9") +Will return: [0,1,2,3,4,5,6,7,8,9] + +range("00", "09") +Will return: [0,1,2,3,4,5,6,7,8,9] +(Zero padded strings are converted to integers automatically) + +range("a", "c") +Will return: ["a","b","c"] + +range("host01", "host10") +Will return: ["host01", "host02", ..., "host09", "host10"] + +range("0", "9", "2") +Will return: [0,2,4,6,8] +``` + +#### `range()` + +NB Be explicit in including trailing zeros. Otherwise the underlying ruby function will fail. + +> *Note:* + Passing a third argument will cause the generated range to step by that + interval, e.g. + +The Puppet Language support Integer and Float ranges by using the type system. Those are suitable for +iterating a given number of times. + + Integer[0, 9].each |$x| { notice($x) } # notices 0, 1, 2, ... 9 + +Returns: `Any` the range is extrapolated as an array + +##### Examples + +###### **Usage** + +```puppet +range("0", "9") +Will return: [0,1,2,3,4,5,6,7,8,9] + +range("00", "09") +Will return: [0,1,2,3,4,5,6,7,8,9] +(Zero padded strings are converted to integers automatically) + +range("a", "c") +Will return: ["a","b","c"] + +range("host01", "host10") +Will return: ["host01", "host02", ..., "host09", "host10"] + +range("0", "9", "2") +Will return: [0,2,4,6,8] +``` + +### `regexpescape` + +Type: Ruby 3.x API + +Regexp escape a string or array of strings. +Requires either a single string or an array as an input. + +#### `regexpescape()` + +The regexpescape function. + +Returns: `String` A string of characters with metacharacters converted to their escaped form. + +### `reject` + +Type: Ruby 3.x API + +> *Note:* +Since Puppet 4.0.0 the same is in general done with the filter function. Here is the equivalence of the reject() function: +['aaa','bbb','ccc','aaaddd'].filter |$x| { $x !~ /a + +#### Examples + +##### **Usage** + +```puppet + +reject(['aaa','bbb','ccc','aaaddd'], 'aaa') + +Would return: ['bbb','ccc'] +``` + +#### `reject()` + +> *Note:* +Since Puppet 4.0.0 the same is in general done with the filter function. Here is the equivalence of the reject() function: +['aaa','bbb','ccc','aaaddd'].filter |$x| { $x !~ /a + +Returns: `Any` an array containing all the elements which doesn'' match the provided regular expression + +##### Examples + +###### **Usage** + +```puppet + +reject(['aaa','bbb','ccc','aaaddd'], 'aaa') + +Would return: ['bbb','ccc'] +``` + +### `reverse` + +Type: Ruby 3.x API + +> *Note:* that the same can be done with the reverse_each() function in Puppet. + +#### `reverse()` + +> *Note:* that the same can be done with the reverse_each() function in Puppet. + +Returns: `Any` reversed string or array + +### `seeded_rand` + +Type: Ruby 4.x API + +DEPRECATED. Use the namespaced function [`stdlib::seeded_rand`](#stdlibseeded_rand) instead. + +#### `seeded_rand(Any *$args)` + +The seeded_rand function. + +Returns: `Any` + +##### `*args` + +Data type: `Any` + + + +### `seeded_rand_string` + +Type: Ruby 4.x API + +DEPRECATED. Use the namespaced function [`stdlib::seeded_rand_string`](#stdlibseeded_rand_string) instead. + +#### `seeded_rand_string(Any *$args)` + +The seeded_rand_string function. + +Returns: `Any` + +##### `*args` + +Data type: `Any` + + + +### `shell_escape` + +Type: Ruby 4.x API + +DEPRECATED. Use the namespaced function [`stdlib::shell_escape`](#stdlibshell_escape) instead. + +#### `shell_escape(Any *$args)` + +The shell_escape function. + +Returns: `Any` + +##### `*args` + +Data type: `Any` + + + +### `shell_join` + +Type: Ruby 3.x API + +Builds a command line string from the given array of strings. +Each array item is escaped for Bourne shell. All items are then joined together, with a single space in between. +This function behaves the same as ruby's Shellwords.shelljoin() function + +#### `shell_join()` + +Builds a command line string from the given array of strings. +Each array item is escaped for Bourne shell. All items are then joined together, with a single space in between. +This function behaves the same as ruby's Shellwords.shelljoin() function + +Returns: `Any` a command line string + +### `shell_split` + +Type: Ruby 3.x API + +This function behaves the same as ruby's Shellwords.shellsplit() function + +#### `shell_split()` + +This function behaves the same as ruby's Shellwords.shellsplit() function + +Returns: `Any` array of tokens + +### `shuffle` + +Type: Ruby 3.x API + +@summary + Randomizes the order of a string or array elements. + +#### `shuffle()` + +@summary + Randomizes the order of a string or array elements. + +Returns: `Any` randomized string or array + +### `squeeze` + +Type: Ruby 3.x API + +Returns a new string where runs of the same character that occur in this set are replaced by a single character. + +#### `squeeze()` + +The squeeze function. + +Returns: `Any` a new string where runs of the same character that occur in this set are replaced by a single character. + +### `stdlib::batch_escape` + +Type: Ruby 4.x API + +>* Note:* that the resulting string should be used unquoted and is not intended for use in double quotes nor in single +quotes. + +#### `stdlib::batch_escape(Any $string)` + +>* Note:* that the resulting string should be used unquoted and is not intended for use in double quotes nor in single +quotes. + +Returns: `Any` An escaped string that can be safely used in a batch command line. + +##### `string` + +Data type: `Any` + +The string to escape + +### `stdlib::crc32` + +Type: Ruby 4.x API + +Run a CRC32 calculation against a given value. + +#### Examples + +##### Check a simple string value + +```puppet +stdlib::crc32('my string') == '18fbd270' +``` + +##### Check a Sensitive datatype + +```puppet +stdlib::crc32(sensitive('my string')) == '18fbd270' +``` + +##### Check a number + +```puppet +stdlib::crc32(100.0) == 'a3fd429a' +stdlib::crc32(100.00000) == 'a3fd429a' +``` + +#### `stdlib::crc32(Variant[ScalarData, Sensitive[ScalarData], Binary, Sensitive[Binary]] $my_data)` + +Run a CRC32 calculation against a given value. + +Returns: `String` String + +##### Examples + +###### Check a simple string value + +```puppet +stdlib::crc32('my string') == '18fbd270' +``` + +###### Check a Sensitive datatype + +```puppet +stdlib::crc32(sensitive('my string')) == '18fbd270' +``` + +###### Check a number + +```puppet +stdlib::crc32(100.0) == 'a3fd429a' +stdlib::crc32(100.00000) == 'a3fd429a' +``` + +##### `my_data` + +Data type: `Variant[ScalarData, Sensitive[ScalarData], Binary, Sensitive[Binary]]` + +The ScalarData to evaluate + +### `stdlib::deferrable_epp` + +Type: Puppet Language + +This function returns either a rendered template or a deferred function to render at runtime. +If any of the values in the variables hash are deferred, then the template will be deferred. + +Note: this function requires all parameters to be explicitly passed in. It cannot expect to +use facts, class variables, and other variables in scope. This is because when deferred, we +have to explicitly pass the entire scope to the client. + +#### `stdlib::deferrable_epp(String $template, Hash $variables)` + +This function returns either a rendered template or a deferred function to render at runtime. +If any of the values in the variables hash are deferred, then the template will be deferred. + +Note: this function requires all parameters to be explicitly passed in. It cannot expect to +use facts, class variables, and other variables in scope. This is because when deferred, we +have to explicitly pass the entire scope to the client. + +Returns: `Variant[String, Sensitive[String], Deferred]` + +##### `template` + +Data type: `String` + + + +##### `variables` + +Data type: `Hash` + + + +### `stdlib::end_with` + +Type: Ruby 4.x API + +Returns true if str ends with one of the prefixes given. Each of the prefixes should be a String. + +#### Examples + +##### + +```puppet +'foobar'.stdlib::end_with('bar') => true +'foobar'.stdlib::end_with('foo') => false +'foobar'.stdlib::end_with(['foo', 'baz']) => false +``` + +#### `stdlib::end_with(String $test_string, Variant[String[1],Array[String[1], 1]] $suffixes)` + +The stdlib::end_with function. + +Returns: `Boolean` True or False + +##### Examples + +###### + +```puppet +'foobar'.stdlib::end_with('bar') => true +'foobar'.stdlib::end_with('foo') => false +'foobar'.stdlib::end_with(['foo', 'baz']) => false +``` + +##### `test_string` + +Data type: `String` + +The string to check + +##### `suffixes` + +Data type: `Variant[String[1],Array[String[1], 1]]` + +The suffixes to check + +### `stdlib::ensure` + +Type: Puppet Language + +function to cast ensure parameter to resource specific value + +#### `stdlib::ensure(Variant[Boolean, Enum['present', 'absent']] $ensure, Optional[Enum['directory', 'link', 'mounted', 'service', 'file', 'package']] $resource = undef)` + +The stdlib::ensure function. + +Returns: `String` + +##### `ensure` + +Data type: `Variant[Boolean, Enum['present', 'absent']]` + + + +##### `resource` + +Data type: `Optional[Enum['directory', 'link', 'mounted', 'service', 'file', 'package']]` + + + +### `stdlib::ensure_packages` + +Type: Ruby 4.x API + +It optionally takes a hash as a second parameter that will be passed as the +third argument to the ensure_resource() function. + +#### `stdlib::ensure_packages(Variant[String[1], Array[String[1]]] $packages, Optional[Hash] $default_attributes)` + +The stdlib::ensure_packages function. + +Returns: `Undef` Returns nothing. + +##### `packages` + +Data type: `Variant[String[1], Array[String[1]]]` + +The packages to ensure are installed. + +##### `default_attributes` + +Data type: `Optional[Hash]` + +Default attributes to be passed to the `ensure_resource()` function + +#### `stdlib::ensure_packages(Hash[String[1], Any] $packages, Optional[Hash] $default_attributes)` + +The stdlib::ensure_packages function. + +Returns: `Undef` Returns nothing. + +##### `packages` + +Data type: `Hash[String[1], Any]` + +The packages to ensure are installed. The keys are packages and values are the attributes specific to that package. + +##### `default_attributes` + +Data type: `Optional[Hash]` + +Default attributes. Package specific attributes from the `packages` parameter will take precedence. + +### `stdlib::extname` + +Type: Ruby 4.x API + +If Path is a Dotfile, or starts with a Period, then the starting Dot is not +dealt with the Start of the Extension. + +An empty String will also be returned, when the Period is the last Character +in Path. + +#### Examples + +##### Determining the Extension of a Filename + +```puppet +stdlib::extname('test.rb') => '.rb' +stdlib::extname('a/b/d/test.rb') => '.rb' +stdlib::extname('test') => '' +stdlib::extname('.profile') => '' +``` + +#### `stdlib::extname(String $filename)` + +If Path is a Dotfile, or starts with a Period, then the starting Dot is not +dealt with the Start of the Extension. + +An empty String will also be returned, when the Period is the last Character +in Path. + +Returns: `String` The Extension starting from the last Period + +##### Examples + +###### Determining the Extension of a Filename + +```puppet +stdlib::extname('test.rb') => '.rb' +stdlib::extname('a/b/d/test.rb') => '.rb' +stdlib::extname('test') => '' +stdlib::extname('.profile') => '' +``` + +##### `filename` + +Data type: `String` + +The Filename + +### `stdlib::fqdn_rand_string` + +Type: Ruby 4.x API + +Optionally, you can specify a character set for the function (defaults to alphanumeric). + +#### Examples + +##### Example Usage: + +```puppet +stdlib::fqdn_rand_string(10) +stdlib::fqdn_rand_string(10, 'ABCDEF!@$%^') +stdlib::fqdn_rand_string(10, undef, 'custom seed') +``` + +#### `stdlib::fqdn_rand_string(Integer[1] $length, Optional[Optional[String]] $charset, Optional[Any] *$seed)` + +Optionally, you can specify a character set for the function (defaults to alphanumeric). + +Returns: `String` + +##### Examples + +###### Example Usage: + +```puppet +stdlib::fqdn_rand_string(10) +stdlib::fqdn_rand_string(10, 'ABCDEF!@$%^') +stdlib::fqdn_rand_string(10, undef, 'custom seed') +``` + +##### `length` + +Data type: `Integer[1]` + +The length of the resulting string. + +##### `charset` + +Data type: `Optional[Optional[String]]` + +The character set to use. + +##### `*seed` + +Data type: `Optional[Any]` + +The seed for repeatable randomness. + +### `stdlib::fqdn_rotate` + +Type: Ruby 4.x API + +Rotates an array or string a random number of times, combining the `fqdn` fact and an optional seed for repeatable randomness. + +#### `stdlib::fqdn_rotate(String $input, Optional[Variant[Integer,String]] *$seeds)` + +The stdlib::fqdn_rotate function. + +Returns: `String` Returns the rotated String + +##### Examples + +###### Rotating a String + +```puppet +stdlib::fqdn_rotate('abcd') +``` + +###### Using a custom seed + +```puppet +stdlib::fqdn_rotate('abcd', 'custom seed') +``` + +##### `input` + +Data type: `String` + +The String you want rotated a random number of times + +##### `*seeds` + +Data type: `Optional[Variant[Integer,String]]` + +One of more values to use as a custom seed. These will be combined with the host's FQDN + +#### `stdlib::fqdn_rotate(Array $input, Optional[Variant[Integer,String]] *$seeds)` + +The stdlib::fqdn_rotate function. + +Returns: `Array` Returns the rotated Array + +##### Examples + +###### Rotating an Array + +```puppet +stdlib::fqdn_rotate(['a', 'b', 'c', 'd']) +``` + +###### Using custom seeds + +```puppet +stdlib::fqdn_rotate([1, 2, 3], 'custom', 'seed', 1) +``` + +##### `input` + +Data type: `Array` + +The Array you want rotated a random number of times + +##### `*seeds` + +Data type: `Optional[Variant[Integer,String]]` + +One of more values to use as a custom seed. These will be combined with the host's FQDN + +### `stdlib::has_function` + +Type: Ruby 4.x API + +Determines whether the Puppet runtime has access to a function by the +name provided. + +#### Examples + +##### Using stdlib::has_function() + +```puppet +stdlib::has_function('stdlib::has_function') # true +stdlib::has_function('not_a_function') # false +``` + +#### `stdlib::has_function(String[1] $function_name)` + +Determines whether the Puppet runtime has access to a function by the +name provided. + +Returns: `Boolean` + +##### Examples + +###### Using stdlib::has_function() + +```puppet +stdlib::has_function('stdlib::has_function') # true +stdlib::has_function('not_a_function') # false +``` + +##### `function_name` + +Data type: `String[1]` + + + +### `stdlib::has_interface_with` + +Type: Ruby 4.x API + +Can be called with one, or two arguments. + +#### `stdlib::has_interface_with(String[1] $interface)` + +The stdlib::has_interface_with function. + +Returns: `Boolean` Returns `true` if `interface` exists and `false` otherwise + +##### Examples + +###### When called with a single argument, the presence of the interface is checked + +```puppet +stdlib::has_interface_with('lo') # Returns `true` +``` + +##### `interface` + +Data type: `String[1]` + +The name of an interface + +#### `stdlib::has_interface_with(Enum['macaddress','netmask','ipaddress','network','ip','mac'] $kind, String[1] $value)` + +The stdlib::has_interface_with function. + +Returns: `Boolean` Returns `true` if any of the interfaces in the `networking` fact has a `kind` attribute with the value `value`. Otherwise returns `false` + +##### Examples + +###### Checking if an interface exists with a given mac address + +```puppet +stdlib::has_interface_with('macaddress', 'x:x:x:x:x:x') # Returns `false` +``` + +###### Checking if an interface exists with a given IP address + +```puppet +stdlib::has_interface_with('ipaddress', '127.0.0.1') # Returns `true` +``` + +##### `kind` + +Data type: `Enum['macaddress','netmask','ipaddress','network','ip','mac']` + +A supported interface attribute + +##### `value` + +Data type: `String[1]` + +The value of the attribute + +### `stdlib::has_ip_address` + +Type: Puppet Language + +Returns true if the client has the requested IPv4 address on some interface. + +#### `stdlib::has_ip_address(Stdlib::IP::Address::V4::Nosubnet $ip_address)` + +The stdlib::has_ip_address function. + +Returns: `Boolean` Returns `true` if the requested IP address exists on any interface. + +##### `ip_address` + +Data type: `Stdlib::IP::Address::V4::Nosubnet` + +The IPv4 address you want to check the existence of + +### `stdlib::has_ip_network` + +Type: Puppet Language + +Returns true if the client has the requested IPv4 network on some interface. + +#### `stdlib::has_ip_network(Stdlib::IP::Address::V4::Nosubnet $ip_network)` + +The stdlib::has_ip_network function. + +Returns: `Boolean` Returns `true` if the requested IP network exists on any interface. + +##### `ip_network` + +Data type: `Stdlib::IP::Address::V4::Nosubnet` + +The IPv4 network you want to check the existence of + +### `stdlib::ip_in_range` + +Type: Ruby 4.x API + +Returns true if the ipaddress is within the given CIDRs + +#### Examples + +##### ip_in_range(, ) + +```puppet +stdlib::ip_in_range('10.10.10.53', '10.10.10.0/24') => true +``` + +#### `stdlib::ip_in_range(String $ipaddress, Variant[String, Array] $range)` + +The stdlib::ip_in_range function. + +Returns: `Boolean` True or False + +##### Examples + +###### ip_in_range(, ) + +```puppet +stdlib::ip_in_range('10.10.10.53', '10.10.10.0/24') => true +``` + +##### `ipaddress` + +Data type: `String` + +The IP address to check + +##### `range` + +Data type: `Variant[String, Array]` + +One CIDR or an array of CIDRs +defining the range(s) to check against + +### `stdlib::merge` + +Type: Ruby 4.x API + +When there is a duplicate key, the key in the rightmost hash will "win." + +Note that since Puppet 4.0.0 the same merge can be achieved with the + operator. + `$merged_hash = $hash1 + $hash2` + +If stdlib::merge is given a single Iterable (Array, Hash, etc.) it will call a given block with +up to three parameters, and merge each resulting Hash into the accumulated result. All other types +of values returned from the block (typically undef) are skipped (not merged). + +The codeblock can take 2 or three parameters: +* with two, it gets the current hash (as built to this point), and each value (for hash the value is a [key, value] tuple) +* with three, it gets the current hash (as built to this point), the key/index of each value, and then the value + +If the iterable is empty, or no hash was returned from the given block, an empty hash is returned. In the given block, a call to `next()` +will skip that entry, and a call to `break()` will end the iteration. + +The iterative `stdlib::merge()` has an advantage over doing the same with a general `reduce()` in that the constructed hash +does not have to be copied in each iteration and thus will perform much better with large inputs. + +#### Examples + +##### Using stdlib::merge() + +```puppet +$hash1 = {'one' => 1, 'two', => 2} +$hash2 = {'two' => 'dos', 'three', => 'tres'} +$merged_hash = stdlib::merge($hash1, $hash2) # $merged_hash = {'one' => 1, 'two' => 'dos', 'three' => 'tres'} +``` + +##### counting occurrences of strings in an array + +```puppet +['a', 'b', 'c', 'c', 'd', 'b'].stdlib::merge | $hsh, $v | { { $v => $hsh[$v].lest || { 0 } + 1 } } # results in { a => 1, b => 2, c => 2, d => 1 } +``` + +##### skipping values for entries that are longer than 1 char + +```puppet +['a', 'b', 'c', 'c', 'd', 'b', 'blah', 'blah'].stdlib::merge | $hsh, $v | { if $v =~ String[1,1] { { $v => $hsh[$v].lest || { 0 } + 1 } } } # results in { a => 1, b => 2, c => 2, d => 1 } +``` + +#### `stdlib::merge(Variant[Hash[Scalar,Any], Undef, String[0,0]] *$args)` + +The stdlib::merge function. + +Returns: `Hash[Scalar,Any]` The merged hash + +##### `*args` + +Data type: `Variant[Hash[Scalar,Any], Undef, String[0,0]]` + +Repeated Param - The hashes that are to be merged + +#### `stdlib::merge(Iterable *$args, Callable[3,3] &$block)` + +The stdlib::merge function. + +Returns: `Hash` The merged hash + +##### `*args` + +Data type: `Iterable` + +Repeated Param - The hashes that are to be merged + +##### `&block` + +Data type: `Callable[3,3]` + +A block placed on the repeatable param `args` + +#### `stdlib::merge(Iterable *$args, Callable[2,2] &$block)` + +The stdlib::merge function. + +Returns: `Hash` The merged hash + +##### `*args` + +Data type: `Iterable` + +Repeated Param - The hashes that are to be merged + +##### `&block` + +Data type: `Callable[2,2]` + +A block placed on the repeatable param `args` + +### `stdlib::nested_values` + +Type: Ruby 4.x API + +Get list of nested values from given hash +This function will return list of nested Hash values and returns list of values in form of Array + +#### Examples + +##### Example Usage: + +```puppet +$hash = { + "key1" => "value1", + "key2" => { "key2.1" => "value2.1"}, + "key3" => "value3" +} +$data = $hash.stdlib::nested_values +#Output : ["value1", "value2.1", "value3"] +``` + +#### `stdlib::nested_values(Hash $hash)` + +The stdlib::nested_values function. + +Returns: `Array` All the values found in the input hash included those deeply nested. + +##### Examples + +###### Example Usage: + +```puppet +$hash = { + "key1" => "value1", + "key2" => { "key2.1" => "value2.1"}, + "key3" => "value3" +} +$data = $hash.stdlib::nested_values +#Output : ["value1", "value2.1", "value3"] +``` + +##### `hash` + +Data type: `Hash` + +A (nested) hash + +### `stdlib::os_version_gte` + +Type: Ruby 4.x API + +> *Note:* +Only the major version is taken into account. + +#### Examples + +##### Example usage:# + +```puppet +if stdlib::os_version_gte('Debian', '9') { } +if stdlib::os_version_gte('Ubuntu', '18.04') { } +``` + +#### `stdlib::os_version_gte(String[1] $os, String[1] $version)` + +> *Note:* +Only the major version is taken into account. + +Returns: `Boolean` `true` or `false + +##### Examples + +###### Example usage:# + +```puppet +if stdlib::os_version_gte('Debian', '9') { } +if stdlib::os_version_gte('Ubuntu', '18.04') { } +``` + +##### `os` + +Data type: `String[1]` + +operating system + +##### `version` + +Data type: `String[1]` + + + +### `stdlib::parsehocon` + +Type: Ruby 4.x API + +This function accepts HOCON as a string and converts it into the correct +Puppet structure + +#### Examples + +##### How to parse hocon + +```puppet +$data = stdlib::parsehocon("{any valid hocon: string}") +``` + +#### `stdlib::parsehocon(String $hocon_string, Optional[Any] $default)` + +The stdlib::parsehocon function. + +Returns: `Data` + +##### Examples + +###### How to parse hocon + +```puppet +$data = stdlib::parsehocon("{any valid hocon: string}") +``` + +##### `hocon_string` + +Data type: `String` + +A valid HOCON string + +##### `default` + +Data type: `Optional[Any]` + +An optional default to return if parsing hocon_string fails + +### `stdlib::powershell_escape` + +Type: Ruby 4.x API + +>* Note:* that the resulting string should be used unquoted and is not intended for use in double quotes nor in single +quotes. + +#### `stdlib::powershell_escape(Any $string)` + +>* Note:* that the resulting string should be used unquoted and is not intended for use in double quotes nor in single +quotes. + +Returns: `Any` An escaped string that can be safely used in a PowerShell command line. + +##### `string` + +Data type: `Any` + +The string to escape + +### `stdlib::seeded_rand` + +Type: Ruby 4.x API + +Generates a random whole number greater than or equal to 0 and less than max, using the value of seed for repeatable randomness. + +#### `stdlib::seeded_rand(Integer[1] $max, String $seed)` + +The stdlib::seeded_rand function. + +Returns: `Integer` A random number greater than or equal to 0 and less than max + +##### `max` + +Data type: `Integer[1]` + +The maximum value. + +##### `seed` + +Data type: `String` + +The seed used for repeatable randomness. + +### `stdlib::seeded_rand_string` + +Type: Ruby 4.x API + +Generates a consistent random string of specific length based on provided seed. + +#### Examples + +##### Generate a consistently random string of length 8 with a seed: + +```puppet +stdlib::seeded_rand_string(8, "${module_name}::redis_password") +``` + +##### Generate a random string from a specific set of characters: + +```puppet +stdlib::seeded_rand_string(5, '', 'abcdef') +``` + +#### `stdlib::seeded_rand_string(Integer[1] $length, String $seed, Optional[String[2]] $charset)` + +The stdlib::seeded_rand_string function. + +Returns: `String` Random string. + +##### Examples + +###### Generate a consistently random string of length 8 with a seed: + +```puppet +stdlib::seeded_rand_string(8, "${module_name}::redis_password") +``` + +###### Generate a random string from a specific set of characters: + +```puppet +stdlib::seeded_rand_string(5, '', 'abcdef') +``` + +##### `length` + +Data type: `Integer[1]` + +Length of string to be generated. + +##### `seed` + +Data type: `String` + +Seed string. + +##### `charset` + +Data type: `Optional[String[2]]` + +String that contains characters to use for the random string. + +### `stdlib::sha256` + +Type: Ruby 4.x API + +Run a SHA256 calculation against a given value. + +#### Examples + +##### Check a simple string value + +```puppet +stdlib::sha256('my string') == '2f7e2089add0288a309abd71ffcc3b3567e2d4215e20e6ed3b74d6042f7ef8e5' +``` + +##### Check a Sensitive datatype + +```puppet +stdlib::sha256(sensitive('my string')) == '2f7e2089add0288a309abd71ffcc3b3567e2d4215e20e6ed3b74d6042f7ef8e5' +``` + +##### Check a number + +```puppet +stdlib::sha256(100.0) == '43b87f618caab482ebe4976c92bcd6ad308b48055f1c27b4c574f3e31d7683e0' +stdlib::sha256(100.00000) == '43b87f618caab482ebe4976c92bcd6ad308b48055f1c27b4c574f3e31d7683e0' +``` + +#### `stdlib::sha256(Variant[ScalarData, Sensitive[ScalarData], Binary, Sensitive[Binary]] $my_data)` + +Run a SHA256 calculation against a given value. + +Returns: `String` String + +##### Examples + +###### Check a simple string value + +```puppet +stdlib::sha256('my string') == '2f7e2089add0288a309abd71ffcc3b3567e2d4215e20e6ed3b74d6042f7ef8e5' +``` + +###### Check a Sensitive datatype + +```puppet +stdlib::sha256(sensitive('my string')) == '2f7e2089add0288a309abd71ffcc3b3567e2d4215e20e6ed3b74d6042f7ef8e5' +``` + +###### Check a number + +```puppet +stdlib::sha256(100.0) == '43b87f618caab482ebe4976c92bcd6ad308b48055f1c27b4c574f3e31d7683e0' +stdlib::sha256(100.00000) == '43b87f618caab482ebe4976c92bcd6ad308b48055f1c27b4c574f3e31d7683e0' +``` + +##### `my_data` + +Data type: `Variant[ScalarData, Sensitive[ScalarData], Binary, Sensitive[Binary]]` + +The ScalarData to evaluate + +### `stdlib::shell_escape` + +Type: Ruby 4.x API + +>* Note:* that the resulting string should be used unquoted and is not intended for use in double quotes nor in single +quotes. + +This function behaves the same as ruby's Shellwords.shellescape() function. + +#### `stdlib::shell_escape(Any $string)` + +>* Note:* that the resulting string should be used unquoted and is not intended for use in double quotes nor in single +quotes. + +This function behaves the same as ruby's Shellwords.shellescape() function. + +Returns: `Any` An escaped string that can be safely used in a Bourne shell command line. + +##### `string` + +Data type: `Any` + +The string to escape + +### `stdlib::sort_by` + +Type: Ruby 4.x API + +Sort an Array, Hash or String by mapping values through a given block. + +#### Examples + +##### Sort local devices according to their used space. + +```puppet +$facts['mountpoints'].stdlib::sort_by |$m| { $m.dig(1, 'used_bytes') } +``` + +#### `stdlib::sort_by(Array $ary, Callable[1,1] &$block)` + +The stdlib::sort_by function. + +Returns: `Array` Returns an ordered copy of ary. + +##### `ary` + +Data type: `Array` + +The Array to sort. + +##### `&block` + +Data type: `Callable[1,1]` + +The block for transforming elements of ary. + +#### `stdlib::sort_by(String $str, Callable[1,1] &$block)` + +The stdlib::sort_by function. + +Returns: `String` Returns an ordered copy of str. + +##### `str` + +Data type: `String` + +The String to sort. + +##### `&block` + +Data type: `Callable[1,1]` + +The block for transforming elements of str. + +#### `stdlib::sort_by(Hash $hsh, Variant[Callable[1,1], Callable[2,2]] &$block)` + +The stdlib::sort_by function. + +Returns: `Hash` Returns an ordered copy of hsh. + +##### `hsh` + +Data type: `Hash` + +The Hash to sort. + +##### `&block` + +Data type: `Variant[Callable[1,1], Callable[2,2]]` + +The block for transforming elements of hsh. +The block may have arity of one or two. + +### `stdlib::start_with` + +Type: Ruby 4.x API + +Returns true if str starts with one of the prefixes given. Each of the prefixes should be a String. + +#### Examples + +##### + +```puppet +'foobar'.stdlib::start_with('foo') => true +'foobar'.stdlib::start_with('bar') => false +'foObar'.stdlib::start_with(['bar', 'baz']) => false +``` + +#### `stdlib::start_with(String $test_string, Variant[String[1],Array[String[1], 1]] $prefixes)` + +The stdlib::start_with function. + +Returns: `Boolean` True or False + +##### Examples + +###### + +```puppet +'foobar'.stdlib::start_with('foo') => true +'foobar'.stdlib::start_with('bar') => false +'foObar'.stdlib::start_with(['bar', 'baz']) => false +``` + +##### `test_string` + +Data type: `String` + +The string to check + +##### `prefixes` + +Data type: `Variant[String[1],Array[String[1], 1]]` + +The prefixes to check. + +### `stdlib::str2resource` + +Type: Ruby 4.x API + +This attempts to convert a string like 'File[/foo]' into the +puppet resource `File['/foo']` as detected by the catalog. + +Things like 'File[/foo, /bar]' are not supported as a +title might contain things like ',' or ' '. There is +no clear value seperator to use. + +This function can depend on the parse order of your +manifests/modules as it inspects the catalog thus far. + +#### Examples + +##### + +```puppet +stdlib::str2resource('File[/foo]') => File[/foo] +``` + +#### `stdlib::str2resource(String $res_string)` + +This attempts to convert a string like 'File[/foo]' into the +puppet resource `File['/foo']` as detected by the catalog. + +Things like 'File[/foo, /bar]' are not supported as a +title might contain things like ',' or ' '. There is +no clear value seperator to use. + +This function can depend on the parse order of your +manifests/modules as it inspects the catalog thus far. + +Returns: `Any` Puppet::Resource + +##### Examples + +###### + +```puppet +stdlib::str2resource('File[/foo]') => File[/foo] +``` + +##### `res_string` + +Data type: `String` + +The string to lookup as a resource + +### `stdlib::time` + +Type: Puppet Language + +It is provided for compatability, but users should use the native time related functions directly. + +#### `stdlib::time(Optional[String] $_timezone = undef)` + +It is provided for compatability, but users should use the native time related functions directly. + +Returns: `Integer` + +##### `_timezone` + +Data type: `Optional[String]` + +This parameter doesn't do anything, but exists for compatability reasons + +### `stdlib::to_json` + +Type: Ruby 4.x API + +Convert a data structure and output to JSON + +#### Examples + +##### Output JSON to a file + +```puppet +file { '/tmp/my.json': + ensure => file, + content => stdlib::to_json($myhash), +} +``` + +#### `stdlib::to_json(Any $data)` + +Convert a data structure and output to JSON + +Returns: `String` Converted data to JSON + +##### Examples + +###### Output JSON to a file + +```puppet +file { '/tmp/my.json': + ensure => file, + content => stdlib::to_json($myhash), +} +``` + +##### `data` + +Data type: `Any` + +Data structure which needs to be converted into JSON + +### `stdlib::to_json_pretty` + +Type: Ruby 4.x API + +Convert data structure and output to pretty JSON + +#### Examples + +##### **Usage** + +```puppet +* how to output pretty JSON to file + file { '/tmp/my.json': + ensure => file, + content => stdlib::to_json_pretty($myhash), + } + +* how to output pretty JSON skipping over keys with undef values + file { '/tmp/my.json': + ensure => file, + content => stdlib::to_json_pretty({ + param_one => 'value', + param_two => undef, + }, true), + } + +* how to output pretty JSON using tabs for indentation + file { '/tmp/my.json': + ensure => file, + content => stdlib::to_json_pretty({ + param_one => 'value', + param_two => { + param_more => 42, + }, + }, nil, {indent => ' '}), + } +``` + +#### `stdlib::to_json_pretty(Variant[Hash, Array] $data, Optional[Optional[Boolean]] $skip_undef, Optional[Struct[{ +indent => Optional[String], +space => Optional[String], +space_before => Optional[String], +object_nl => Optional[String], +array_nl => Optional[String], +allow_nan => Optional[Boolean], +max_nesting => Optional[Integer[-1,default]], +}]] $opts)` + +The stdlib::to_json_pretty function. + +Returns: `Any` converted data to pretty json + +##### Examples + +###### **Usage** + +```puppet +* how to output pretty JSON to file + file { '/tmp/my.json': + ensure => file, + content => stdlib::to_json_pretty($myhash), + } + +* how to output pretty JSON skipping over keys with undef values + file { '/tmp/my.json': + ensure => file, + content => stdlib::to_json_pretty({ + param_one => 'value', + param_two => undef, + }, true), + } + +* how to output pretty JSON using tabs for indentation + file { '/tmp/my.json': + ensure => file, + content => stdlib::to_json_pretty({ + param_one => 'value', + param_two => { + param_more => 42, + }, + }, nil, {indent => ' '}), + } +``` + +##### `data` + +Data type: `Variant[Hash, Array]` + +data structure which needs to be converted to pretty json + +##### `skip_undef` + +Data type: `Optional[Optional[Boolean]]` + +value `true` or `false` + +##### `opts` + +Data type: + +```puppet +Optional[Struct[{ +indent => Optional[String], +space => Optional[String], +space_before => Optional[String], +object_nl => Optional[String], +array_nl => Optional[String], +allow_nan => Optional[Boolean], +max_nesting => Optional[Integer[-1,default]], +}]] +``` + +hash-map of settings passed to JSON.pretty_generate, see +https://ruby-doc.org/stdlib-2.0.0/libdoc/json/rdoc/JSON.html#method-i-generate. +Note that `max_nesting` doesn't take the value `false`; use `-1` instead. + +### `stdlib::to_python` + +Type: Ruby 4.x API + +Convert an object into a String containing its Python representation + +#### Examples + +##### how to output Python + +```puppet +# output Python to a file +$listen = '0.0.0.0' +$port = 8000 +file { '/opt/acme/etc/settings.py': + content => inline_epp(@("SETTINGS")), + LISTEN = <%= stdlib::to_python($listen) %> + PORT = <%= stdlib::to_python($mailserver) %> + | SETTINGS +} +``` + +#### `stdlib::to_python(Any $object)` + +The stdlib::to_python function. + +Returns: `String` The String representation of the object + +##### Examples + +###### how to output Python + +```puppet +# output Python to a file +$listen = '0.0.0.0' +$port = 8000 +file { '/opt/acme/etc/settings.py': + content => inline_epp(@("SETTINGS")), + LISTEN = <%= stdlib::to_python($listen) %> + PORT = <%= stdlib::to_python($mailserver) %> + | SETTINGS +} +``` + +##### `object` + +Data type: `Any` + +The object to be converted + +### `stdlib::to_ruby` + +Type: Ruby 4.x API + +Convert an object into a String containing its Ruby representation + +#### Examples + +##### how to output Ruby + +```puppet +# output Ruby to a file +$listen = '0.0.0.0' +$port = 8000 +file { '/opt/acme/etc/settings.rb': + content => inline_epp(@("SETTINGS")), + LISTEN = <%= stdlib::to_ruby($listen) %> + PORT = <%= stdlib::to_ruby($mailserver) %> + | SETTINGS +} +``` + +#### `stdlib::to_ruby(Any $object)` + +The stdlib::to_ruby function. + +Returns: `String` The String representation of the object + +##### Examples + +###### how to output Ruby + +```puppet +# output Ruby to a file +$listen = '0.0.0.0' +$port = 8000 +file { '/opt/acme/etc/settings.rb': + content => inline_epp(@("SETTINGS")), + LISTEN = <%= stdlib::to_ruby($listen) %> + PORT = <%= stdlib::to_ruby($mailserver) %> + | SETTINGS +} +``` + +##### `object` + +Data type: `Any` + +The object to be converted + +### `stdlib::to_toml` + +Type: Ruby 4.x API + +Convert a data structure and output to TOML. + +#### Examples + +##### How to output TOML to a file + +```puppet +file { '/tmp/config.toml': + ensure => file, + content => stdlib::to_toml($myhash), +} +``` + +#### `stdlib::to_toml(Hash $data)` + +The stdlib::to_toml function. + +Returns: `String` Converted data as TOML string + +##### Examples + +###### How to output TOML to a file + +```puppet +file { '/tmp/config.toml': + ensure => file, + content => stdlib::to_toml($myhash), +} +``` + +##### `data` + +Data type: `Hash` + +Data structure which needs to be converted into TOML + +### `stdlib::to_yaml` + +Type: Ruby 4.x API + +Convert a data structure and output it as YAML + +#### Examples + +##### Output YAML to a file + +```puppet +file { '/tmp/my.yaml': + ensure => file, + content => stdlib::to_yaml($myhash), +} +``` + +##### Use options to control the output format + +```puppet +file { '/tmp/my.yaml': + ensure => file, + content => stdlib::to_yaml($myhash, {indentation => 4}) +} +``` + +#### `stdlib::to_yaml(Any $data, Optional[Hash] $options)` + +Convert a data structure and output it as YAML + +Returns: `String` The YAML document + +##### Examples + +###### Output YAML to a file + +```puppet +file { '/tmp/my.yaml': + ensure => file, + content => stdlib::to_yaml($myhash), +} +``` + +###### Use options to control the output format + +```puppet +file { '/tmp/my.yaml': + ensure => file, + content => stdlib::to_yaml($myhash, {indentation => 4}) +} +``` + +##### `data` + +Data type: `Any` + +The data you want to convert to YAML + +##### `options` + +Data type: `Optional[Hash]` + +A hash of options that will be passed to Ruby's Psych library. Note, this could change between Puppet versions, but at time of writing these are `line_width`, `indentation`, and `canonical`. + +### `stdlib::type_of` + +Type: Ruby 4.x API + +See the documentation for "The Puppet Type System" for more information about types. +See the `assert_type()` function for flexible ways to assert the type of a value. + +The built-in type() function in puppet is generally preferred over this function +this function is provided for backwards compatibility. + +#### Examples + +##### how to compare values' types + +```puppet +# compare the types of two values +if stdlib::type_of($first_value) != stdlib::type_of($second_value) { fail("first_value and second_value are different types") } +``` + +##### how to compare against an abstract type + +```puppet +unless stdlib::type_of($first_value) <= Numeric { fail("first_value must be Numeric") } +unless stdlib::type_of{$first_value) <= Collection[1] { fail("first_value must be an Array or Hash, and contain at least one element") } +``` + +#### `stdlib::type_of(Any $value)` + +See the documentation for "The Puppet Type System" for more information about types. +See the `assert_type()` function for flexible ways to assert the type of a value. + +The built-in type() function in puppet is generally preferred over this function +this function is provided for backwards compatibility. + +Returns: `String` the type of the passed value + +##### Examples + +###### how to compare values' types + +```puppet +# compare the types of two values +if stdlib::type_of($first_value) != stdlib::type_of($second_value) { fail("first_value and second_value are different types") } +``` + +###### how to compare against an abstract type + +```puppet +unless stdlib::type_of($first_value) <= Numeric { fail("first_value must be Numeric") } +unless stdlib::type_of{$first_value) <= Collection[1] { fail("first_value must be an Array or Hash, and contain at least one element") } +``` + +##### `value` + +Data type: `Any` + + + +### `stdlib::validate_domain_name` + +Type: Ruby 4.x API + +Validate that all values passed are syntactically correct domain names. +Fail compilation if any value fails this check. + +#### Examples + +##### Passing examples + +```puppet +$my_domain_name = 'server.domain.tld' +stdlib::validate_domain_name($my_domain_name) +stdlib::validate_domain_name('domain.tld', 'puppet.com', $my_domain_name) +stdlib::validate_domain_name('www.example.2com') +``` + +##### Failing examples (causing compilation to abort) + +```puppet +stdlib::validate_domain_name(1) +stdlib::validate_domain_name(true) +stdlib::validate_domain_name('invalid domain') +stdlib::validate_domain_name('-foo.example.com') +``` + +#### `stdlib::validate_domain_name(Variant[Stdlib::Fqdn, Stdlib::Dns::Zone] *$values)` + +The stdlib::validate_domain_name function. + +Returns: `Undef` passes when the given values are syntactically correct domain names or raise an error when they are not and fails compilation + +##### Examples + +###### Passing examples + +```puppet +$my_domain_name = 'server.domain.tld' +stdlib::validate_domain_name($my_domain_name) +stdlib::validate_domain_name('domain.tld', 'puppet.com', $my_domain_name) +stdlib::validate_domain_name('www.example.2com') +``` + +###### Failing examples (causing compilation to abort) + +```puppet +stdlib::validate_domain_name(1) +stdlib::validate_domain_name(true) +stdlib::validate_domain_name('invalid domain') +stdlib::validate_domain_name('-foo.example.com') +``` + +##### `*values` + +Data type: `Variant[Stdlib::Fqdn, Stdlib::Dns::Zone]` + +A domain name or an array of domain names to check + +### `stdlib::validate_email_address` + +Type: Ruby 4.x API + +Validate that all values passed are valid email addresses. +Fail compilation if any value fails this check. + +#### Examples + +##### Passing examples + +```puppet +$my_email = "waldo@gmail.com" +stdlib::validate_email_address($my_email) +stdlib::validate_email_address("bob@gmail.com", "alice@gmail.com", $my_email) +``` + +##### Failing examples (causing compilation to abort) + +```puppet +$some_array = [ 'bad_email@/d/efdf.com' ] +stdlib::validate_email_address($some_array) +``` + +#### `stdlib::validate_email_address(Stdlib::Email *$values)` + +The stdlib::validate_email_address function. + +Returns: `Undef` Fail compilation if any value fails this check. + +##### Examples + +###### Passing examples + +```puppet +$my_email = "waldo@gmail.com" +stdlib::validate_email_address($my_email) +stdlib::validate_email_address("bob@gmail.com", "alice@gmail.com", $my_email) +``` + +###### Failing examples (causing compilation to abort) + +```puppet +$some_array = [ 'bad_email@/d/efdf.com' ] +stdlib::validate_email_address($some_array) +``` + +##### `*values` + +Data type: `Stdlib::Email` + +An e-mail address or an array of e-mail addresses to check + +### `stdlib::xml_encode` + +Type: Ruby 4.x API + +This function can encode strings such that they can be used directly in XML files. +It supports encoding for both XML text (CharData) or attribute values (AttValue). + +#### Examples + +##### Creating an XML file from a template + +```puppet +file { '/path/to/config.xml': + ensure => file, + content => epp( + 'mymodule/config.xml.epp', + { + password => $password.stdlib::xml_encode, + }, + ), +} +``` + +#### `stdlib::xml_encode(String $str, Optional[Enum['text','attr']] $type)` + +This function can encode strings such that they can be used directly in XML files. +It supports encoding for both XML text (CharData) or attribute values (AttValue). + +Returns: `String` Returns the encoded CharData or AttValue string suitable for use in XML + +##### Examples + +###### Creating an XML file from a template + +```puppet +file { '/path/to/config.xml': + ensure => file, + content => epp( + 'mymodule/config.xml.epp', + { + password => $password.stdlib::xml_encode, + }, + ), +} +``` + +##### `str` + +Data type: `String` + +The string to encode + +##### `type` + +Data type: `Optional[Enum['text','attr']]` + +Whether to encode for text or an attribute + +### `str2bool` + +Type: Ruby 3.x API + +> *Note:* that since Puppet 5.0.0 the Boolean data type can convert strings to a Boolean value. +See the function new() in Puppet for details what the Boolean data type supports. + +#### `str2bool()` + +> *Note:* that since Puppet 5.0.0 the Boolean data type can convert strings to a Boolean value. +See the function new() in Puppet for details what the Boolean data type supports. + +Returns: `Any` This attempt to convert to boolean strings that contain things like: Y,y, 1, T,t, TRUE,true to 'true' and strings that contain things +like: 0, F,f, N,n, false, FALSE, no to 'false'. + +### `str2saltedpbkdf2` + +Type: Ruby 3.x API + +Convert a string into a salted SHA512 PBKDF2 password hash like requred for OS X / macOS 10.8+. +Note, however, that Apple changes what's required periodically and this may not work for the latest +version of macOS. If that is the case you should get a helpful error message when Puppet tries to set +the pasword using the parameters you provide to the user resource. + +#### Examples + +##### Plain text password and salt + +```puppet +$pw_info = str2saltedpbkdf2('Pa55w0rd', 'Use a s@lt h3r3 th@t is 32 byt3s', 50000) +user { 'jdoe': + ensure => present, + iterations => $pw_info['interations'], + password => $pw_info['password_hex'], + salt => $pw_info['salt_hex'], +} +``` + +##### Sensitive password and salt + +```puppet +$pw = Sensitive.new('Pa55w0rd') +$salt = Sensitive.new('Use a s@lt h3r3 th@t is 32 byt3s') +$pw_info = Sensitive.new(str2saltedpbkdf2($pw, $salt, 50000)) +user { 'jdoe': + ensure => present, + iterations => unwrap($pw_info)['interations'], + password => unwrap($pw_info)['password_hex'], + salt => unwrap($pw_info)['salt_hex'], +} +``` + +#### `str2saltedpbkdf2()` + +Convert a string into a salted SHA512 PBKDF2 password hash like requred for OS X / macOS 10.8+. +Note, however, that Apple changes what's required periodically and this may not work for the latest +version of macOS. If that is the case you should get a helpful error message when Puppet tries to set +the pasword using the parameters you provide to the user resource. + +Returns: `Hash` Provides a hash containing the hex version of the password, the hex version of the salt, and iterations. + +##### Examples + +###### Plain text password and salt + +```puppet +$pw_info = str2saltedpbkdf2('Pa55w0rd', 'Use a s@lt h3r3 th@t is 32 byt3s', 50000) +user { 'jdoe': + ensure => present, + iterations => $pw_info['interations'], + password => $pw_info['password_hex'], + salt => $pw_info['salt_hex'], +} +``` + +###### Sensitive password and salt + +```puppet +$pw = Sensitive.new('Pa55w0rd') +$salt = Sensitive.new('Use a s@lt h3r3 th@t is 32 byt3s') +$pw_info = Sensitive.new(str2saltedpbkdf2($pw, $salt, 50000)) +user { 'jdoe': + ensure => present, + iterations => unwrap($pw_info)['interations'], + password => unwrap($pw_info)['password_hex'], + salt => unwrap($pw_info)['salt_hex'], +} +``` + +### `str2saltedsha512` + +Type: Ruby 3.x API + +Given any simple string, you will get a hex version +of a salted-SHA512 password hash that can be inserted into your Puppet +manifests as a valid password attribute. + +#### `str2saltedsha512()` + +Given any simple string, you will get a hex version +of a salted-SHA512 password hash that can be inserted into your Puppet +manifests as a valid password attribute. + +Returns: `Any` converted string as a hex version of a salted-SHA512 password hash + +### `suffix` + +Type: Ruby 3.x API + +> *Note:* that since Puppet 4.0.0 the general way to modify values is in array is by using the map +function in Puppet. This example does the same as the example above: + +```['a', 'b', 'c'].map |$x| { "${x}p" }``` + +#### Examples + +##### **Usage** + +```puppet + +suffix(['a','b','c'], 'p') +Will return: ['ap','bp','cp'] +``` + +#### `suffix()` + +> *Note:* that since Puppet 4.0.0 the general way to modify values is in array is by using the map +function in Puppet. This example does the same as the example above: + +```['a', 'b', 'c'].map |$x| { "${x}p" }``` + +Returns: `Any` Array or Hash with updated elements containing the passed suffix + +##### Examples + +###### **Usage** + +```puppet + +suffix(['a','b','c'], 'p') +Will return: ['ap','bp','cp'] +``` + +### `swapcase` + +Type: Ruby 3.x API + +This function will swap the existing case of a string. + +#### Examples + +##### **Usage** + +```puppet + +swapcase("aBcD") +Would result in: "AbCd" +``` + +#### `swapcase()` + +The swapcase function. + +Returns: `Any` string with uppercase alphabetic characters converted to lowercase and lowercase characters converted to uppercase + +##### Examples + +###### **Usage** + +```puppet + +swapcase("aBcD") +Would result in: "AbCd" +``` + +### `time` + +Type: Ruby 4.x API + +DEPRECATED. Use the native Puppet fuctionality instead of this function. eg `Integer(Timestamp().strftime('%s'))` + +#### `time(Any *$args)` + +The time function. + +Returns: `Any` + +##### `*args` + +Data type: `Any` + + + +### `to_bytes` + +Type: Ruby 3.x API + +Takes a single string value as an argument. +These conversions reflect a layperson's understanding of +1 MB = 1024 KB, when in fact 1 MB = 1000 KB, and 1 MiB = 1024 KiB. + +#### `to_bytes()` + +Takes a single string value as an argument. +These conversions reflect a layperson's understanding of +1 MB = 1024 KB, when in fact 1 MB = 1000 KB, and 1 MiB = 1024 KiB. + +Returns: `Any` converted value into bytes + +### `to_json` + +Type: Ruby 4.x API + +DEPRECATED. Use the namespaced function [`stdlib::to_json`](#stdlibto_json) instead. + +#### `to_json(Any *$args)` + +The to_json function. + +Returns: `Any` + +##### `*args` + +Data type: `Any` + + + +### `to_json_pretty` + +Type: Ruby 4.x API + +DEPRECATED. Use the namespaced function [`stdlib::to_json_pretty`](#stdlibto_json_pretty) instead. + +#### `to_json_pretty(Any *$args)` + +The to_json_pretty function. + +Returns: `Any` + +##### `*args` + +Data type: `Any` + + + +### `to_python` + +Type: Ruby 4.x API + +DEPRECATED. Use the namespaced function [`stdlib::to_python`](#stdlibto_python) instead. + +#### `to_python(Any *$args)` + +The to_python function. + +Returns: `Any` + +##### `*args` + +Data type: `Any` + + + +### `to_ruby` + +Type: Ruby 4.x API + +DEPRECATED. Use the namespaced function [`stdlib::to_ruby`](#stdlibto_ruby) instead. + +#### `to_ruby(Any *$args)` + +The to_ruby function. + +Returns: `Any` + +##### `*args` + +Data type: `Any` + + + +### `to_toml` + +Type: Ruby 4.x API + +DEPRECATED. Use the namespaced function [`stdlib::to_toml`](#stdlibto_toml) instead. + +#### `to_toml(Any *$args)` + +The to_toml function. + +Returns: `Any` + +##### `*args` + +Data type: `Any` + + + +### `to_yaml` + +Type: Ruby 4.x API + +DEPRECATED. Use the namespaced function [`stdlib::to_yaml`](#stdlibto_yaml) instead. + +#### `to_yaml(Any *$args)` + +The to_yaml function. + +Returns: `Any` + +##### `*args` + +Data type: `Any` + + + +### `type_of` + +Type: Ruby 4.x API + +DEPRECATED. Use the namespaced function [`stdlib::type_of`](#stdlibtype_of) instead. + +#### `type_of(Any *$args)` + +The type_of function. + +Returns: `Any` + +##### `*args` + +Data type: `Any` + + + +### `union` + +Type: Ruby 3.x API + +This function returns a union of two or more arrays. + +#### Examples + +##### **Usage** + +```puppet + +union(["a","b","c"],["b","c","d"]) +Would return: ["a","b","c","d"] +``` + +#### `union()` + +The union function. + +Returns: `Any` a unionized array of two or more arrays + +##### Examples + +###### **Usage** + +```puppet + +union(["a","b","c"],["b","c","d"]) +Would return: ["a","b","c","d"] +``` + +### `unix2dos` + +Type: Ruby 3.x API + +Takes a single string argument. + +#### `unix2dos()` + +Takes a single string argument. + +Returns: `Any` the DOS version of the given string. + +### `uriescape` + +Type: Ruby 3.x API + +> **Note:** **Deprecated:** Starting Puppet 8, our Ruby version has upgraded to 3.2. +Therefore, its no longer possible to call URI.escape as it was deprecated by 2.7 and removed completely by 3+. +This function should be removed once Puppet 7 is no longer supported. + +#### `uriescape()` + +> **Note:** **Deprecated:** Starting Puppet 8, our Ruby version has upgraded to 3.2. +Therefore, its no longer possible to call URI.escape as it was deprecated by 2.7 and removed completely by 3+. +This function should be removed once Puppet 7 is no longer supported. + +Returns: `String` a string that contains the converted value + +### `validate_augeas` + +Type: Ruby 3.x API + +The first argument of this function should be a string to +test, and the second argument should be the name of the Augeas lens to use. +If Augeas fails to parse the string with the lens, the compilation will +abort with a parse error. + +A third argument can be specified, listing paths which should +not be found in the file. The `$file` variable points to the location +of the temporary file being tested in the Augeas tree. + +#### Examples + +##### **Usage** + +```puppet + +If you want to make sure your passwd content never contains +a user `foo`, you could write: + + validate_augeas($passwdcontent, 'Passwd.lns', ['$file/foo']) + +If you wanted to ensure that no users used the '/bin/barsh' shell, +you could use: + + validate_augeas($passwdcontent, 'Passwd.lns', ['$file/*[shell="/bin/barsh"]'] + +If a fourth argument is specified, this will be the error message raised and +seen by the user. + +A helpful error message can be returned like this: + + validate_augeas($sudoerscontent, 'Sudoers.lns', [], 'Failed to validate sudoers content with Augeas') +``` + +#### `validate_augeas()` + +The first argument of this function should be a string to +test, and the second argument should be the name of the Augeas lens to use. +If Augeas fails to parse the string with the lens, the compilation will +abort with a parse error. + +A third argument can be specified, listing paths which should +not be found in the file. The `$file` variable points to the location +of the temporary file being tested in the Augeas tree. + +Returns: `Any` validate string using an Augeas lens + +##### Examples + +###### **Usage** + +```puppet + +If you want to make sure your passwd content never contains +a user `foo`, you could write: + + validate_augeas($passwdcontent, 'Passwd.lns', ['$file/foo']) + +If you wanted to ensure that no users used the '/bin/barsh' shell, +you could use: + + validate_augeas($passwdcontent, 'Passwd.lns', ['$file/*[shell="/bin/barsh"]'] + +If a fourth argument is specified, this will be the error message raised and +seen by the user. + +A helpful error message can be returned like this: + + validate_augeas($sudoerscontent, 'Sudoers.lns', [], 'Failed to validate sudoers content with Augeas') +``` + +### `validate_cmd` + +Type: Ruby 3.x API + +The first argument of this function should be a string to +test, and the second argument should be a path to a test command +taking a % as a placeholder for the file path (will default to the end). +If the command, launched against a tempfile containing the passed string, +returns a non-null value, compilation will abort with a parse error. +If a third argument is specified, this will be the error message raised and +seen by the user. + +A helpful error message can be returned like this: + +#### Examples + +##### **Usage** + +```puppet + +Defaults to end of path + validate_cmd($sudoerscontent, '/usr/sbin/visudo -c -f', 'Visudo failed to validate sudoers content') + +% as file location + validate_cmd($haproxycontent, '/usr/sbin/haproxy -f % -c', 'Haproxy failed to validate config content') +``` + +#### `validate_cmd()` + +The first argument of this function should be a string to +test, and the second argument should be a path to a test command +taking a % as a placeholder for the file path (will default to the end). +If the command, launched against a tempfile containing the passed string, +returns a non-null value, compilation will abort with a parse error. +If a third argument is specified, this will be the error message raised and +seen by the user. + +A helpful error message can be returned like this: + +Returns: `Any` validate of a string with an external command + +##### Examples + +###### **Usage** + +```puppet + +Defaults to end of path + validate_cmd($sudoerscontent, '/usr/sbin/visudo -c -f', 'Visudo failed to validate sudoers content') + +% as file location + validate_cmd($haproxycontent, '/usr/sbin/haproxy -f % -c', 'Haproxy failed to validate config content') +``` + +### `validate_domain_name` + +Type: Ruby 4.x API + +DEPRECATED. Use the namespaced function [`stdlib::validate_domain_name`](#stdlibvalidate_domain_name) instead. + +#### `validate_domain_name(Any *$args)` + +The validate_domain_name function. + +Returns: `Any` + +##### `*args` + +Data type: `Any` + + + +### `validate_email_address` + +Type: Ruby 4.x API + +DEPRECATED. Use the namespaced function [`stdlib::validate_email_address`](#stdlibvalidate_email_address) instead. + +#### `validate_email_address(Any *$args)` + +The validate_email_address function. + +Returns: `Any` + +##### `*args` + +Data type: `Any` + + + +### `validate_legacy` + +Type: Ruby 4.x API + +**Deprecated:** Validate a value against both the target_type (new). + +#### `validate_legacy(Any $scope, Type $target_type, String $function_name, Any $value, Any *$args)` + +The function checks a value against both the target_type (new). + +Returns: `Any` A boolean value (`true` or `false`) returned from the called function. + +##### `scope` + +Data type: `Any` + +The main value that will be passed to the method + +##### `target_type` + +Data type: `Type` + + + +##### `function_name` + +Data type: `String` + +Unused + +##### `value` + +Data type: `Any` + + + +##### `*args` + +Data type: `Any` + +Any additional values that are to be passed to the method + +#### `validate_legacy(Any $scope, String $type_string, String $function_name, Any $value, Any *$args)` + +The validate_legacy function. + +Returns: `Any` Legacy validation method + +##### `scope` + +Data type: `Any` + +The main value that will be passed to the method + +##### `type_string` + +Data type: `String` + + + +##### `function_name` + +Data type: `String` + +Unused + +##### `value` + +Data type: `Any` + + + +##### `*args` + +Data type: `Any` + +Any additional values that are to be passed to the method + +### `validate_x509_rsa_key_pair` + +Type: Ruby 3.x API + +Verifies that the certficate's signature was created from the +supplied key. + +```validate_x509_rsa_key_pair($cert, $key)``` + +#### `validate_x509_rsa_key_pair()` + +Verifies that the certficate's signature was created from the +supplied key. + +```validate_x509_rsa_key_pair($cert, $key)``` + +Returns: `Any` Fail compilation if any value fails this check. + +### `values_at` + +Type: Ruby 3.x API + +The first argument is the array you want to analyze, and the second element can +be a combination of: + +* A single numeric index +* A range in the form of 'start-stop' (eg. 4-9) +* An array combining the above + +> *Note:* +Since Puppet 4.0.0 it is possible to slice an array with index and count directly in the language. +A negative value is taken to be "from the end" of the array: + +`['a', 'b', 'c', 'd'][1, 2]` results in `['b', 'c']` +`['a', 'b', 'c', 'd'][2, -1]` results in `['c', 'd']` +`['a', 'b', 'c', 'd'][1, -2]` results in `['b', 'c']` + +#### Examples + +##### **Usage** + +```puppet + +values_at(['a','b','c'], 2) +Would return ['c'] + +values_at(['a','b','c'], ["0-1"]) +Would return ['a','b'] + +values_at(['a','b','c','d','e'], [0, "2-3"]) +Would return ['a','c','d'] +``` + +#### `values_at()` + +The first argument is the array you want to analyze, and the second element can +be a combination of: + +* A single numeric index +* A range in the form of 'start-stop' (eg. 4-9) +* An array combining the above + +> *Note:* +Since Puppet 4.0.0 it is possible to slice an array with index and count directly in the language. +A negative value is taken to be "from the end" of the array: + +`['a', 'b', 'c', 'd'][1, 2]` results in `['b', 'c']` +`['a', 'b', 'c', 'd'][2, -1]` results in `['c', 'd']` +`['a', 'b', 'c', 'd'][1, -2]` results in `['b', 'c']` + +Returns: `Any` an array of values identified by location + +##### Examples + +###### **Usage** + +```puppet + +values_at(['a','b','c'], 2) +Would return ['c'] + +values_at(['a','b','c'], ["0-1"]) +Would return ['a','b'] + +values_at(['a','b','c','d','e'], [0, "2-3"]) +Would return ['a','c','d'] +``` + +### `zip` + +Type: Ruby 3.x API + +Takes one element from first array and merges corresponding elements from second array. + +#### Examples + +##### + +```puppet +zip(['1','2','3'],['4','5','6']) +Would result in: ["1", "4"], ["2", "5"], ["3", "6"] +``` + +#### `zip()` + +The zip function. + +Returns: `Any` This generates a sequence of n-element arrays, where n is one more than the count of arguments. + +##### Examples + +###### + +```puppet +zip(['1','2','3'],['4','5','6']) +Would result in: ["1", "4"], ["2", "5"], ["3", "6"] +``` + +## Data types + +### `Stdlib::Absolutepath` + +A strict absolutepath type + +Alias of `Variant[Stdlib::Windowspath, Stdlib::Unixpath]` + +### `Stdlib::Base32` + +Type to match base32 String + +Alias of `Pattern[/\A[a-z2-7]+={,6}\z/, /\A[A-Z2-7]+={,6}\z/]` + +### `Stdlib::Base64` + +Type to match base64 String + +Alias of `Pattern[/\A[a-zA-Z0-9\/\+]+={,2}\z/]` + +### `Stdlib::CreateResources` + +A type description used for the create_resources function + +#### Examples + +##### As a class parameter + +```puppet +class myclass ( + Stdlib::CreateResources $myresources = {}, +) { + # Using create_resources + create_resources('myresource', $myresources) + + # Using iteration + $myresources.each |$myresource_name, $myresource_attrs| { + myresource { $myresource_name: + * => $myresource_attrs, + } + } +} +``` + +Alias of `Hash[String[1], Hash[String[1], Any]]` + +### `Stdlib::Datasize` + +Validate the size of data + +Alias of `Pattern[/^\d+(?i:[kmgt]b?|b)$/]` + +### `Stdlib::Dns::Zone` + +Validate a DNS zone name + +Alias of `Pattern[/\A((([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])\.)+|\.)\z/]` + +### `Stdlib::Email` + +https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address +lint:ignore:140chars + +Alias of `Pattern[/\A[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\z/]` + +### `Stdlib::Ensure::File` + +Validate the value of the ensure parameter for a file + +Alias of `Enum['present', 'file', 'directory', 'link', 'absent']` + +### `Stdlib::Ensure::File::Directory` + +Validate the ensure parameter of a "directory" file resource + +Alias of `Enum['directory', 'absent']` + +### `Stdlib::Ensure::File::File` + +Validate the ensure parameter of a "file" file resource + +Alias of `Enum['file', 'absent']` + +### `Stdlib::Ensure::File::Link` + +Validate the ensure parameter of a "link" file resource + +Alias of `Enum['link', 'absent']` + +### `Stdlib::Ensure::Package` + +Validate the value of the ensure parameter for a package + +Alias of `Variant[Enum['present', 'absent', 'purged', 'disabled', 'installed', 'latest'], String[1]]` + +### `Stdlib::Ensure::Service` + +Validate the value of the ensure parameter of a service resource + +Alias of `Enum['stopped', 'running']` + +### `Stdlib::Filemode` + +See `man chmod.1` for the regular expression for symbolic mode +lint:ignore:140chars + +Alias of `Pattern[/\A(([0-7]{1,4})|(([ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=][0-7]+)(,([ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=][0-7]+))*))\z/]` + +### `Stdlib::Filesource` + +Validate the source parameter on file types + +Alias of + +```puppet +Variant[Stdlib::Absolutepath, Stdlib::HTTPUrl, Pattern[ + /\Afile:\/\/\/([^\n\/\0]+(\/)?)+\z/, + /\Apuppet:\/\/(([\w-]+\.?)+)?\/([^\n\/\0]+(\/)?)+\z/, + ]] +``` + +### `Stdlib::Fqdn` + +Validate a Fully Qualified Domain Name + +Alias of `Pattern[/\A(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])\z/]` + +### `Stdlib::HTTPSUrl` + +Validate a HTTPS URL + +Alias of `Pattern[/(?i:\Ahttps:\/\/.*\z)/]` + +### `Stdlib::HTTPUrl` + +Validate a HTTP(S) URL + +Alias of `Pattern[/(?i:\Ahttps?:\/\/.*\z)/]` + +### `Stdlib::Host` + +Validate a host (FQDN or IP address) + +Alias of `Variant[Stdlib::Fqdn, Stdlib::IP::Address]` + +### `Stdlib::Http::Method` + +Valid HTTP method verbs + +* **See also** + * https://www.iana.org/assignments/http-methods/http-methods.xhtml + +Alias of `Enum['ACL', 'BASELINE-CONTROL', 'BIND', 'CHECKIN', 'CHECKOUT', 'CONNECT', 'COPY', 'DELETE', 'GET', 'HEAD', 'LABEL', 'LINK', 'LOCK', 'MERGE', 'MKACTIVITY', 'MKCALENDAR', 'MKCOL', 'MKREDIRECTREF', 'MKWORKSPACE', 'MOVE', 'OPTIONS', 'ORDERPATCH', 'PATCH', 'POST', 'PRI', 'PROPFIND', 'PROPPATCH', 'PUT', 'REBIND', 'REPORT', 'SEARCH', 'TRACE', 'UNBIND', 'UNCHECKOUT', 'UNLINK', 'UNLOCK', 'UPDATE', 'UPDATEREDIRECTREF', 'VERSION-CONTROL']` + +### `Stdlib::Http::Status` + +A valid HTTP status code per RFC9110 + +* **See also** + * https://httpwg.org/specs/rfc9110.html#overview.of.status.codes + +Alias of `Integer[100, 599]` + +### `Stdlib::HttpStatus` + +Validate a HTTP status code + +* **DEPRECATED** Use Stdlib::Http::Status + +* **See also** + * Stdlib::Http::Status + +Alias of `Stdlib::Http::Status` + +### `Stdlib::IP::Address` + +Validate an IP address + +Alias of `Variant[Stdlib::IP::Address::V4, Stdlib::IP::Address::V6]` + +### `Stdlib::IP::Address::CIDR` + +Validate an IP address with subnet + +Alias of `Variant[Stdlib::IP::Address::V4::CIDR, Stdlib::IP::Address::V6::CIDR]` + +### `Stdlib::IP::Address::Nosubnet` + +Validate an IP address without subnet + +Alias of `Variant[Stdlib::IP::Address::V4::Nosubnet, Stdlib::IP::Address::V6::Nosubnet]` + +### `Stdlib::IP::Address::V4` + +Validate an IPv4 address + +Alias of `Variant[Stdlib::IP::Address::V4::CIDR, Stdlib::IP::Address::V4::Nosubnet]` + +### `Stdlib::IP::Address::V4::CIDR` + +lint:ignore:140chars + +Alias of `Pattern[/\A([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}\/([0-9]|[12][0-9]|3[0-2])\z/]` + +### `Stdlib::IP::Address::V4::Nosubnet` + +lint:ignore:140chars + +Alias of `Pattern[/\A([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}\z/]` + +### `Stdlib::IP::Address::V6` + +Validate an IPv6 address + +Alias of `Variant[Stdlib::IP::Address::V6::Full, Stdlib::IP::Address::V6::Compressed, Stdlib::IP::Address::V6::Alternative, Stdlib::IP::Address::V6::Nosubnet]` + +### `Stdlib::IP::Address::V6::Alternative` + +lint:ignore:140chars + +Alias of `Pattern[/\A([[:xdigit:]]{1,4}:){6}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/, /\A([[:xdigit:]]{1,4}:){5}:([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/, /\A([[:xdigit:]]{1,4}:){4}(:[[:xdigit:]]{1,4}){0,1}:([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/, /\A([[:xdigit:]]{1,4}:){3}(:[[:xdigit:]]{1,4}){0,2}:([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/, /\A([[:xdigit:]]{1,4}:){2}(:[[:xdigit:]]{1,4}){0,3}:([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/, /\A([[:xdigit:]]{1,4}:){1}(:[[:xdigit:]]{1,4}){0,4}:([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/, /\A:(:[[:xdigit:]]{1,4}){0,5}:([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/]` + +### `Stdlib::IP::Address::V6::CIDR` + +lint:ignore:140chars + +Alias of `Pattern[/\A((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*\/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])?\z/]` + +### `Stdlib::IP::Address::V6::Compressed` + +Validate a compressed IPv6 address + +Alias of `Pattern[/\A:(:|(:[[:xdigit:]]{1,4}){1,7})(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/, /\A([[:xdigit:]]{1,4}:){1}(:|(:[[:xdigit:]]{1,4}){1,6})(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/, /\A([[:xdigit:]]{1,4}:){2}(:|(:[[:xdigit:]]{1,4}){1,5})(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/, /\A([[:xdigit:]]{1,4}:){3}(:|(:[[:xdigit:]]{1,4}){1,4})(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/, /\A([[:xdigit:]]{1,4}:){4}(:|(:[[:xdigit:]]{1,4}){1,3})(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/, /\A([[:xdigit:]]{1,4}:){5}(:|(:[[:xdigit:]]{1,4}){1,2})(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/, /\A([[:xdigit:]]{1,4}:){6}(:|(:[[:xdigit:]]{1,4}){1,1})(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/, /\A([[:xdigit:]]{1,4}:){7}:(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/]` + +### `Stdlib::IP::Address::V6::Full` + +Validate a full IPv6 address + +Alias of `Pattern[/\A[[:xdigit:]]{1,4}(:[[:xdigit:]]{1,4}){7}(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/]` + +### `Stdlib::IP::Address::V6::Nosubnet` + +Validate an IPv6 address without subnet + +Alias of `Variant[Stdlib::IP::Address::V6::Nosubnet::Full, Stdlib::IP::Address::V6::Nosubnet::Compressed, Stdlib::IP::Address::V6::Nosubnet::Alternative]` + +### `Stdlib::IP::Address::V6::Nosubnet::Alternative` + +lint:ignore:140chars + +Alias of `Pattern[/\A([[:xdigit:]]{1,4}:){6}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}\z/, /\A([[:xdigit:]]{1,4}:){5}:([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}\z/, /\A([[:xdigit:]]{1,4}:){4}(:[[:xdigit:]]{1,4}){0,1}:([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}\z/, /\A([[:xdigit:]]{1,4}:){3}(:[[:xdigit:]]{1,4}){0,2}:([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}\z/, /\A([[:xdigit:]]{1,4}:){2}(:[[:xdigit:]]{1,4}){0,3}:([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}\z/, /\A([[:xdigit:]]{1,4}:){1}(:[[:xdigit:]]{1,4}){0,4}:([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}\z/, /\A:(:[[:xdigit:]]{1,4}){0,5}:([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}\z/]` + +### `Stdlib::IP::Address::V6::Nosubnet::Compressed` + +Validate compressed IPv6 address without subnet + +Alias of `Pattern[/\A:(:|(:[[:xdigit:]]{1,4}){1,7})\z/, /\A([[:xdigit:]]{1,4}:){1}(:|(:[[:xdigit:]]{1,4}){1,6})\z/, /\A([[:xdigit:]]{1,4}:){2}(:|(:[[:xdigit:]]{1,4}){1,5})\z/, /\A([[:xdigit:]]{1,4}:){3}(:|(:[[:xdigit:]]{1,4}){1,4})\z/, /\A([[:xdigit:]]{1,4}:){4}(:|(:[[:xdigit:]]{1,4}){1,3})\z/, /\A([[:xdigit:]]{1,4}:){5}(:|(:[[:xdigit:]]{1,4}){1,2})\z/, /\A([[:xdigit:]]{1,4}:){6}(:|(:[[:xdigit:]]{1,4}){1,1})\z/, /\A([[:xdigit:]]{1,4}:){7}:\z/]` + +### `Stdlib::IP::Address::V6::Nosubnet::Full` + +Validate full IPv6 address without subnet + +Alias of `Pattern[/\A[[:xdigit:]]{1,4}(:[[:xdigit:]]{1,4}){7}\z/]` + +### `Stdlib::MAC` + +A type for a MAC address + +Alias of `Pattern[/\A([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})\z/, /\A([0-9A-Fa-f]{2}[:-]){19}([0-9A-Fa-f]{2})\z/]` + +### `Stdlib::ObjectStore` + +Validate an ObjectStore + +Alias of `Variant[Stdlib::ObjectStore::GSUri, Stdlib::ObjectStore::S3Uri]` + +### `Stdlib::ObjectStore::GSUri` + +Validate a Google Cloud object store URI + +Alias of `Pattern[/\Ags:\/\/.*\z/]` + +### `Stdlib::ObjectStore::S3Uri` + +Validate an Amazon Web Services S3 object store URI + +Alias of `Pattern[/\As3:\/\/.*\z/]` + +### `Stdlib::Port` + +Validate a port number + +Alias of `Integer[0, 65535]` + +### `Stdlib::Port::Dynamic` + +Validate a dynamic port number + +Alias of `Integer[49152, 65535]` + +### `Stdlib::Port::Ephemeral` + +Validate an ephemeral port number + +Alias of `Stdlib::Port::Dynamic` + +### `Stdlib::Port::Privileged` + +Validate a priviliged port number + +Alias of `Integer[1, 1023]` + +### `Stdlib::Port::Registered` + +Validate a registered port number + +Alias of `Stdlib::Port::User` + +### `Stdlib::Port::Unprivileged` + +Validate an unprivileged port number + +Alias of `Integer[1024, 65535]` + +### `Stdlib::Port::User` + +Validate a port number usable by a user + +Alias of `Integer[1024, 49151]` + +### `Stdlib::Syslogfacility` + +Validate a syslog facility + +Alias of `Enum['kern', 'user', 'mail', 'daemon', 'auth', 'syslog', 'lpr', 'news', 'uucp', 'cron', 'authpriv', 'ftp', 'ntp', 'security', 'console', 'solaris-cron', 'local0', 'local1', 'local2', 'local3', 'local4', 'local5', 'local6', 'local7']` + +### `Stdlib::Unixpath` + +this regex rejects any path component that does not start with "/" or is NUL + +Alias of `Pattern[/\A\/([^\n\/\0]+\/*)*\z/]` + +### `Stdlib::Windowspath` + +Validate a Windows path + +Alias of `Pattern[/\A(([a-zA-Z]:[\\\/])|([\\\/][\\\/][^\\\/]+[\\\/][^\\\/]+)|([\\\/][\\\/]\?[\\\/][^\\\/]+)).*\z/]` + +### `Stdlib::Yes_no` + +Validate a yes / no value + +Alias of `Pattern[/\A(?i:(yes|no))\z/]` + diff --git a/RELEASE_PROCESS.markdown b/RELEASE_PROCESS.markdown index 0f9328ed0..083eeeb8e 100644 --- a/RELEASE_PROCESS.markdown +++ b/RELEASE_PROCESS.markdown @@ -3,12 +3,12 @@ * Work in a topic branch * Submit a github pull request * Address any comments / feeback - * Merge into master using --no-ff + * Merge into main using --no-ff # Releasing this module # * This module adheres to http://semver.org/ - * Look for API breaking changes using git diff vX.Y.Z..master + * Look for API breaking changes using git diff vX.Y.Z.. * If no API breaking changes, the minor version may be bumped. * If there are API breaking changes, the major version must be bumped. * If there are only small minor changes, the patch version may be bumped. diff --git a/Rakefile b/Rakefile index e136b8e41..31b593053 100644 --- a/Rakefile +++ b/Rakefile @@ -1,7 +1,18 @@ -require 'rubygems' -# keep for compatibility for now +# frozen_string_literal: true + +require 'bundler' +require 'puppet_litmus/rake_tasks' if Gem.loaded_specs.key? 'puppet_litmus' require 'puppetlabs_spec_helper/rake_tasks' -require 'puppet-lint/tasks/puppet-lint' +require 'puppet-syntax/tasks/puppet-syntax' +require 'puppet-strings/tasks' if Gem.loaded_specs.key? 'puppet-strings' + +PuppetLint.configuration.send('disable_relative') PuppetLint.configuration.send('disable_80chars') -PuppetLint.configuration.ignore_paths = ["spec/**/*.pp", "pkg/**/*.pp"] +PuppetLint.configuration.send('disable_140chars') +PuppetLint.configuration.send('disable_class_inherits_from_params_class') +PuppetLint.configuration.send('disable_autoloader_layout') +PuppetLint.configuration.send('disable_documentation') +PuppetLint.configuration.send('disable_single_quote_string_with_variables') +PuppetLint.configuration.fail_on_warnings = true +PuppetLint.configuration.ignore_paths = [".vendor/**/*.pp", ".bundle/**/*.pp", "pkg/**/*.pp", "spec/**/*.pp", "tests/**/*.pp", "types/**/*.pp", "vendor/**/*.pp"] diff --git a/data/common.yaml b/data/common.yaml new file mode 100644 index 000000000..2fbf0ffd7 --- /dev/null +++ b/data/common.yaml @@ -0,0 +1 @@ +--- {} diff --git a/examples/file_line.pp b/examples/file_line.pp index 85b132586..e628bea34 100644 --- a/examples/file_line.pp +++ b/examples/file_line.pp @@ -2,8 +2,8 @@ # of the file_line resource type. file { '/tmp/dansfile': ensure => file, -} -> -file_line { 'dans_line': +} +-> file_line { 'dans_line': line => 'dan is awesome', path => '/tmp/dansfile', } diff --git a/examples/has_interface_with.pp b/examples/has_interface_with.pp index a578dd279..8906a66c5 100644 --- a/examples/has_interface_with.pp +++ b/examples/has_interface_with.pp @@ -1,4 +1,4 @@ -include ::stdlib +include stdlib info('has_interface_with(\'lo\'):', has_interface_with('lo')) info('has_interface_with(\'loX\'):', has_interface_with('loX')) info('has_interface_with(\'ipaddress\', \'127.0.0.1\'):', has_interface_with('ipaddress', '127.0.0.1')) diff --git a/examples/has_ip_address.pp b/examples/has_ip_address.pp index 594143d66..8429a8855 100644 --- a/examples/has_ip_address.pp +++ b/examples/has_ip_address.pp @@ -1,3 +1,3 @@ -include ::stdlib +include stdlib info('has_ip_address(\'192.168.1.256\'):', has_ip_address('192.168.1.256')) info('has_ip_address(\'127.0.0.1\'):', has_ip_address('127.0.0.1')) diff --git a/examples/has_ip_network.pp b/examples/has_ip_network.pp index 1f1130dc7..669a29127 100644 --- a/examples/has_ip_network.pp +++ b/examples/has_ip_network.pp @@ -1,3 +1,3 @@ -include ::stdlib +include stdlib info('has_ip_network(\'127.0.0.0\'):', has_ip_network('127.0.0.0')) info('has_ip_network(\'128.0.0.0\'):', has_ip_network('128.0.0.0')) diff --git a/examples/init.pp b/examples/init.pp index ad2797213..9675d8374 100644 --- a/examples/init.pp +++ b/examples/init.pp @@ -1 +1 @@ -include ::stdlib +include stdlib diff --git a/functions/deferrable_epp.pp b/functions/deferrable_epp.pp new file mode 100644 index 000000000..ae3d653d9 --- /dev/null +++ b/functions/deferrable_epp.pp @@ -0,0 +1,18 @@ +# This function returns either a rendered template or a deferred function to render at runtime. +# If any of the values in the variables hash are deferred, then the template will be deferred. +# +# Note: this function requires all parameters to be explicitly passed in. It cannot expect to +# use facts, class variables, and other variables in scope. This is because when deferred, we +# have to explicitly pass the entire scope to the client. +# +function stdlib::deferrable_epp(String $template, Hash $variables) >> Variant[String, Sensitive[String], Deferred] { + if $variables.stdlib::nested_values.any |$value| { $value.is_a(Deferred) } { + Deferred( + 'inline_epp', + [find_template($template).file, $variables], + ) + } + else { + epp($template, $variables) + } +} diff --git a/functions/ensure.pp b/functions/ensure.pp new file mode 100644 index 000000000..9b63d44e5 --- /dev/null +++ b/functions/ensure.pp @@ -0,0 +1,33 @@ +# @summary function to cast ensure parameter to resource specific value +# +# @return [String] +function stdlib::ensure( + Variant[Boolean, Enum['present', 'absent']] $ensure, + Optional[Enum['directory', 'link', 'mounted', 'service', 'file', 'package']] $resource = undef, +) >> String { + $_ensure = $ensure ? { + Boolean => $ensure.bool2str('present', 'absent'), + default => $ensure, + } + case $resource { + 'package': { + $_ensure ? { + 'present' => 'installed', + default => 'absent', + } + } + 'service': { + $_ensure ? { + 'present' => 'running', + default => 'stopped', + } + } + undef: { $_ensure } + default: { + $_ensure ? { + 'present' => $resource, + default => $_ensure, + } + } + } +} diff --git a/functions/has_ip_address.pp b/functions/has_ip_address.pp new file mode 100644 index 000000000..d8d7e6a79 --- /dev/null +++ b/functions/has_ip_address.pp @@ -0,0 +1,10 @@ +# @summary Returns true if the client has the requested IPv4 address on some interface. +# +# @param ip_address +# The IPv4 address you want to check the existence of +# @return [Boolean] Returns `true` if the requested IP address exists on any interface. +function stdlib::has_ip_address( + Stdlib::IP::Address::V4::Nosubnet $ip_address, +) >> Boolean { + stdlib::has_interface_with('ipaddress', $ip_address) +} diff --git a/functions/has_ip_network.pp b/functions/has_ip_network.pp new file mode 100644 index 000000000..b6b9cb0f8 --- /dev/null +++ b/functions/has_ip_network.pp @@ -0,0 +1,10 @@ +# @summary Returns true if the client has the requested IPv4 network on some interface. +# +# @param ip_network +# The IPv4 network you want to check the existence of +# @return [Boolean] Returns `true` if the requested IP network exists on any interface. +function stdlib::has_ip_network( + Stdlib::IP::Address::V4::Nosubnet $ip_network, +) >> Boolean { + stdlib::has_interface_with('network', $ip_network) +} diff --git a/functions/time.pp b/functions/time.pp new file mode 100644 index 000000000..711bd7a5b --- /dev/null +++ b/functions/time.pp @@ -0,0 +1,11 @@ +# @summary This function is deprecated. It implements the functionality of the original non-namespaced stdlib `time` function. +# +# It is provided for compatability, but users should use the native time related functions directly. +# +# @param _timezone +# This parameter doesn't do anything, but exists for compatability reasons +function stdlib::time(Optional[String] $_timezone = undef) >> Integer { + # Note the `timezone` parameter doesn't do anything and didn't in the ruby implementation for _years_ (pre 1.8.7 perhaps ???) + deprecation('time', 'The stdlib `time` function is deprecated. Please direcly use native Puppet functionality instead. eg. `Integer(Timestamp().strftime(\'%s\'))`', false) + Integer(Timestamp().strftime('%s')) +} diff --git a/hiera.yaml b/hiera.yaml new file mode 100644 index 000000000..545fff327 --- /dev/null +++ b/hiera.yaml @@ -0,0 +1,21 @@ +--- +version: 5 + +defaults: # Used for any hierarchy level that omits these keys. + datadir: data # This path is relative to hiera.yaml's directory. + data_hash: yaml_data # Use the built-in YAML backend. + +hierarchy: + - name: "osfamily/major release" + paths: + # Used to distinguish between Debian and Ubuntu + - "os/%{facts.os.name}/%{facts.os.release.major}.yaml" + - "os/%{facts.os.family}/%{facts.os.release.major}.yaml" + # Used for Solaris + - "os/%{facts.os.family}/%{facts.kernelrelease}.yaml" + - name: "osfamily" + paths: + - "os/%{facts.os.name}.yaml" + - "os/%{facts.os.family}.yaml" + - name: 'common' + path: 'common.yaml' diff --git a/lib/facter/facter_dot_d.rb b/lib/facter/facter_dot_d.rb deleted file mode 100644 index d85940de5..000000000 --- a/lib/facter/facter_dot_d.rb +++ /dev/null @@ -1,202 +0,0 @@ -# A Facter plugin that loads facts from /etc/facter/facts.d -# and /etc/puppetlabs/facter/facts.d. -# -# Facts can be in the form of JSON, YAML or Text files -# and any executable that returns key=value pairs. -# -# In the case of scripts you can also create a file that -# contains a cache TTL. For foo.sh store the ttl as just -# a number in foo.sh.ttl -# -# The cache is stored in $libdir/facts_dot_d.cache as a mode -# 600 file and will have the end result of not calling your -# fact scripts more often than is needed - -class Facter::Util::DotD - require 'yaml' - - def initialize(dir="/etc/facts.d", cache_file=File.join(Puppet[:libdir], "facts_dot_d.cache")) - @dir = dir - @cache_file = cache_file - @cache = nil - @types = {".txt" => :txt, ".json" => :json, ".yaml" => :yaml} - end - - def entries - Dir.entries(@dir).reject { |f| f =~ /^\.|\.ttl$/ }.sort.map { |f| File.join(@dir, f) } - rescue - [] - end - - def fact_type(file) - extension = File.extname(file) - - type = @types[extension] || :unknown - - type = :script if type == :unknown && File.executable?(file) - - return type - end - - def txt_parser(file) - File.readlines(file).each do |line| - if line =~ /^([^=]+)=(.+)$/ - var = $1; val = $2 - - Facter.add(var) do - setcode { val } - end - end - end - rescue Exception => e - Facter.warn("Failed to handle #{file} as text facts: #{e.class}: #{e}") - end - - def json_parser(file) - begin - require 'json' - rescue LoadError - retry if require 'rubygems' - raise - end - - JSON.load(File.read(file)).each_pair do |f, v| - Facter.add(f) do - setcode { v } - end - end - rescue Exception => e - Facter.warn("Failed to handle #{file} as json facts: #{e.class}: #{e}") - end - - def yaml_parser(file) - require 'yaml' - - YAML.load_file(file).each_pair do |f, v| - Facter.add(f) do - setcode { v } - end - end - rescue Exception => e - Facter.warn("Failed to handle #{file} as yaml facts: #{e.class}: #{e}") - end - - def script_parser(file) - result = cache_lookup(file) - ttl = cache_time(file) - - unless result - result = Facter::Util::Resolution.exec(file) - - if ttl > 0 - Facter.debug("Updating cache for #{file}") - cache_store(file, result) - cache_save! - end - else - Facter.debug("Using cached data for #{file}") - end - - result.split("\n").each do |line| - if line =~ /^(.+)=(.+)$/ - var = $1; val = $2 - - Facter.add(var) do - setcode { val } - end - end - end - rescue Exception => e - Facter.warn("Failed to handle #{file} as script facts: #{e.class}: #{e}") - Facter.debug(e.backtrace.join("\n\t")) - end - - def cache_save! - cache = load_cache - File.open(@cache_file, "w", 0600) { |f| f.write(YAML.dump(cache)) } - rescue - end - - def cache_store(file, data) - load_cache - - @cache[file] = {:data => data, :stored => Time.now.to_i} - rescue - end - - def cache_lookup(file) - cache = load_cache - - return nil if cache.empty? - - ttl = cache_time(file) - - if cache[file] - now = Time.now.to_i - - return cache[file][:data] if ttl == -1 - return cache[file][:data] if (now - cache[file][:stored]) <= ttl - return nil - else - return nil - end - rescue - return nil - end - - def cache_time(file) - meta = file + ".ttl" - - return File.read(meta).chomp.to_i - rescue - return 0 - end - - def load_cache - unless @cache - if File.exist?(@cache_file) - @cache = YAML.load_file(@cache_file) - else - @cache = {} - end - end - - return @cache - rescue - @cache = {} - return @cache - end - - def create - entries.each do |fact| - type = fact_type(fact) - parser = "#{type}_parser" - - if respond_to?("#{type}_parser") - Facter.debug("Parsing #{fact} using #{parser}") - - send(parser, fact) - end - end - end -end - - -mdata = Facter.version.match(/(\d+)\.(\d+)\.(\d+)/) -if mdata - (major, minor, patch) = mdata.captures.map { |v| v.to_i } - if major < 2 - # Facter 1.7 introduced external facts support directly - unless major == 1 and minor > 6 - Facter::Util::DotD.new("/etc/facter/facts.d").create - Facter::Util::DotD.new("/etc/puppetlabs/facter/facts.d").create - - # Windows has a different configuration directory that defaults to a vendor - # specific sub directory of the %COMMON_APPDATA% directory. - if Dir.const_defined? 'COMMON_APPDATA' then - windows_facts_dot_d = File.join(Dir::COMMON_APPDATA, 'PuppetLabs', 'facter', 'facts.d') - Facter::Util::DotD.new(windows_facts_dot_d).create - end - end - end -end diff --git a/lib/facter/package_provider.rb b/lib/facter/package_provider.rb index 65a2da0a8..c5c1ef859 100644 --- a/lib/facter/package_provider.rb +++ b/lib/facter/package_provider.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Fact: package_provider # # Purpose: Returns the default provider Puppet will choose to manage packages @@ -10,12 +12,10 @@ require 'puppet/type' require 'puppet/type/package' +# These will be nil if Puppet is not available. Facter.add(:package_provider) do + # Instantiates a dummy package resource and return the provider setcode do - if Gem::Version.new(Facter.value(:puppetversion)) >= Gem::Version.new('3.6') - Puppet::Type.type(:package).newpackage(:name => 'dummy', :allow_virtual => 'true')[:provider].to_s - else - Puppet::Type.type(:package).newpackage(:name => 'dummy')[:provider].to_s - end + Puppet::Type.type(:package).newpackage(name: 'dummy', allow_virtual: 'true')[:provider].to_s end end diff --git a/lib/facter/pe_version.rb b/lib/facter/pe_version.rb index c9f2181c0..716ff7198 100644 --- a/lib/facter/pe_version.rb +++ b/lib/facter/pe_version.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Fact: is_pe, pe_version, pe_major_version, pe_minor_version, pe_patch_version # # Purpose: Return various facts about the PE state of the system @@ -8,51 +10,53 @@ # # Caveats: # -Facter.add("pe_version") do +# Fact: pe_version +Facter.add('pe_version') do setcode do - puppet_ver = Facter.value("puppetversion") - if puppet_ver != nil - pe_ver = puppet_ver.match(/Puppet Enterprise (\d+\.\d+\.\d+)/) - pe_ver[1] if pe_ver - else - nil + found_version = Facter.value('pe_build') + + unless found_version + puppet_ver = Facter.value('puppetversion') + unless puppet_ver.nil? + pe_ver = puppet_ver.match(%r{Puppet Enterprise (\d+\.\d+\.\d+)}) + found_version = pe_ver[1] if pe_ver + end end + + found_version end end -Facter.add("is_pe") do +# Fact: is_pe +Facter.add('is_pe') do setcode do - if Facter.value(:pe_version).to_s.empty? then - false - else - true - end + !Facter.value(:pe_version).to_s.empty? end end -Facter.add("pe_major_version") do - confine :is_pe => true +# Fact: pe_major_version +Facter.add('pe_major_version') do + confine is_pe: true setcode do - if pe_version = Facter.value(:pe_version) - pe_version.to_s.split('.')[0] - end + pe_version = Facter.value(:pe_version) + pe_version.to_s.split('.')[0] if pe_version end end -Facter.add("pe_minor_version") do - confine :is_pe => true +# Fact: pe_minor_version +Facter.add('pe_minor_version') do + confine is_pe: true setcode do - if pe_version = Facter.value(:pe_version) - pe_version.to_s.split('.')[1] - end + pe_version = Facter.value(:pe_version) + pe_version.to_s.split('.')[1] if pe_version end end -Facter.add("pe_patch_version") do - confine :is_pe => true +# Fact: pe_patch_version +Facter.add('pe_patch_version') do + confine is_pe: true setcode do - if pe_version = Facter.value(:pe_version) - pe_version.to_s.split('.')[2] - end + pe_version = Facter.value(:pe_version) + pe_version.to_s.split('.')[2] if pe_version end end diff --git a/lib/facter/puppet_settings.rb b/lib/facter/puppet_settings.rb new file mode 100644 index 000000000..951b2eb7c --- /dev/null +++ b/lib/facter/puppet_settings.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +# These facter facts return the value of the Puppet vardir and environment path +# settings for the node running puppet or puppet agent. The intent is to +# enable Puppet modules to automatically have insight into a place where they +# can place variable data, or for modules running on the puppet server to know +# where environments are stored. +# +# The values should be directly usable in a File resource path attribute. +# +begin + require 'facter/util/puppet_settings' +rescue LoadError => e + # puppet apply does not add module lib directories to the $LOAD_PATH (See + # #4248). It should (in the future) but for the time being we need to be + # defensive which is what this rescue block is doing. + rb_file = File.join(File.dirname(__FILE__), 'util', 'puppet_settings.rb') + load rb_file if File.exist?(rb_file) || raise(e) +end + +# Facter fact returns the value of the Puppet vardir +Facter.add(:puppet_vardir) do + setcode do + Facter::Util::PuppetSettings.with_puppet do + Puppet[:vardir] + end + end +end + +# Facter fact returns the value of the Puppet environment path +Facter.add(:puppet_environmentpath) do + setcode do + Facter::Util::PuppetSettings.with_puppet do + Puppet[:environmentpath] + end + end +end + +# Facter fact returns the value of the Puppet server +Facter.add(:puppet_server) do + setcode do + Facter::Util::PuppetSettings.with_puppet do + Puppet[:server] + end + end +end diff --git a/lib/facter/puppet_vardir.rb b/lib/facter/puppet_vardir.rb deleted file mode 100644 index 0e6af40e4..000000000 --- a/lib/facter/puppet_vardir.rb +++ /dev/null @@ -1,26 +0,0 @@ -# This facter fact returns the value of the Puppet vardir setting for the node -# running puppet or puppet agent. The intent is to enable Puppet modules to -# automatically have insight into a place where they can place variable data, -# regardless of the node's platform. -# -# The value should be directly usable in a File resource path attribute. - - -begin - require 'facter/util/puppet_settings' -rescue LoadError => e - # puppet apply does not add module lib directories to the $LOAD_PATH (See - # #4248). It should (in the future) but for the time being we need to be - # defensive which is what this rescue block is doing. - rb_file = File.join(File.dirname(__FILE__), 'util', 'puppet_settings.rb') - load rb_file if File.exists?(rb_file) or raise e -end - -Facter.add(:puppet_vardir) do - setcode do - # This will be nil if Puppet is not available. - Facter::Util::PuppetSettings.with_puppet do - Puppet[:vardir] - end - end -end diff --git a/lib/facter/root_home.rb b/lib/facter/root_home.rb index 87c765718..c44d64a7b 100644 --- a/lib/facter/root_home.rb +++ b/lib/facter/root_home.rb @@ -1,45 +1,11 @@ -# A facter fact to determine the root home directory. -# This varies on PE supported platforms and may be -# reconfigured by the end user. - -module Facter::Util::RootHome - class << self - def get_root_home - root_ent = Facter::Util::Resolution.exec("getent passwd root") - # The home directory is the sixth element in the passwd entry - # If the platform doesn't have getent, root_ent will be nil and we should - # return it straight away. - root_ent && root_ent.split(":")[5] - end - end -end - -Facter.add(:root_home) do - setcode { Facter::Util::RootHome.get_root_home } -end - -Facter.add(:root_home) do - confine :kernel => :darwin - setcode do - str = Facter::Util::Resolution.exec("dscacheutil -q user -a name root") - hash = {} - str.split("\n").each do |pair| - key,value = pair.split(/:/) - hash[key] = value - end - hash['dir'].strip - end -end +# frozen_string_literal: true Facter.add(:root_home) do - confine :kernel => :aix - root_home = nil setcode do - str = Facter::Util::Resolution.exec("lsuser -c -a home root") - str && str.split("\n").each do |line| - next if line =~ /^#/ - root_home = line.split(/:/)[1] - end - root_home + require 'etc' + rescue LoadError + # Unavailable on platforms like Windows + else + Etc.getpwnam('root')&.dir end end diff --git a/lib/facter/service_provider.rb b/lib/facter/service_provider.rb index a11792115..3d4e44a57 100644 --- a/lib/facter/service_provider.rb +++ b/lib/facter/service_provider.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Fact: service_provider # # Purpose: Returns the default provider Puppet will choose to manage services @@ -12,6 +14,6 @@ Facter.add(:service_provider) do setcode do - Puppet::Type.type(:service).newservice(:name => 'dummy')[:provider].to_s + Puppet::Type.type(:service).newservice(name: 'dummy')[:provider].to_s end end diff --git a/lib/facter/util/puppet_settings.rb b/lib/facter/util/puppet_settings.rb index 1ad945218..d808f264c 100644 --- a/lib/facter/util/puppet_settings.rb +++ b/lib/facter/util/puppet_settings.rb @@ -1,21 +1,18 @@ -module Facter - module Util - module PuppetSettings - # This method is intended to provide a convenient way to evaluate a - # Facter code block only if Puppet is loaded. This is to account for the - # situation where the fact happens to be in the load path, but Puppet is - # not loaded for whatever reason. Perhaps the user is simply running - # facter without the --puppet flag and they happen to be working in a lib - # directory of a module. - def self.with_puppet - begin - Module.const_get("Puppet") - rescue NameError - nil - else - yield - end - end - end +# frozen_string_literal: true + +# A method to evaluate a Facter code block if puppet is loaded. +module Facter::Util::PuppetSettings + # This method is intended to provide a convenient way to evaluate a + # Facter code block only if Puppet is loaded. This is to account for the + # situation where the fact happens to be in the load path, but Puppet is + # not loaded for whatever reason. Perhaps the user is simply running + # facter without the --puppet flag and they happen to be working in a lib + # directory of a module. + def self.with_puppet + Module.const_get(:Puppet) + rescue NameError + nil + else + yield end end diff --git a/lib/puppet/functions/batch_escape.rb b/lib/puppet/functions/batch_escape.rb new file mode 100644 index 000000000..07d326a88 --- /dev/null +++ b/lib/puppet/functions/batch_escape.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# THIS FILE WAS GENERATED BY `rake regenerate_unamespaced_shims` + +# @summary DEPRECATED. Use the namespaced function [`stdlib::batch_escape`](#stdlibbatch_escape) instead. +Puppet::Functions.create_function(:batch_escape) do + dispatch :deprecation_gen do + repeated_param 'Any', :args + end + def deprecation_gen(*args) + call_function('deprecation', 'batch_escape', 'This function is deprecated, please use stdlib::batch_escape instead.', false) + call_function('stdlib::batch_escape', *args) + end +end diff --git a/lib/puppet/functions/deprecation.rb b/lib/puppet/functions/deprecation.rb new file mode 100644 index 000000000..f508cf029 --- /dev/null +++ b/lib/puppet/functions/deprecation.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +# @summary Function to print deprecation warnings, Logs a warning once for a given key. +Puppet::Functions.create_function(:deprecation) do + # @param key + # The uniqueness key. This function logs once for any given key. + # @param message + # Is the message text including any positional information that is formatted by the user/caller of the function. + # @param use_strict_setting + # When `true`, (the default), the function is affected by the puppet setting 'strict', which can be set to :error + # (outputs as an error message), :off (no message / error is displayed) and :warning + # (default, outputs a warning). + dispatch :deprecation do + param 'String', :key + param 'String', :message + optional_param 'Boolean', :use_strict_setting + end + + def deprecation(key, message, use_strict_setting = true) # rubocop:disable Style/OptionalBooleanParameter + if defined? Puppet::Pops::PuppetStack.stacktrace + stacktrace = Puppet::Pops::PuppetStack.stacktrace + file = stacktrace[0] + line = stacktrace[1] + message = "#{message} at #{file}:#{line}" + end + + # Do nothing if using strict setting and strict is set to `off` + return if use_strict_setting && Puppet.settings[:strict] == :off + + # Fail hard if using strict setting and strict is set to `error` + raise("deprecation. #{key}. #{message}") if use_strict_setting && Puppet.settings[:strict] == :error + + # Otherwise raise a soft warning + # (unless the STDLIB_LOG_DEPRECATIONS has been set to `false`. This is mainly for use in rspec-puppet testing to suppress noise in logs) + Puppet.deprecation_warning(message, key) unless ENV['STDLIB_LOG_DEPRECATIONS'] == 'false' + nil + end +end diff --git a/lib/puppet/functions/ensure_packages.rb b/lib/puppet/functions/ensure_packages.rb new file mode 100644 index 000000000..f6f4b3ce8 --- /dev/null +++ b/lib/puppet/functions/ensure_packages.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +# @summary DEPRECATED. Use the namespaced function [`stdlib::ensure_packages`](#stdlibensure_packages) instead. +Puppet::Functions.create_function(:ensure_packages, Puppet::Functions::InternalFunction) do + dispatch :deprecation_gen do + scope_param + repeated_param 'Any', :args + end + def deprecation_gen(scope, *args) + call_function('deprecation', 'ensure_packages', 'This function is deprecated, please use stdlib::ensure_packages instead.', false) + scope.call_function('stdlib::ensure_packages', args) + end +end diff --git a/lib/puppet/functions/fact.rb b/lib/puppet/functions/fact.rb new file mode 100644 index 000000000..c450436ca --- /dev/null +++ b/lib/puppet/functions/fact.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true + +# @summary +# Digs into the facts hash using dot-notation +# +# Supports the use of dot-notation for referring to structured facts. If a fact requested +# does not exist, returns Undef. +# +# @example Example usage: +# fact('osfamily') +# fact('os.architecture') +# +# @example Array indexing: +# fact('mountpoints."/dev".options.1') +# +# @example Fact containing a "." in the name: +# fact('vmware."VRA.version"') +# +Puppet::Functions.create_function(:fact) do + # @param fact_name + # The name of the fact to check + # + # @return + # All information retrieved on the given fact_name + dispatch :fact do + param 'String', :fact_name + end + + def to_dot_syntax(array_path) + array_path.map { |string| + string.include?('.') ? %("#{string}") : string + }.join('.') + end + + def fact(fact_name) + facts = closure_scope['facts'] + + # Transform the dot-notation string into an array of paths to walk. Make + # sure to correctly extract double-quoted values containing dots as single + # elements in the path. + path = fact_name.scan(%r{([^."]+)|(?:")([^"]+)(?:")}).map { |x| x.compact.first } + + walked_path = [] + path.reduce(facts) do |d, k| + return nil if d.nil? || k.nil? + + if d.is_a?(Array) + begin + result = d[Integer(k)] + rescue ArgumentError => e # rubocop:disable Lint/UselessAssignment : Causes errors if assigment is removed. + Puppet.warning("fact request for #{fact_name} returning nil: '#{to_dot_syntax(walked_path)}' is an array; cannot index to '#{k}'") + result = nil + end + elsif d.is_a?(Hash) + result = d[k] + else + Puppet.warning("fact request for #{fact_name} returning nil: '#{to_dot_syntax(walked_path)}' is not a collection; cannot walk to '#{k}'") + result = nil + end + + walked_path << k + result + end + end +end diff --git a/lib/puppet/functions/fqdn_rand_string.rb b/lib/puppet/functions/fqdn_rand_string.rb new file mode 100644 index 000000000..1c5f5f6fe --- /dev/null +++ b/lib/puppet/functions/fqdn_rand_string.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# THIS FILE WAS GENERATED BY `rake regenerate_unamespaced_shims` + +# @summary DEPRECATED. Use the namespaced function [`stdlib::fqdn_rand_string`](#stdlibfqdn_rand_string) instead. +Puppet::Functions.create_function(:fqdn_rand_string) do + dispatch :deprecation_gen do + repeated_param 'Any', :args + end + def deprecation_gen(*args) + call_function('deprecation', 'fqdn_rand_string', 'This function is deprecated, please use stdlib::fqdn_rand_string instead.', false) + call_function('stdlib::fqdn_rand_string', *args) + end +end diff --git a/lib/puppet/functions/fqdn_rotate.rb b/lib/puppet/functions/fqdn_rotate.rb new file mode 100644 index 000000000..2f067fe43 --- /dev/null +++ b/lib/puppet/functions/fqdn_rotate.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# THIS FILE WAS GENERATED BY `rake regenerate_unamespaced_shims` + +# @summary DEPRECATED. Use the namespaced function [`stdlib::fqdn_rotate`](#stdlibfqdn_rotate) instead. +Puppet::Functions.create_function(:fqdn_rotate) do + dispatch :deprecation_gen do + repeated_param 'Any', :args + end + def deprecation_gen(*args) + call_function('deprecation', 'fqdn_rotate', 'This function is deprecated, please use stdlib::fqdn_rotate instead.', false) + call_function('stdlib::fqdn_rotate', *args) + end +end diff --git a/lib/puppet/functions/has_interface_with.rb b/lib/puppet/functions/has_interface_with.rb new file mode 100644 index 000000000..bd36802c8 --- /dev/null +++ b/lib/puppet/functions/has_interface_with.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# THIS FILE WAS GENERATED BY `rake regenerate_unamespaced_shims` + +# @summary DEPRECATED. Use the namespaced function [`stdlib::has_interface_with`](#stdlibhas_interface_with) instead. +Puppet::Functions.create_function(:has_interface_with) do + dispatch :deprecation_gen do + repeated_param 'Any', :args + end + def deprecation_gen(*args) + call_function('deprecation', 'has_interface_with', 'This function is deprecated, please use stdlib::has_interface_with instead.', false) + call_function('stdlib::has_interface_with', *args) + end +end diff --git a/lib/puppet/functions/has_ip_address.rb b/lib/puppet/functions/has_ip_address.rb new file mode 100644 index 000000000..392d5c550 --- /dev/null +++ b/lib/puppet/functions/has_ip_address.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# THIS FILE WAS GENERATED BY `rake regenerate_unamespaced_shims` + +# @summary DEPRECATED. Use the namespaced function [`stdlib::has_ip_address`](#stdlibhas_ip_address) instead. +Puppet::Functions.create_function(:has_ip_address) do + dispatch :deprecation_gen do + repeated_param 'Any', :args + end + def deprecation_gen(*args) + call_function('deprecation', 'has_ip_address', 'This function is deprecated, please use stdlib::has_ip_address instead.', false) + call_function('stdlib::has_ip_address', *args) + end +end diff --git a/lib/puppet/functions/has_ip_network.rb b/lib/puppet/functions/has_ip_network.rb new file mode 100644 index 000000000..b0219b671 --- /dev/null +++ b/lib/puppet/functions/has_ip_network.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# THIS FILE WAS GENERATED BY `rake regenerate_unamespaced_shims` + +# @summary DEPRECATED. Use the namespaced function [`stdlib::has_ip_network`](#stdlibhas_ip_network) instead. +Puppet::Functions.create_function(:has_ip_network) do + dispatch :deprecation_gen do + repeated_param 'Any', :args + end + def deprecation_gen(*args) + call_function('deprecation', 'has_ip_network', 'This function is deprecated, please use stdlib::has_ip_network instead.', false) + call_function('stdlib::has_ip_network', *args) + end +end diff --git a/lib/puppet/functions/is_a.rb b/lib/puppet/functions/is_a.rb index da98b0352..275d21815 100644 --- a/lib/puppet/functions/is_a.rb +++ b/lib/puppet/functions/is_a.rb @@ -1,31 +1,43 @@ -# Boolean check to determine whether a variable is of a given data type. This is equivalent to the `=~` type checks. +# frozen_string_literal: true + +# @summary +# Boolean check to determine whether a variable is of a given data type. +# This is equivalent to the `=~` type checks. # -# @example how to check a data type +# @example Example Usage: # # check a data type -# foo = 3 -# $bar = [1,2,3] -# $baz = 'A string!' +# foo = 3 +# $bar = [1,2,3] +# $baz = 'A string!' # -# if $foo.is_a(Integer) { -# notify { 'foo!': } -# } -# if $bar.is_a(Array) { -# notify { 'bar!': } -# } -# if $baz.is_a(String) { -# notify { 'baz!': } -# } +# if $foo.is_a(Integer) { +# notify { 'foo!': } +# } +# if $bar.is_a(Array) { +# notify { 'bar!': } +# } +# if $baz.is_a(String) { +# notify { 'baz!': } +# } # # See the documentation for "The Puppet Type System" for more information about types. # See the `assert_type()` function for flexible ways to assert the type of a value. # Puppet::Functions.create_function(:is_a) do + # @param value + # The value to be checked + # + # @param type + # The expected type + # + # @return [Boolean] + # Return's `true` or `false`. dispatch :is_a do param 'Any', :value param 'Type', :type end - def is_a(value, type) + def is_a(value, type) # rubocop:disable Naming/PredicateName : Used in to many other places to rename at this time, attempting to refactor caused Rubocop to crash. # See puppet's lib/puppet/pops/evaluator/evaluator_impl.rb eval_MatchExpression Puppet::Pops::Types::TypeCalculator.instance?(type, value) end diff --git a/lib/puppet/functions/merge.rb b/lib/puppet/functions/merge.rb new file mode 100644 index 000000000..da42d9c92 --- /dev/null +++ b/lib/puppet/functions/merge.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +# THIS FILE WAS GENERATED BY `rake regenerate_unamespaced_shims` + +# @summary DEPRECATED. Use the namespaced function [`stdlib::merge`](#stdlibmerge) instead. +Puppet::Functions.create_function(:merge) do + dispatch :deprecation_gen do + repeated_param 'Any', :args + optional_block_param 'Variant[Callable[2,2], Callable[3,3]]', :block + end + def deprecation_gen(*args, &block) + call_function('deprecation', 'merge', 'This function is deprecated, please use stdlib::merge instead.', false) + call_function('stdlib::merge', *args, &block) + end +end diff --git a/lib/puppet/functions/os_version_gte.rb b/lib/puppet/functions/os_version_gte.rb new file mode 100644 index 000000000..28da44fe0 --- /dev/null +++ b/lib/puppet/functions/os_version_gte.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# THIS FILE WAS GENERATED BY `rake regenerate_unamespaced_shims` + +# @summary DEPRECATED. Use the namespaced function [`stdlib::os_version_gte`](#stdlibos_version_gte) instead. +Puppet::Functions.create_function(:os_version_gte) do + dispatch :deprecation_gen do + repeated_param 'Any', :args + end + def deprecation_gen(*args) + call_function('deprecation', 'os_version_gte', 'This function is deprecated, please use stdlib::os_version_gte instead.', false) + call_function('stdlib::os_version_gte', *args) + end +end diff --git a/lib/puppet/functions/parsehocon.rb b/lib/puppet/functions/parsehocon.rb new file mode 100644 index 000000000..700f685e5 --- /dev/null +++ b/lib/puppet/functions/parsehocon.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# THIS FILE WAS GENERATED BY `rake regenerate_unamespaced_shims` + +# @summary DEPRECATED. Use the namespaced function [`stdlib::parsehocon`](#stdlibparsehocon) instead. +Puppet::Functions.create_function(:parsehocon) do + dispatch :deprecation_gen do + repeated_param 'Any', :args + end + def deprecation_gen(*args) + call_function('deprecation', 'parsehocon', 'This function is deprecated, please use stdlib::parsehocon instead.', false) + call_function('stdlib::parsehocon', *args) + end +end diff --git a/lib/puppet/functions/parsepson.rb b/lib/puppet/functions/parsepson.rb new file mode 100644 index 000000000..2eedbeee9 --- /dev/null +++ b/lib/puppet/functions/parsepson.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +# @summary +# **Deprecated:** Starting Puppet 8, we no longer natively support PSON usage. This function should be removed once we stop supporting Puppet 7. +# +# This function accepts PSON, a Puppet variant of JSON, as a string and converts +# it into the correct Puppet structure +# +# @example How to parse pson +# $data = parsepson('{"a":"1","b":"2"}') +# +# For more information on PSON please see the following link: +# https://puppet.com/docs/puppet/7/http_api/pson.html +# +Puppet::Functions.create_function(:parsepson) do + # @param pson_string A valid PSON string + # @param default An optional default to return if parsing the pson_string fails + # @return [Data] + dispatch :parsepson do + param 'String[1]', :pson_string + optional_param 'Any', :default + end + + def parsepson(pson_string, default = :no_default_provided) + call_function('deprecation', 'parsepson', 'This method is deprecated. From Puppet 8, PSON is no longer natively supported. Please use JSON.parse().') + + PSON.load(pson_string) if Puppet::Util::Package.versioncmp(Puppet.version, '8').negative? + rescue StandardError => e + Puppet.debug("Parsing PSON failed with error: #{e.message}") + raise e if default == :no_default_provided + + default + end +end diff --git a/lib/puppet/functions/powershell_escape.rb b/lib/puppet/functions/powershell_escape.rb new file mode 100644 index 000000000..72209b24a --- /dev/null +++ b/lib/puppet/functions/powershell_escape.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# THIS FILE WAS GENERATED BY `rake regenerate_unamespaced_shims` + +# @summary DEPRECATED. Use the namespaced function [`stdlib::powershell_escape`](#stdlibpowershell_escape) instead. +Puppet::Functions.create_function(:powershell_escape) do + dispatch :deprecation_gen do + repeated_param 'Any', :args + end + def deprecation_gen(*args) + call_function('deprecation', 'powershell_escape', 'This function is deprecated, please use stdlib::powershell_escape instead.', false) + call_function('stdlib::powershell_escape', *args) + end +end diff --git a/lib/puppet/functions/seeded_rand.rb b/lib/puppet/functions/seeded_rand.rb new file mode 100644 index 000000000..b97c93f36 --- /dev/null +++ b/lib/puppet/functions/seeded_rand.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# THIS FILE WAS GENERATED BY `rake regenerate_unamespaced_shims` + +# @summary DEPRECATED. Use the namespaced function [`stdlib::seeded_rand`](#stdlibseeded_rand) instead. +Puppet::Functions.create_function(:seeded_rand) do + dispatch :deprecation_gen do + repeated_param 'Any', :args + end + def deprecation_gen(*args) + call_function('deprecation', 'seeded_rand', 'This function is deprecated, please use stdlib::seeded_rand instead.', false) + call_function('stdlib::seeded_rand', *args) + end +end diff --git a/lib/puppet/functions/seeded_rand_string.rb b/lib/puppet/functions/seeded_rand_string.rb new file mode 100644 index 000000000..486082547 --- /dev/null +++ b/lib/puppet/functions/seeded_rand_string.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# THIS FILE WAS GENERATED BY `rake regenerate_unamespaced_shims` + +# @summary DEPRECATED. Use the namespaced function [`stdlib::seeded_rand_string`](#stdlibseeded_rand_string) instead. +Puppet::Functions.create_function(:seeded_rand_string) do + dispatch :deprecation_gen do + repeated_param 'Any', :args + end + def deprecation_gen(*args) + call_function('deprecation', 'seeded_rand_string', 'This function is deprecated, please use stdlib::seeded_rand_string instead.', false) + call_function('stdlib::seeded_rand_string', *args) + end +end diff --git a/lib/puppet/functions/shell_escape.rb b/lib/puppet/functions/shell_escape.rb new file mode 100644 index 000000000..87af9a9af --- /dev/null +++ b/lib/puppet/functions/shell_escape.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# THIS FILE WAS GENERATED BY `rake regenerate_unamespaced_shims` + +# @summary DEPRECATED. Use the namespaced function [`stdlib::shell_escape`](#stdlibshell_escape) instead. +Puppet::Functions.create_function(:shell_escape) do + dispatch :deprecation_gen do + repeated_param 'Any', :args + end + def deprecation_gen(*args) + call_function('deprecation', 'shell_escape', 'This function is deprecated, please use stdlib::shell_escape instead.', false) + call_function('stdlib::shell_escape', *args) + end +end diff --git a/lib/puppet/functions/stdlib/batch_escape.rb b/lib/puppet/functions/stdlib/batch_escape.rb new file mode 100644 index 000000000..740d0a4a4 --- /dev/null +++ b/lib/puppet/functions/stdlib/batch_escape.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +# @summary +# Escapes a string so that it can be safely used in a batch shell command line. +# +# >* Note:* that the resulting string should be used unquoted and is not intended for use in double quotes nor in single +# quotes. +Puppet::Functions.create_function(:'stdlib::batch_escape') do + # @param string + # The string to escape + # + # @return + # An escaped string that can be safely used in a batch command line. + dispatch :batch_escape do + param 'Any', :string + end + + def batch_escape(string) + result = '' + + string.to_s.chars.each do |char| + result += case char + when '"' then '""' + when '$', '\\' then "\\#{char}" + else char + end + end + + %("#{result}") + end +end diff --git a/lib/puppet/functions/stdlib/crc32.rb b/lib/puppet/functions/stdlib/crc32.rb new file mode 100644 index 000000000..73ecfa3b5 --- /dev/null +++ b/lib/puppet/functions/stdlib/crc32.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require 'zlib' +# @note +# The CRC32 algorithm can easily generate collisions, +# but may be useful for generating sharding, describing +# secrets, or seeding nonce values. +# +# @summary +# Run a CRC32 calculation against a given value. +Puppet::Functions.create_function(:'stdlib::crc32') do + # @param my_data The ScalarData to evaluate + # @example Check a simple string value + # stdlib::crc32('my string') == '18fbd270' + # @example Check a Sensitive datatype + # stdlib::crc32(sensitive('my string')) == '18fbd270' + # @example Check a number + # stdlib::crc32(100.0) == 'a3fd429a' + # stdlib::crc32(100.00000) == 'a3fd429a' + # @return String + dispatch :crc32 do + param 'Variant[ScalarData, Sensitive[ScalarData], Binary, Sensitive[Binary]]', :my_data + return_type 'String' + end + + def crc32(my_data) + Zlib.crc32(my_data.unwrap.to_s).to_s(16).downcase + rescue StandardError + Zlib.crc32(my_data.to_s).to_s(16).downcase + end +end diff --git a/lib/puppet/functions/stdlib/end_with.rb b/lib/puppet/functions/stdlib/end_with.rb new file mode 100644 index 000000000..6c640890c --- /dev/null +++ b/lib/puppet/functions/stdlib/end_with.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +# @summary +# Returns true if str ends with one of the prefixes given. Each of the prefixes should be a String. +# +Puppet::Functions.create_function(:'stdlib::end_with') do + # @param test_string The string to check + # @param suffixes The suffixes to check + # @example + # 'foobar'.stdlib::end_with('bar') => true + # 'foobar'.stdlib::end_with('foo') => false + # 'foobar'.stdlib::end_with(['foo', 'baz']) => false + # @return [Boolean] True or False + dispatch :end_with do + param 'String', :test_string + param 'Variant[String[1],Array[String[1], 1]]', :suffixes + return_type 'Boolean' + end + + def end_with(test_string, suffixes) + test_string.end_with?(*suffixes) + end +end diff --git a/lib/puppet/functions/stdlib/ensure_packages.rb b/lib/puppet/functions/stdlib/ensure_packages.rb new file mode 100644 index 000000000..288100f06 --- /dev/null +++ b/lib/puppet/functions/stdlib/ensure_packages.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +# @summary Takes a list of packages and only installs them if they don't already exist. +# +# It optionally takes a hash as a second parameter that will be passed as the +# third argument to the ensure_resource() function. +Puppet::Functions.create_function(:'stdlib::ensure_packages', Puppet::Functions::InternalFunction) do + # @param packages + # The packages to ensure are installed. + # @param default_attributes + # Default attributes to be passed to the `ensure_resource()` function + # @return [Undef] Returns nothing. + dispatch :ensure_packages do + scope_param + param 'Variant[String[1], Array[String[1]]]', :packages + optional_param 'Hash', :default_attributes + return_type 'Undef' + end + + # @param packages + # The packages to ensure are installed. The keys are packages and values are the attributes specific to that package. + # @param default_attributes + # Default attributes. Package specific attributes from the `packages` parameter will take precedence. + # @return [Undef] Returns nothing. + dispatch :ensure_packages_hash do + scope_param + param 'Hash[String[1], Any]', :packages + optional_param 'Hash', :default_attributes + return_type 'Undef' + end + + def ensure_packages(scope, packages, default_attributes = {}) + Array(packages).each do |package_name| + defaults = { 'ensure' => 'installed' }.merge(default_attributes) + + # `present` and `installed` are aliases for the `ensure` attribute. If `ensure` is set to either of these values replace + # with `installed` by default but `present` if this package is already in the catalog with `ensure => present` + defaults['ensure'] = default_ensure(package_name) if ['present', 'installed'].include?(defaults['ensure']) + + scope.call_function('ensure_resource', ['package', package_name, defaults]) + end + nil + end + + def ensure_packages_hash(scope, packages, default_attributes = {}) + packages.each do |package, attributes| + ensure_packages(scope, package, default_attributes.merge(attributes)) + end + nil + end + + private + + def default_ensure(package_name) + if call_function('defined_with_params', "Package[#{package_name}]", { 'ensure' => 'present' }) + 'present' + else + 'installed' + end + end +end diff --git a/lib/puppet/functions/stdlib/extname.rb b/lib/puppet/functions/stdlib/extname.rb new file mode 100644 index 000000000..7de9d50a6 --- /dev/null +++ b/lib/puppet/functions/stdlib/extname.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +# @summary +# Returns the Extension (the Portion of Filename in Path starting from the +# last Period). +# +# If Path is a Dotfile, or starts with a Period, then the starting Dot is not +# dealt with the Start of the Extension. +# +# An empty String will also be returned, when the Period is the last Character +# in Path. +Puppet::Functions.create_function(:'stdlib::extname') do + # @param filename The Filename + # @return [String] The Extension starting from the last Period + # @example Determining the Extension of a Filename + # stdlib::extname('test.rb') => '.rb' + # stdlib::extname('a/b/d/test.rb') => '.rb' + # stdlib::extname('test') => '' + # stdlib::extname('.profile') => '' + dispatch :extname do + param 'String', :filename + return_type 'String' + end + + def extname(filename) + File.extname(filename) + end +end diff --git a/lib/puppet/functions/stdlib/fqdn_rand_string.rb b/lib/puppet/functions/stdlib/fqdn_rand_string.rb new file mode 100644 index 000000000..47e436605 --- /dev/null +++ b/lib/puppet/functions/stdlib/fqdn_rand_string.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +# @summary +# Generates a random alphanumeric string. Combining the `$fqdn` fact and an +# optional seed for repeatable randomness. +# +# Optionally, you can specify a character set for the function (defaults to alphanumeric). +Puppet::Functions.create_function(:'stdlib::fqdn_rand_string') do + # @param length The length of the resulting string. + # @param charset The character set to use. + # @param seed The seed for repeatable randomness. + # + # @return [String] + # + # @example Example Usage: + # stdlib::fqdn_rand_string(10) + # stdlib::fqdn_rand_string(10, 'ABCDEF!@$%^') + # stdlib::fqdn_rand_string(10, undef, 'custom seed') + dispatch :fqdn_rand_string do + param 'Integer[1]', :length + optional_param 'Optional[String]', :charset + optional_repeated_param 'Any', :seed + end + + def fqdn_rand_string(length, charset = nil, *seed) + charset = if charset && !charset.empty? + charset.chars.to_a + else + (0..9).map(&:to_s) + ('A'..'Z').to_a + ('a'..'z').to_a + end + + rand_string = '' + length.times do |current| + rand_string += charset[call_function('fqdn_rand', charset.size, (seed + [current + 1]).join(':'))] + end + + rand_string + end +end diff --git a/lib/puppet/functions/stdlib/fqdn_rotate.rb b/lib/puppet/functions/stdlib/fqdn_rotate.rb new file mode 100644 index 000000000..5d7121b28 --- /dev/null +++ b/lib/puppet/functions/stdlib/fqdn_rotate.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +# @summary Rotates an array or string a random number of times, combining the `fqdn` fact and an optional seed for repeatable randomness. +Puppet::Functions.create_function(:'stdlib::fqdn_rotate') do + # @param input + # The String you want rotated a random number of times + # @param seeds + # One of more values to use as a custom seed. These will be combined with the host's FQDN + # + # @return [String] Returns the rotated String + # + # @example Rotating a String + # stdlib::fqdn_rotate('abcd') + # @example Using a custom seed + # stdlib::fqdn_rotate('abcd', 'custom seed') + dispatch :fqdn_rotate_string do + param 'String', :input + optional_repeated_param 'Variant[Integer,String]', :seeds + return_type 'String' + end + + # @param input + # The Array you want rotated a random number of times + # @param seeds + # One of more values to use as a custom seed. These will be combined with the host's FQDN + # + # @return [String] Returns the rotated Array + # + # @example Rotating an Array + # stdlib::fqdn_rotate(['a', 'b', 'c', 'd']) + # @example Using custom seeds + # stdlib::fqdn_rotate([1, 2, 3], 'custom', 'seed', 1) + dispatch :fqdn_rotate_array do + param 'Array', :input + optional_repeated_param 'Variant[Integer,String]', :seeds + return_type 'Array' + end + + def fqdn_rotate_array(input, *seeds) + # Check whether it makes sense to rotate ... + return input if input.size <= 1 + + result = input.clone + + require 'digest/md5' + seed = Digest::MD5.hexdigest([fqdn_fact, seeds].join(':')).hex + + offset = Puppet::Util.deterministic_rand(seed, result.size).to_i + + offset.times do + result.push result.shift + end + + result + end + + def fqdn_rotate_string(input, *seeds) + fqdn_rotate_array(input.chars, seeds).join + end + + private + + def fqdn_fact + closure_scope['facts']['networking']['fqdn'] + end +end diff --git a/lib/puppet/functions/stdlib/has_function.rb b/lib/puppet/functions/stdlib/has_function.rb new file mode 100644 index 000000000..c30a6a203 --- /dev/null +++ b/lib/puppet/functions/stdlib/has_function.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +# @summary +# Returns whether the Puppet runtime has access to a given function. +# +# @example Using stdlib::has_function() +# stdlib::has_function('stdlib::has_function') # true +# stdlib::has_function('not_a_function') # false +# +# Determines whether the Puppet runtime has access to a function by the +# name provided. +# +# @return +# Returns true if the provided function name is available, false otherwise. +# +Puppet::Functions.create_function(:'stdlib::has_function', Puppet::Functions::InternalFunction) do + dispatch :has_function do + scope_param + param 'String[1]', :function_name + return_type 'Boolean' + end + + def has_function(scope, function_name) # rubocop:disable Naming/PredicateName + loaders = scope.compiler.loaders + loader = loaders.private_environment_loader + return true unless loader&.load(:function, function_name).nil? + + # If the loader cannot find the function it might be + # a 3x-style function stubbed in on-the-fly for testing. + func_3x = Puppet::Parser::Functions.function(function_name.to_sym) + func_3x.is_a?(String) && !func_3x.empty? + end +end diff --git a/lib/puppet/functions/stdlib/has_interface_with.rb b/lib/puppet/functions/stdlib/has_interface_with.rb new file mode 100644 index 000000000..3bfbc0f42 --- /dev/null +++ b/lib/puppet/functions/stdlib/has_interface_with.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +# @summary Returns boolean based on network interfaces present and their attribute values. +# +# Can be called with one, or two arguments. +Puppet::Functions.create_function(:'stdlib::has_interface_with') do + # @param interface + # The name of an interface + # @return [Boolean] Returns `true` if `interface` exists and `false` otherwise + # @example When called with a single argument, the presence of the interface is checked + # stdlib::has_interface_with('lo') # Returns `true` + dispatch :has_interface do + param 'String[1]', :interface + return_type 'Boolean' + end + + # @param kind + # A supported interface attribute + # @param value + # The value of the attribute + # @return [Boolean] Returns `true` if any of the interfaces in the `networking` fact has a `kind` attribute with the value `value`. Otherwise returns `false` + # @example Checking if an interface exists with a given mac address + # stdlib::has_interface_with('macaddress', 'x:x:x:x:x:x') # Returns `false` + # @example Checking if an interface exists with a given IP address + # stdlib::has_interface_with('ipaddress', '127.0.0.1') # Returns `true` + dispatch :has_interface_with do + param "Enum['macaddress','netmask','ipaddress','network','ip','mac']", :kind + param 'String[1]', :value + return_type 'Boolean' + end + + def has_interface(interface) # rubocop:disable Naming/PredicateName + interfaces.key? interface + end + + def has_interface_with(kind, value) # rubocop:disable Naming/PredicateName + # For compatibility with older version of function that used the legacy facts, alias `ip` with `ipaddress` and `mac` with `macaddress` + kind = 'ip' if kind == 'ipaddress' + kind = 'mac' if kind == 'macaddress' + + interfaces.any? { |_interface, params| params[kind] == value } + end + + def interfaces + closure_scope['facts']['networking']['interfaces'] + end +end diff --git a/lib/puppet/functions/stdlib/ip_in_range.rb b/lib/puppet/functions/stdlib/ip_in_range.rb new file mode 100644 index 000000000..eed5c0b2e --- /dev/null +++ b/lib/puppet/functions/stdlib/ip_in_range.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +# @summary +# Returns true if the ipaddress is within the given CIDRs +# +# @example ip_in_range(, ) +# stdlib::ip_in_range('10.10.10.53', '10.10.10.0/24') => true +Puppet::Functions.create_function(:'stdlib::ip_in_range') do + # @param ipaddress The IP address to check + # @param range One CIDR or an array of CIDRs + # defining the range(s) to check against + # + # @return [Boolean] True or False + dispatch :ip_in_range do + param 'String', :ipaddress + param 'Variant[String, Array]', :range + return_type 'Boolean' + end + + require 'ipaddr' + def ip_in_range(ipaddress, range) + ip = IPAddr.new(ipaddress) + + if range.is_a? Array + ranges = range.map { |r| IPAddr.new(r) } + ranges.any? { |rng| rng.include?(ip) } + elsif range.is_a? String + ranges = IPAddr.new(range) + ranges.include?(ip) + end + end +end diff --git a/lib/puppet/functions/stdlib/merge.rb b/lib/puppet/functions/stdlib/merge.rb new file mode 100644 index 000000000..c55a29a69 --- /dev/null +++ b/lib/puppet/functions/stdlib/merge.rb @@ -0,0 +1,112 @@ +# frozen_string_literal: true + +# @summary +# Merges two or more hashes together or hashes resulting from iteration, and returns +# the resulting hash. +# +# @example Using stdlib::merge() +# $hash1 = {'one' => 1, 'two', => 2} +# $hash2 = {'two' => 'dos', 'three', => 'tres'} +# $merged_hash = stdlib::merge($hash1, $hash2) # $merged_hash = {'one' => 1, 'two' => 'dos', 'three' => 'tres'} +# +# When there is a duplicate key, the key in the rightmost hash will "win." +# +# Note that since Puppet 4.0.0 the same merge can be achieved with the + operator. +# `$merged_hash = $hash1 + $hash2` +# +# If stdlib::merge is given a single Iterable (Array, Hash, etc.) it will call a given block with +# up to three parameters, and merge each resulting Hash into the accumulated result. All other types +# of values returned from the block (typically undef) are skipped (not merged). +# +# The codeblock can take 2 or three parameters: +# * with two, it gets the current hash (as built to this point), and each value (for hash the value is a [key, value] tuple) +# * with three, it gets the current hash (as built to this point), the key/index of each value, and then the value +# +# If the iterable is empty, or no hash was returned from the given block, an empty hash is returned. In the given block, a call to `next()` +# will skip that entry, and a call to `break()` will end the iteration. +# +# @example counting occurrences of strings in an array +# ['a', 'b', 'c', 'c', 'd', 'b'].stdlib::merge | $hsh, $v | { { $v => $hsh[$v].lest || { 0 } + 1 } } # results in { a => 1, b => 2, c => 2, d => 1 } +# +# @example skipping values for entries that are longer than 1 char +# ['a', 'b', 'c', 'c', 'd', 'b', 'blah', 'blah'].stdlib::merge | $hsh, $v | { if $v =~ String[1,1] { { $v => $hsh[$v].lest || { 0 } + 1 } } } # results in { a => 1, b => 2, c => 2, d => 1 } +# +# The iterative `stdlib::merge()` has an advantage over doing the same with a general `reduce()` in that the constructed hash +# does not have to be copied in each iteration and thus will perform much better with large inputs. +Puppet::Functions.create_function(:'stdlib::merge') do + # @param args + # Repeated Param - The hashes that are to be merged + # + # @return + # The merged hash + dispatch :merge2hashes do + repeated_param 'Variant[Hash[Scalar,Any], Undef, String[0,0]]', :args # this strange type is backwards compatible + return_type 'Hash[Scalar,Any]' + end + + # @param args + # Repeated Param - The hashes that are to be merged + # + # @param block + # A block placed on the repeatable param `args` + # + # @return + # The merged hash + dispatch :merge_iterable3 do + repeated_param 'Iterable', :args + block_param 'Callable[3,3]', :block + return_type 'Hash' + end + + # @param args + # Repeated Param - The hashes that are to be merged + # + # @param block + # A block placed on the repeatable param `args` + # + # @return + # The merged hash + dispatch :merge_iterable2 do + repeated_param 'Iterable', :args + block_param 'Callable[2,2]', :block + return_type 'Hash' + end + + def merge2hashes(*hashes) + accumulator = {} + hashes.each { |h| accumulator.merge!(h) if h.is_a?(Hash) } + accumulator + end + + def merge_iterable2(iterable) + accumulator = {} + enum = Puppet::Pops::Types::Iterable.asserted_iterable(self, iterable) + enum.each do |v| + r = yield(accumulator, v) + accumulator.merge!(r) if r.is_a?(Hash) + end + accumulator + end + + def merge_iterable3(iterable) + accumulator = {} + enum = Puppet::Pops::Types::Iterable.asserted_iterable(self, iterable) + if enum.hash_style? + enum.each do |entry| + r = yield(accumulator, *entry) + accumulator.merge!(r) if r.is_a?(Hash) + end + else + begin + index = 0 + loop do + r = yield(accumulator, index, enum.next) + accumulator.merge!(r) if r.is_a?(Hash) + index += 1 + end + rescue StopIteration + end + end + accumulator + end +end diff --git a/lib/puppet/functions/stdlib/nested_values.rb b/lib/puppet/functions/stdlib/nested_values.rb new file mode 100644 index 000000000..54c5313cd --- /dev/null +++ b/lib/puppet/functions/stdlib/nested_values.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +# @summary Get list of nested values from given hash +# This function will return list of nested Hash values and returns list of values in form of Array +# +# @example Example Usage: +# $hash = { +# "key1" => "value1", +# "key2" => { "key2.1" => "value2.1"}, +# "key3" => "value3" +# } +# $data = $hash.stdlib::nested_values +# #Output : ["value1", "value2.1", "value3"] +Puppet::Functions.create_function(:'stdlib::nested_values') do + # @param hash A (nested) hash + # @return All the values found in the input hash included those deeply nested. + dispatch :nested_values do + param 'Hash', :hash + return_type 'Array' + end + + def nested_values(hash) + hash.each_with_object([]) do |(_k, v), values| + v.is_a?(Hash) ? values.concat(nested_values(v)) : (values << v) + end + end +end diff --git a/lib/puppet/functions/stdlib/os_version_gte.rb b/lib/puppet/functions/stdlib/os_version_gte.rb new file mode 100644 index 000000000..866ba5d24 --- /dev/null +++ b/lib/puppet/functions/stdlib/os_version_gte.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +# @summary +# Checks if the OS version is at least a certain version. +# > *Note:* +# Only the major version is taken into account. +# +# @example Example usage:# +# if stdlib::os_version_gte('Debian', '9') { } +# if stdlib::os_version_gte('Ubuntu', '18.04') { } +Puppet::Functions.create_function(:'stdlib::os_version_gte') do + # @param os operating system + # @param version + # + # @return [Boolean] `true` or `false + dispatch :os_version_gte do + param 'String[1]', :os + param 'String[1]', :version + return_type 'Boolean' + end + + def os_version_gte(os, version) + facts = closure_scope['facts'] + (facts['os']['name'] == os && + Puppet::Util::Package.versioncmp(facts['os']['release']['major'], version) >= 0) + end +end diff --git a/lib/puppet/functions/stdlib/parsehocon.rb b/lib/puppet/functions/stdlib/parsehocon.rb new file mode 100644 index 000000000..159028f99 --- /dev/null +++ b/lib/puppet/functions/stdlib/parsehocon.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +# @summary +# This function accepts HOCON as a string and converts it into the correct +# Puppet structure +# +# @example How to parse hocon +# $data = stdlib::parsehocon("{any valid hocon: string}") +# +Puppet::Functions.create_function(:'stdlib::parsehocon') do + # @param hocon_string A valid HOCON string + # @param default An optional default to return if parsing hocon_string fails + # @return [Data] + dispatch :parsehocon do + param 'String', :hocon_string + optional_param 'Any', :default + end + + def parsehocon(hocon_string, default = :no_default_provided) + require 'hocon/config_factory' + + begin + data = Hocon::ConfigFactory.parse_string(hocon_string) + data.resolve.root.unwrapped + rescue Hocon::ConfigError::ConfigParseError => e + Puppet.debug("Parsing hocon failed with error: #{e.message}") + raise e if default == :no_default_provided + + default + end + end +end diff --git a/lib/puppet/functions/stdlib/powershell_escape.rb b/lib/puppet/functions/stdlib/powershell_escape.rb new file mode 100644 index 000000000..4e7e1377f --- /dev/null +++ b/lib/puppet/functions/stdlib/powershell_escape.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +# @summary +# Escapes a string so that it can be safely used in a PowerShell command line. +# +# >* Note:* that the resulting string should be used unquoted and is not intended for use in double quotes nor in single +# quotes. +Puppet::Functions.create_function(:'stdlib::powershell_escape') do + # @param string + # The string to escape + # + # @return + # An escaped string that can be safely used in a PowerShell command line. + dispatch :powershell_escape do + param 'Any', :string + end + + def powershell_escape(string) + result = '' + + string.to_s.chars.each do |char| + result += case char + when ' ', "'", '`', '|', "\n", '$' then "`#{char}" + when '"' then '\`"' + else char + end + end + + result + end +end diff --git a/lib/puppet/functions/stdlib/seeded_rand.rb b/lib/puppet/functions/stdlib/seeded_rand.rb new file mode 100644 index 000000000..331fbdaab --- /dev/null +++ b/lib/puppet/functions/stdlib/seeded_rand.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +# @summary +# Generates a random whole number greater than or equal to 0 and less than max, using the value of seed for repeatable randomness. +Puppet::Functions.create_function(:'stdlib::seeded_rand') do + # @param max The maximum value. + # @param seed The seed used for repeatable randomness. + # + # @return [Integer] + # A random number greater than or equal to 0 and less than max + dispatch :seeded_rand do + param 'Integer[1]', :max + param 'String', :seed + end + + def seeded_rand(max, seed) + require 'digest/md5' + + seed = Digest::MD5.hexdigest(seed).hex + Puppet::Util.deterministic_rand_int(seed, max) + end +end diff --git a/lib/puppet/functions/stdlib/seeded_rand_string.rb b/lib/puppet/functions/stdlib/seeded_rand_string.rb new file mode 100644 index 000000000..166e62e01 --- /dev/null +++ b/lib/puppet/functions/stdlib/seeded_rand_string.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +# @summary +# Generates a consistent random string of specific length based on provided seed. +# +# @example Generate a consistently random string of length 8 with a seed: +# stdlib::seeded_rand_string(8, "${module_name}::redis_password") +# +# @example Generate a random string from a specific set of characters: +# stdlib::seeded_rand_string(5, '', 'abcdef') +Puppet::Functions.create_function(:'stdlib::seeded_rand_string') do + # @param length Length of string to be generated. + # @param seed Seed string. + # @param charset String that contains characters to use for the random string. + # + # @return [String] Random string. + dispatch :rand_string do + param 'Integer[1]', :length + param 'String', :seed + optional_param 'String[2]', :charset + end + + def rand_string(length, seed, charset = nil) + require 'digest/sha2' + + charset ||= '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' + + random_generator = Random.new(Digest::SHA256.hexdigest(seed).to_i(16)) + + Array.new(length) { charset[random_generator.rand(charset.size)] }.join + end +end diff --git a/lib/puppet/functions/stdlib/sha256.rb b/lib/puppet/functions/stdlib/sha256.rb new file mode 100644 index 000000000..278568ba5 --- /dev/null +++ b/lib/puppet/functions/stdlib/sha256.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require 'digest' +# @summary +# Run a SHA256 calculation against a given value. +Puppet::Functions.create_function(:'stdlib::sha256') do + # @param my_data The ScalarData to evaluate + # @example Check a simple string value + # stdlib::sha256('my string') == '2f7e2089add0288a309abd71ffcc3b3567e2d4215e20e6ed3b74d6042f7ef8e5' + # @example Check a Sensitive datatype + # stdlib::sha256(sensitive('my string')) == '2f7e2089add0288a309abd71ffcc3b3567e2d4215e20e6ed3b74d6042f7ef8e5' + # @example Check a number + # stdlib::sha256(100.0) == '43b87f618caab482ebe4976c92bcd6ad308b48055f1c27b4c574f3e31d7683e0' + # stdlib::sha256(100.00000) == '43b87f618caab482ebe4976c92bcd6ad308b48055f1c27b4c574f3e31d7683e0' + # @return String + dispatch :sha256 do + param 'Variant[ScalarData, Sensitive[ScalarData], Binary, Sensitive[Binary]]', :my_data + return_type 'String' + end + + def sha256(my_data) + Digest::SHA256.hexdigest(my_data.unwrap.to_s) + rescue StandardError + Digest::SHA256.hexdigest(my_data.to_s) + end +end diff --git a/lib/puppet/functions/stdlib/shell_escape.rb b/lib/puppet/functions/stdlib/shell_escape.rb new file mode 100644 index 000000000..3d4f7ab3c --- /dev/null +++ b/lib/puppet/functions/stdlib/shell_escape.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +# @summary +# Escapes a string so that it can be safely used in a Bourne shell command line. +# +# >* Note:* that the resulting string should be used unquoted and is not intended for use in double quotes nor in single +# quotes. +# +# This function behaves the same as ruby's Shellwords.shellescape() function. +Puppet::Functions.create_function(:'stdlib::shell_escape') do + # @param string + # The string to escape + # + # @return + # An escaped string that can be safely used in a Bourne shell command line. + dispatch :shell_escape do + param 'Any', :string + end + + def shell_escape(string) + require 'shellwords' + + Shellwords.shellescape(string.to_s) + end +end diff --git a/lib/puppet/functions/stdlib/sort_by.rb b/lib/puppet/functions/stdlib/sort_by.rb new file mode 100644 index 000000000..30b69b5f6 --- /dev/null +++ b/lib/puppet/functions/stdlib/sort_by.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +# @summary Sort an Array, Hash or String by mapping values through a given block. +# +# @example Sort local devices according to their used space. +# $facts['mountpoints'].stdlib::sort_by |$m| { $m.dig(1, 'used_bytes') } +# +Puppet::Functions.create_function(:'stdlib::sort_by') do + # @param ary The Array to sort. + # @param block The block for transforming elements of ary. + # @return [Array] Returns an ordered copy of ary. + dispatch :sort_by_array do + param 'Array', :ary + block_param 'Callable[1,1]', :block + end + + # @param str The String to sort. + # @param block The block for transforming elements of str. + # @return [String] Returns an ordered copy of str. + dispatch :sort_by_string do + param 'String', :str + block_param 'Callable[1,1]', :block + end + + # @param hsh The Hash to sort. + # @param block The block for transforming elements of hsh. + # The block may have arity of one or two. + # @return [Hash] Returns an ordered copy of hsh. + dispatch :sort_by_hash do + param 'Hash', :hsh + block_param 'Variant[Callable[1,1], Callable[2,2]]', :block + end + + def sort_by_iterable(iterable, &block) + Puppet::Pops::Types::Iterable.asserted_iterable(self, iterable).sort_by(&block) + end + + def sort_by_array(ary, &block) + sort_by_iterable(ary, &block) + end + + def sort_by_string(str, &block) + sort_by_iterable(str, &block).join + end + + def sort_by_hash(hsh, &block) + sort_by_iterable(hsh, &block).to_h + end +end diff --git a/lib/puppet/functions/stdlib/start_with.rb b/lib/puppet/functions/stdlib/start_with.rb new file mode 100644 index 000000000..5203baf4f --- /dev/null +++ b/lib/puppet/functions/stdlib/start_with.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +# @summary +# Returns true if str starts with one of the prefixes given. Each of the prefixes should be a String. +# +Puppet::Functions.create_function(:'stdlib::start_with') do + # @param test_string The string to check + # @param prefixes The prefixes to check. + # @example + # 'foobar'.stdlib::start_with('foo') => true + # 'foobar'.stdlib::start_with('bar') => false + # 'foObar'.stdlib::start_with(['bar', 'baz']) => false + # @return [Boolean] True or False + dispatch :start_with do + param 'String', :test_string + param 'Variant[String[1],Array[String[1], 1]]', :prefixes + return_type 'Boolean' + end + + def start_with(test_string, prefixes) + test_string.start_with?(*prefixes) + end +end diff --git a/lib/puppet/functions/stdlib/str2resource.rb b/lib/puppet/functions/stdlib/str2resource.rb new file mode 100644 index 000000000..b2b586992 --- /dev/null +++ b/lib/puppet/functions/stdlib/str2resource.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +# @summary +# This converts a string to a puppet resource. +# +# This attempts to convert a string like 'File[/foo]' into the +# puppet resource `File['/foo']` as detected by the catalog. +# +# Things like 'File[/foo, /bar]' are not supported as a +# title might contain things like ',' or ' '. There is +# no clear value seperator to use. +# +# This function can depend on the parse order of your +# manifests/modules as it inspects the catalog thus far. +Puppet::Functions.create_function(:'stdlib::str2resource') do + # @param res_string The string to lookup as a resource + # @example + # stdlib::str2resource('File[/foo]') => File[/foo] + # @return Puppet::Resource + dispatch :str2resource do + param 'String', :res_string + # return_type 'Puppet::Resource' + return_type 'Any' + end + + def str2resource(res_string) + type_name, title = Puppet::Resource.type_and_title(res_string, nil) + + resource = closure_scope.findresource(type_name, title) + + raise(Puppet::ParseError, "stdlib::str2resource(): could not find #{type_name}[#{title}], this is parse order dependent and values should not be quoted") if resource.nil? + + resource + end +end diff --git a/lib/puppet/functions/stdlib/to_json.rb b/lib/puppet/functions/stdlib/to_json.rb new file mode 100644 index 000000000..1f1d74d27 --- /dev/null +++ b/lib/puppet/functions/stdlib/to_json.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'json' +# @summary +# Convert a data structure and output to JSON +Puppet::Functions.create_function(:'stdlib::to_json') do + # @param data + # Data structure which needs to be converted into JSON + # + # @example Output JSON to a file + # file { '/tmp/my.json': + # ensure => file, + # content => stdlib::to_json($myhash), + # } + # + # @return [String] Converted data to JSON + dispatch :to_json do + param 'Any', :data + end + + def to_json(data) + data.to_json + end +end diff --git a/lib/puppet/functions/stdlib/to_json_pretty.rb b/lib/puppet/functions/stdlib/to_json_pretty.rb new file mode 100644 index 000000000..6fc748575 --- /dev/null +++ b/lib/puppet/functions/stdlib/to_json_pretty.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +require 'json' + +# @summary +# Convert data structure and output to pretty JSON +# +# @example **Usage** +# * how to output pretty JSON to file +# file { '/tmp/my.json': +# ensure => file, +# content => stdlib::to_json_pretty($myhash), +# } +# +# * how to output pretty JSON skipping over keys with undef values +# file { '/tmp/my.json': +# ensure => file, +# content => stdlib::to_json_pretty({ +# param_one => 'value', +# param_two => undef, +# }, true), +# } +# +# * how to output pretty JSON using tabs for indentation +# file { '/tmp/my.json': +# ensure => file, +# content => stdlib::to_json_pretty({ +# param_one => 'value', +# param_two => { +# param_more => 42, +# }, +# }, nil, {indent => ' '}), +# } + +Puppet::Functions.create_function(:'stdlib::to_json_pretty') do + # @param data + # data structure which needs to be converted to pretty json + # @param skip_undef + # value `true` or `false` + # @param opts + # hash-map of settings passed to JSON.pretty_generate, see + # https://ruby-doc.org/stdlib-2.0.0/libdoc/json/rdoc/JSON.html#method-i-generate. + # Note that `max_nesting` doesn't take the value `false`; use `-1` instead. + # @return + # converted data to pretty json + dispatch :to_json_pretty do + param 'Variant[Hash, Array]', :data + optional_param 'Optional[Boolean]', :skip_undef + optional_param 'Struct[{ +indent => Optional[String], +space => Optional[String], +space_before => Optional[String], +object_nl => Optional[String], +array_nl => Optional[String], +allow_nan => Optional[Boolean], +max_nesting => Optional[Integer[-1,default]], +}]', :opts + end + + def to_json_pretty(data, skip_undef = false, opts = nil) + # It's not possible to make an abstract type that can be either a boolean + # false or an integer, so we use -1 as the falsey value + if opts + opts = opts.transform_keys(&:to_sym) + + opts[:max_nesting] = false if opts[:max_nesting] == -1 + end + + data = data.compact if skip_undef && (data.is_a?(Array) || Hash) + # Call ::JSON to ensure it references the JSON library from Ruby's standard library + # instead of a random JSON namespace that might be in scope due to user code. + JSON.pretty_generate(data, opts) << "\n" + end +end diff --git a/lib/puppet/functions/stdlib/to_python.rb b/lib/puppet/functions/stdlib/to_python.rb new file mode 100644 index 000000000..59e3535b1 --- /dev/null +++ b/lib/puppet/functions/stdlib/to_python.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +# @summary +# Convert an object into a String containing its Python representation +# +# @example how to output Python +# # output Python to a file +# $listen = '0.0.0.0' +# $port = 8000 +# file { '/opt/acme/etc/settings.py': +# content => inline_epp(@("SETTINGS")), +# LISTEN = <%= stdlib::to_python($listen) %> +# PORT = <%= stdlib::to_python($mailserver) %> +# | SETTINGS +# } + +Puppet::Functions.create_function(:'stdlib::to_python') do + # @param object + # The object to be converted + # + # @return [String] + # The String representation of the object + dispatch :to_python do + param 'Any', :object + end + + def to_python(object) + serialized = Puppet::Pops::Serialization::ToDataConverter.convert(object, rich_data: true) + serialized_to_python(serialized) + end + + def serialized_to_python(serialized) + case serialized + when true then 'True' + when false then 'False' + when nil then 'None' + when Array then "[#{serialized.map { |x| serialized_to_python(x) }.join(', ')}]" + when Hash then "{#{serialized.map { |k, v| "#{serialized_to_python(k)}: #{serialized_to_python(v)}" }.join(', ')}}" + else serialized.inspect + end + end +end diff --git a/lib/puppet/functions/stdlib/to_ruby.rb b/lib/puppet/functions/stdlib/to_ruby.rb new file mode 100644 index 000000000..0e8c8d6cf --- /dev/null +++ b/lib/puppet/functions/stdlib/to_ruby.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +# @summary +# Convert an object into a String containing its Ruby representation +# +# @example how to output Ruby +# # output Ruby to a file +# $listen = '0.0.0.0' +# $port = 8000 +# file { '/opt/acme/etc/settings.rb': +# content => inline_epp(@("SETTINGS")), +# LISTEN = <%= stdlib::to_ruby($listen) %> +# PORT = <%= stdlib::to_ruby($mailserver) %> +# | SETTINGS +# } + +Puppet::Functions.create_function(:'stdlib::to_ruby') do + # @param object + # The object to be converted + # + # @return [String] + # The String representation of the object + dispatch :to_ruby do + param 'Any', :object + end + + def to_ruby(object) + serialized = Puppet::Pops::Serialization::ToDataConverter.convert(object, rich_data: true) + serialized_to_ruby(serialized) + end + + def serialized_to_ruby(serialized) + case serialized + when Array then "[#{serialized.map { |x| serialized_to_ruby(x) }.join(', ')}]" + when Hash then "{#{serialized.map { |k, v| "#{serialized_to_ruby(k)} => #{serialized_to_ruby(v)}" }.join(', ')}}" + else serialized.inspect + end + end +end diff --git a/lib/puppet/functions/stdlib/to_toml.rb b/lib/puppet/functions/stdlib/to_toml.rb new file mode 100644 index 000000000..c94b6ea4a --- /dev/null +++ b/lib/puppet/functions/stdlib/to_toml.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +require_relative '../../../puppet_x/stdlib/toml_dumper' + +# @summary Convert a data structure and output to TOML. +Puppet::Functions.create_function(:'stdlib::to_toml') do + # @param data Data structure which needs to be converted into TOML + # @return [String] Converted data as TOML string + # @example How to output TOML to a file + # file { '/tmp/config.toml': + # ensure => file, + # content => stdlib::to_toml($myhash), + # } + dispatch :to_toml do + required_param 'Hash', :data + return_type 'String' + end + + def to_toml(data) + PuppetX::Stdlib::TomlDumper.new(data).toml_str + end +end diff --git a/lib/puppet/functions/stdlib/to_yaml.rb b/lib/puppet/functions/stdlib/to_yaml.rb new file mode 100644 index 000000000..22b134017 --- /dev/null +++ b/lib/puppet/functions/stdlib/to_yaml.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require 'yaml' +# @summary +# Convert a data structure and output it as YAML +Puppet::Functions.create_function(:'stdlib::to_yaml') do + # @param data + # The data you want to convert to YAML + # @param options + # A hash of options that will be passed to Ruby's Psych library. Note, this could change between Puppet versions, but at time of writing these are `line_width`, `indentation`, and `canonical`. + # + # @example Output YAML to a file + # file { '/tmp/my.yaml': + # ensure => file, + # content => stdlib::to_yaml($myhash), + # } + # @example Use options to control the output format + # file { '/tmp/my.yaml': + # ensure => file, + # content => stdlib::to_yaml($myhash, {indentation => 4}) + # } + # + # @return [String] The YAML document + dispatch :to_yaml do + param 'Any', :data + optional_param 'Hash', :options + end + + def to_yaml(data, options = {}) + data.to_yaml(options.transform_keys(&:to_sym)) + end +end diff --git a/lib/puppet/functions/stdlib/type_of.rb b/lib/puppet/functions/stdlib/type_of.rb new file mode 100644 index 000000000..043908fda --- /dev/null +++ b/lib/puppet/functions/stdlib/type_of.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +# @summary +# Returns the type of the passed value. +# +# @example how to compare values' types +# # compare the types of two values +# if stdlib::type_of($first_value) != stdlib::type_of($second_value) { fail("first_value and second_value are different types") } +# @example how to compare against an abstract type +# unless stdlib::type_of($first_value) <= Numeric { fail("first_value must be Numeric") } +# unless stdlib::type_of{$first_value) <= Collection[1] { fail("first_value must be an Array or Hash, and contain at least one element") } +# +# See the documentation for "The Puppet Type System" for more information about types. +# See the `assert_type()` function for flexible ways to assert the type of a value. +# +# The built-in type() function in puppet is generally preferred over this function +# this function is provided for backwards compatibility. +Puppet::Functions.create_function(:'stdlib::type_of') do + # @return [String] + # the type of the passed value + # + # @param value + def type_of(value) + Puppet::Pops::Types::TypeCalculator.infer_set(value) + end +end diff --git a/lib/puppet/functions/stdlib/validate_domain_name.rb b/lib/puppet/functions/stdlib/validate_domain_name.rb new file mode 100644 index 000000000..ff0779340 --- /dev/null +++ b/lib/puppet/functions/stdlib/validate_domain_name.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +# @summary +# Validate that all values passed are syntactically correct domain names. +# Fail compilation if any value fails this check. +Puppet::Functions.create_function(:'stdlib::validate_domain_name') do + # @param values A domain name or an array of domain names to check + # + # @return [Undef] + # passes when the given values are syntactically correct domain names or raise an error when they are not and fails compilation + # + # @example Passing examples + # $my_domain_name = 'server.domain.tld' + # stdlib::validate_domain_name($my_domain_name) + # stdlib::validate_domain_name('domain.tld', 'puppet.com', $my_domain_name) + # stdlib::validate_domain_name('www.example.2com') + # + # @example Failing examples (causing compilation to abort) + # stdlib::validate_domain_name(1) + # stdlib::validate_domain_name(true) + # stdlib::validate_domain_name('invalid domain') + # stdlib::validate_domain_name('-foo.example.com') + dispatch :validate_domain_name do + repeated_param 'Variant[Stdlib::Fqdn, Stdlib::Dns::Zone]', :values + end + + def validate_domain_name(*args) + assert_arg_count(args) + end + + def assert_arg_count(args) + raise(ArgumentError, 'stdlib::validate_domain_name(): Wrong number of arguments need at least one') if args.empty? + end +end diff --git a/lib/puppet/functions/stdlib/validate_email_address.rb b/lib/puppet/functions/stdlib/validate_email_address.rb new file mode 100644 index 000000000..a07c85dcc --- /dev/null +++ b/lib/puppet/functions/stdlib/validate_email_address.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +# @summary +# Validate that all values passed are valid email addresses. +# Fail compilation if any value fails this check. +Puppet::Functions.create_function(:'stdlib::validate_email_address') do + # @param values An e-mail address or an array of e-mail addresses to check + # + # @return [Undef] + # Fail compilation if any value fails this check. + # + # @example Passing examples + # $my_email = "waldo@gmail.com" + # stdlib::validate_email_address($my_email) + # stdlib::validate_email_address("bob@gmail.com", "alice@gmail.com", $my_email) + # + # @example Failing examples (causing compilation to abort) + # $some_array = [ 'bad_email@/d/efdf.com' ] + # stdlib::validate_email_address($some_array) + dispatch :validate_email_address do + repeated_param 'Stdlib::Email', :values + end + + def validate_email_address(*args) + assert_arg_count(args) + end + + def assert_arg_count(args) + raise(ArgumentError, 'stdlib::validate_email_address(): Wrong number of arguments need at least one') if args.empty? + end +end diff --git a/lib/puppet/functions/stdlib/xml_encode.rb b/lib/puppet/functions/stdlib/xml_encode.rb new file mode 100644 index 000000000..6c580b749 --- /dev/null +++ b/lib/puppet/functions/stdlib/xml_encode.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +# @summary Encode strings for XML files +# +# This function can encode strings such that they can be used directly in XML files. +# It supports encoding for both XML text (CharData) or attribute values (AttValue). +Puppet::Functions.create_function(:'stdlib::xml_encode') do + # @param str The string to encode + # @param type Whether to encode for text or an attribute + # @return Returns the encoded CharData or AttValue string suitable for use in XML + # @example Creating an XML file from a template + # file { '/path/to/config.xml': + # ensure => file, + # content => epp( + # 'mymodule/config.xml.epp', + # { + # password => $password.stdlib::xml_encode, + # }, + # ), + # } + dispatch :xml_encode do + param 'String', :str + optional_param "Enum['text','attr']", :type + return_type 'String' + end + + def xml_encode(str, type = 'text') + str.encode(xml: type.to_sym) + end +end diff --git a/lib/puppet/functions/time.rb b/lib/puppet/functions/time.rb new file mode 100644 index 000000000..6268c1f7b --- /dev/null +++ b/lib/puppet/functions/time.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +# @summary DEPRECATED. Use the native Puppet fuctionality instead of this function. eg `Integer(Timestamp().strftime('%s'))` +Puppet::Functions.create_function(:time) do + dispatch :call_puppet_function do + repeated_param 'Any', :args + end + def call_puppet_function(*args) + # Note, `stdlib::time` calls `deprecation`, so we don't also do that here. + call_function('stdlib::time', *args) + end +end diff --git a/lib/puppet/functions/to_json.rb b/lib/puppet/functions/to_json.rb new file mode 100644 index 000000000..82c0534c2 --- /dev/null +++ b/lib/puppet/functions/to_json.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# THIS FILE WAS GENERATED BY `rake regenerate_unamespaced_shims` + +# @summary DEPRECATED. Use the namespaced function [`stdlib::to_json`](#stdlibto_json) instead. +Puppet::Functions.create_function(:to_json) do + dispatch :deprecation_gen do + repeated_param 'Any', :args + end + def deprecation_gen(*args) + call_function('deprecation', 'to_json', 'This function is deprecated, please use stdlib::to_json instead.', false) + call_function('stdlib::to_json', *args) + end +end diff --git a/lib/puppet/functions/to_json_pretty.rb b/lib/puppet/functions/to_json_pretty.rb new file mode 100644 index 000000000..9f6dc5e5d --- /dev/null +++ b/lib/puppet/functions/to_json_pretty.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# THIS FILE WAS GENERATED BY `rake regenerate_unamespaced_shims` + +# @summary DEPRECATED. Use the namespaced function [`stdlib::to_json_pretty`](#stdlibto_json_pretty) instead. +Puppet::Functions.create_function(:to_json_pretty) do + dispatch :deprecation_gen do + repeated_param 'Any', :args + end + def deprecation_gen(*args) + call_function('deprecation', 'to_json_pretty', 'This function is deprecated, please use stdlib::to_json_pretty instead.', false) + call_function('stdlib::to_json_pretty', *args) + end +end diff --git a/lib/puppet/functions/to_python.rb b/lib/puppet/functions/to_python.rb new file mode 100644 index 000000000..95045c1bb --- /dev/null +++ b/lib/puppet/functions/to_python.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# THIS FILE WAS GENERATED BY `rake regenerate_unamespaced_shims` + +# @summary DEPRECATED. Use the namespaced function [`stdlib::to_python`](#stdlibto_python) instead. +Puppet::Functions.create_function(:to_python) do + dispatch :deprecation_gen do + repeated_param 'Any', :args + end + def deprecation_gen(*args) + call_function('deprecation', 'to_python', 'This function is deprecated, please use stdlib::to_python instead.', false) + call_function('stdlib::to_python', *args) + end +end diff --git a/lib/puppet/functions/to_ruby.rb b/lib/puppet/functions/to_ruby.rb new file mode 100644 index 000000000..c2d919c9b --- /dev/null +++ b/lib/puppet/functions/to_ruby.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# THIS FILE WAS GENERATED BY `rake regenerate_unamespaced_shims` + +# @summary DEPRECATED. Use the namespaced function [`stdlib::to_ruby`](#stdlibto_ruby) instead. +Puppet::Functions.create_function(:to_ruby) do + dispatch :deprecation_gen do + repeated_param 'Any', :args + end + def deprecation_gen(*args) + call_function('deprecation', 'to_ruby', 'This function is deprecated, please use stdlib::to_ruby instead.', false) + call_function('stdlib::to_ruby', *args) + end +end diff --git a/lib/puppet/functions/to_toml.rb b/lib/puppet/functions/to_toml.rb new file mode 100644 index 000000000..6de87678e --- /dev/null +++ b/lib/puppet/functions/to_toml.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# THIS FILE WAS GENERATED BY `rake regenerate_unamespaced_shims` + +# @summary DEPRECATED. Use the namespaced function [`stdlib::to_toml`](#stdlibto_toml) instead. +Puppet::Functions.create_function(:to_toml) do + dispatch :deprecation_gen do + repeated_param 'Any', :args + end + def deprecation_gen(*args) + call_function('deprecation', 'to_toml', 'This function is deprecated, please use stdlib::to_toml instead.', false) + call_function('stdlib::to_toml', *args) + end +end diff --git a/lib/puppet/functions/to_yaml.rb b/lib/puppet/functions/to_yaml.rb new file mode 100644 index 000000000..980748bfa --- /dev/null +++ b/lib/puppet/functions/to_yaml.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# THIS FILE WAS GENERATED BY `rake regenerate_unamespaced_shims` + +# @summary DEPRECATED. Use the namespaced function [`stdlib::to_yaml`](#stdlibto_yaml) instead. +Puppet::Functions.create_function(:to_yaml) do + dispatch :deprecation_gen do + repeated_param 'Any', :args + end + def deprecation_gen(*args) + call_function('deprecation', 'to_yaml', 'This function is deprecated, please use stdlib::to_yaml instead.', false) + call_function('stdlib::to_yaml', *args) + end +end diff --git a/lib/puppet/functions/type_of.rb b/lib/puppet/functions/type_of.rb index 02cdd4db7..414b361d0 100644 --- a/lib/puppet/functions/type_of.rb +++ b/lib/puppet/functions/type_of.rb @@ -1,17 +1,14 @@ -# Returns the type when passed a value. -# -# @example how to compare values' types -# # compare the types of two values -# if type_of($first_value) != type_of($second_value) { fail("first_value and second_value are different types") } -# @example how to compare against an abstract type -# unless type_of($first_value) <= Numeric { fail("first_value must be Numeric") } -# unless type_of{$first_value) <= Collection[1] { fail("first_value must be an Array or Hash, and contain at least one element") } -# -# See the documentation for "The Puppet Type System" for more information about types. -# See the `assert_type()` function for flexible ways to assert the type of a value. -# +# frozen_string_literal: true + +# THIS FILE WAS GENERATED BY `rake regenerate_unamespaced_shims` + +# @summary DEPRECATED. Use the namespaced function [`stdlib::type_of`](#stdlibtype_of) instead. Puppet::Functions.create_function(:type_of) do - def type_of(value) - Puppet::Pops::Types::TypeCalculator.infer_set(value) + dispatch :deprecation_gen do + repeated_param 'Any', :args + end + def deprecation_gen(*args) + call_function('deprecation', 'type_of', 'This function is deprecated, please use stdlib::type_of instead.', false) + call_function('stdlib::type_of', *args) end end diff --git a/lib/puppet/functions/validate_domain_name.rb b/lib/puppet/functions/validate_domain_name.rb new file mode 100644 index 000000000..04ca517a9 --- /dev/null +++ b/lib/puppet/functions/validate_domain_name.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# THIS FILE WAS GENERATED BY `rake regenerate_unamespaced_shims` + +# @summary DEPRECATED. Use the namespaced function [`stdlib::validate_domain_name`](#stdlibvalidate_domain_name) instead. +Puppet::Functions.create_function(:validate_domain_name) do + dispatch :deprecation_gen do + repeated_param 'Any', :args + end + def deprecation_gen(*args) + call_function('deprecation', 'validate_domain_name', 'This function is deprecated, please use stdlib::validate_domain_name instead.', false) + call_function('stdlib::validate_domain_name', *args) + end +end diff --git a/lib/puppet/functions/validate_email_address.rb b/lib/puppet/functions/validate_email_address.rb new file mode 100644 index 000000000..bbc21d648 --- /dev/null +++ b/lib/puppet/functions/validate_email_address.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# THIS FILE WAS GENERATED BY `rake regenerate_unamespaced_shims` + +# @summary DEPRECATED. Use the namespaced function [`stdlib::validate_email_address`](#stdlibvalidate_email_address) instead. +Puppet::Functions.create_function(:validate_email_address) do + dispatch :deprecation_gen do + repeated_param 'Any', :args + end + def deprecation_gen(*args) + call_function('deprecation', 'validate_email_address', 'This function is deprecated, please use stdlib::validate_email_address instead.', false) + call_function('stdlib::validate_email_address', *args) + end +end diff --git a/lib/puppet/functions/validate_legacy.rb b/lib/puppet/functions/validate_legacy.rb new file mode 100644 index 000000000..fb8d9c687 --- /dev/null +++ b/lib/puppet/functions/validate_legacy.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true + +# @summary +# **Deprecated:** Validate a value against both the target_type (new). +Puppet::Functions.create_function(:validate_legacy) do + # The function checks a value against both the target_type (new). + # @param scope + # The main value that will be passed to the method + # @param target_type + # @param function_name + # Unused + # @param value + # @param args + # Any additional values that are to be passed to the method + # @return + # A boolean value (`true` or `false`) returned from the called function. + dispatch :validate_legacy do + param 'Any', :scope + param 'Type', :target_type + param 'String', :function_name + param 'Any', :value + repeated_param 'Any', :args + end + + # @param scope + # The main value that will be passed to the method + # @param type_string + # @param function_name + # Unused + # @param value + # @param args Any additional values that are to be passed to the method + # @return Legacy validation method + # + dispatch :validate_legacy_s do + param 'Any', :scope + param 'String', :type_string + param 'String', :function_name + param 'Any', :value + repeated_param 'Any', :args + end + + # Workaround PUP-4438 (fixed: https://github.com/puppetlabs/puppet/commit/e01c4dc924cd963ff6630008a5200fc6a2023b08#diff- + # c937cc584953271bb3d3b3c2cb141790R221) to support puppet < 4.1.0 and puppet < 3.8.1. + def call(scope, *args) + manipulated_args = [scope] + args + self.class.dispatcher.dispatch(self, scope, manipulated_args) + end + + def validate_legacy_s(scope, type_string, *args) + t = Puppet::Pops::Types::TypeParser.new.parse(type_string, scope) + validate_legacy(scope, t, *args) + end + + def validate_legacy(_scope, target_type, _function_name, value, *_prev_args) + call_function('deprecation', 'validate_legacy', 'This method is deprecated, please use Puppet data types to validate parameters') + if assert_type(target_type, value) + # "Silently" passes + else + inferred_type = Puppet::Pops::Types::TypeCalculator.infer_set(value) + error_msg = Puppet::Pops::Types::TypeMismatchDescriber.new.describe_mismatch("validate_legacy(#{target_type}, ...)", target_type, inferred_type) + call_function('fail', error_msg) + end + end + + def assert_type(type, value) + Puppet::Pops::Types::TypeCalculator.instance?(type, value) + end +end diff --git a/lib/puppet/parser/functions/abs.rb b/lib/puppet/parser/functions/abs.rb deleted file mode 100644 index 11d2d7fea..000000000 --- a/lib/puppet/parser/functions/abs.rb +++ /dev/null @@ -1,36 +0,0 @@ -# -# abs.rb -# - -module Puppet::Parser::Functions - newfunction(:abs, :type => :rvalue, :doc => <<-EOS - Returns the absolute value of a number, for example -34.56 becomes - 34.56. Takes a single integer and float value as an argument. - EOS - ) do |arguments| - - raise(Puppet::ParseError, "abs(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 - - value = arguments[0] - - # Numbers in Puppet are often string-encoded which is troublesome ... - if value.is_a?(String) - if value.match(/^-?(?:\d+)(?:\.\d+){1}$/) - value = value.to_f - elsif value.match(/^-?\d+$/) - value = value.to_i - else - raise(Puppet::ParseError, 'abs(): Requires float or ' + - 'integer to work with') - end - end - - # We have numeric value to handle ... - result = value.abs - - return result - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/any2array.rb b/lib/puppet/parser/functions/any2array.rb index e71407e89..81efd77d7 100644 --- a/lib/puppet/parser/functions/any2array.rb +++ b/lib/puppet/parser/functions/any2array.rb @@ -1,31 +1,54 @@ +# frozen_string_literal: true + # # any2array.rb # - module Puppet::Parser::Functions - newfunction(:any2array, :type => :rvalue, :doc => <<-EOS -This converts any object to an array containing that object. Empty argument -lists are converted to an empty array. Arrays are left untouched. Hashes are -converted to arrays of alternating keys and values. - EOS + newfunction(:any2array, type: :rvalue, doc: <<-DOC + @summary + This converts any object to an array containing that object. + + Empty argument lists are converted to an empty array. Arrays are left + untouched. Hashes are converted to arrays of alternating keys and values. + + > *Note:* + since Puppet 5.0.0 it is possible to create new data types for almost any + datatype using the type system and the built-in + [`Array.new`](https://puppet.com/docs/puppet/latest/function.html#conversion-to-array-and-tuple) + function is used to create a new Array.. + + ``` + $hsh = {'key' => 42, 'another-key' => 100} + notice(Array($hsh)) + ``` + + Would notice `[['key', 42], ['another-key', 100]]` + + The Array data type also has a special mode to "create an array if not already an array" + + ``` + notice(Array({'key' => 42, 'another-key' => 100}, true)) + ``` + + Would notice `[{'key' => 42, 'another-key' => 100}]`, as the `true` flag prevents the hash from being + transformed into an array. + + @return [Array] The new array containing the given object + DOC ) do |arguments| + return [] if arguments.empty? - if arguments.empty? - return [] - end + return arguments unless arguments.length == 1 + return arguments[0] if arguments[0].is_a?(Array) + return [] if arguments == [''] - if arguments.length == 1 - if arguments[0].kind_of?(Array) - return arguments[0] - elsif arguments[0].kind_of?(Hash) - result = [] - arguments[0].each do |key, value| - result << key << value - end - return result - end + if arguments[0].is_a?(Hash) + result = [] + arguments[0].each do |key, value| + result << key << value + end + return result end - return arguments end end diff --git a/lib/puppet/parser/functions/any2bool.rb b/lib/puppet/parser/functions/any2bool.rb new file mode 100644 index 000000000..f32e3daea --- /dev/null +++ b/lib/puppet/parser/functions/any2bool.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +# +# any2bool.rb +# +module Puppet::Parser::Functions + newfunction(:any2bool, type: :rvalue, doc: <<-DOC + @summary + Converts 'anything' to a boolean. + + In practise it does the following: + * Strings such as Y,y,1,T,t,TRUE,yes,'true' will return true + * Strings such as 0,F,f,N,n,FALSE,no,'false' will return false + * Booleans will just return their original value + * Number (or a string representation of a number) > 0 will return true, otherwise false + * undef will return false + * Anything else will return true + + Also see the built-in [`Boolean.new`](https://puppet.com/docs/puppet/latest/function.html#conversion-to-boolean) + function. + + @return [Boolean] The boolean value of the object that was given + DOC + ) do |arguments| + raise(Puppet::ParseError, "any2bool(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty? + + # If argument is already Boolean, return it + return arguments[0] if !!arguments[0] == arguments[0] # rubocop:disable Style/DoubleNegation : Could not find a better way to check if a boolean + + arg = arguments[0] + + return false if arg.nil? + + return false if arg == :undef + + valid_float = begin + !!Float(arg) # rubocop:disable Style/DoubleNegation : Could not find a better way to check if a boolean + rescue StandardError + false + end + + return function_num2bool([arguments[0]]) if arg.is_a?(Numeric) + + if arg.is_a?(String) + return function_num2bool([arguments[0]]) if valid_float + + return function_str2bool([arguments[0]]) + end + + return true + end +end + +# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/assert_private.rb b/lib/puppet/parser/functions/assert_private.rb index 66c79cce3..a5f420984 100644 --- a/lib/puppet/parser/functions/assert_private.rb +++ b/lib/puppet/parser/functions/assert_private.rb @@ -1,21 +1,25 @@ +# frozen_string_literal: true + # # assert_private.rb # - module Puppet::Parser::Functions - newfunction(:assert_private, :doc => <<-'EOS' - Sets the current class or definition as private. + newfunction(:assert_private, doc: <<-DOC + @summary + Sets the current class or definition as private. + + @return + set the current class or definition as private. + Calling the class or definition from outside the current module will fail. - EOS + DOC ) do |args| - - raise(Puppet::ParseError, "assert_private(): Wrong number of arguments "+ - "given (#{args.size}}) for 0 or 1)") if args.size > 1 + raise(Puppet::ParseError, "assert_private(): Wrong number of arguments given (#{args.size}}) for 0 or 1)") if args.size > 1 scope = self if scope.lookupvar('module_name') != scope.lookupvar('caller_module_name') message = nil - if args[0] and args[0].is_a? String + if args[0].is_a?(String) message = args[0] else manifest_name = scope.source.name diff --git a/lib/puppet/parser/functions/base64.rb b/lib/puppet/parser/functions/base64.rb index 617ba31b6..b65458e6e 100644 --- a/lib/puppet/parser/functions/base64.rb +++ b/lib/puppet/parser/functions/base64.rb @@ -1,35 +1,79 @@ +# frozen_string_literal: true + +# Please note: This function is an implementation of a Ruby class and as such may not be entirely UTF8 compatible. To ensure compatibility please use this function with Ruby 2.4.0 or greater - https://bugs.ruby-lang.org/issues/10085. module Puppet::Parser::Functions + newfunction(:base64, type: :rvalue, doc: <<-DOC) do |args| + @summary + Base64 encode or decode a string based on the command and the string submitted + + @example Example usage + + Encode and decode a string + + $encodestring = base64('encode', 'thestring') + $decodestring = base64('decode', 'dGhlc3RyaW5n') + + Explicitly define encode/decode method: default, strict, urlsafe + + $method = 'default' + $encodestring = base64('encode', 'thestring', $method) + $decodestring = base64('decode', 'dGhlc3RyaW5n', $method) - newfunction(:base64, :type => :rvalue, :doc => <<-'ENDHEREDOC') do |args| + Encode a string as if it was binary - Base64 encode or decode a string based on the command and the string submitted + $encodestring = String(Binary('thestring', '%s')) - Usage: + Decode a Binary assuming it is an UTF-8 String - $encodestring = base64('encode','thestring') - $decodestring = base64('decode','dGhlc3RyaW5n') + $decodestring = String(Binary("dGhlc3RyaW5n"), "%s") - ENDHEREDOC + > **Note:* + Since Puppet 4.8.0, the Binary data type can be used to produce base 64 encoded strings. + See the `new()` function for the Binary and String types for documentation. Also see `binary_file()` + function for reading a file with binary (non UTF-8) content. + + @return [String] The encoded/decoded value + DOC require 'base64' - raise Puppet::ParseError, ("base64(): Wrong number of arguments (#{args.length}; must be = 2)") unless args.length == 2 + raise Puppet::ParseError, "base64(): Wrong number of arguments (#{args.length}; must be >= 2)" unless args.length >= 2 - actions = ['encode','decode'] + actions = ['encode', 'decode'] - unless actions.include?(args[0]) - raise Puppet::ParseError, ("base64(): the first argument must be one of 'encode' or 'decode'") - end + raise Puppet::ParseError, "base64(): the first argument must be one of 'encode' or 'decode'" unless actions.include?(args[0]) - unless args[1].is_a?(String) - raise Puppet::ParseError, ("base64(): the second argument must be a string to base64") - end + raise Puppet::ParseError, 'base64(): the second argument must be a string to base64' unless args[1].is_a?(String) + + method = ['default', 'strict', 'urlsafe'] + + chosen_method = if args.length <= 2 + 'default' + else + args[2] + end + + raise Puppet::ParseError, "base64(): the third argument must be one of 'default', 'strict', or 'urlsafe'" unless method.include?(chosen_method) case args[0] - when 'encode' + when 'encode' + case chosen_method + when 'default' result = Base64.encode64(args[1]) - when 'decode' + when 'strict' + result = Base64.strict_encode64(args[1]) + when 'urlsafe' + result = Base64.urlsafe_encode64(args[1]) + end + when 'decode' + case chosen_method + when 'default' result = Base64.decode64(args[1]) + when 'strict' + result = Base64.strict_decode64(args[1]) + when 'urlsafe' + result = Base64.urlsafe_decode64(args[1]) + end end return result diff --git a/lib/puppet/parser/functions/basename.rb b/lib/puppet/parser/functions/basename.rb index f7e443847..b7aa80b38 100644 --- a/lib/puppet/parser/functions/basename.rb +++ b/lib/puppet/parser/functions/basename.rb @@ -1,30 +1,25 @@ -module Puppet::Parser::Functions - newfunction(:basename, :type => :rvalue, :doc => <<-EOS - Strips directory (and optional suffix) from a filename - EOS - ) do |arguments| - - if arguments.size < 1 then - raise(Puppet::ParseError, "basename(): No arguments given") - elsif arguments.size > 2 then - raise(Puppet::ParseError, "basename(): Too many arguments given (#{arguments.size})") - else +# frozen_string_literal: true - unless arguments[0].is_a?(String) - raise(Puppet::ParseError, 'basename(): Requires string as first argument') - end - - if arguments.size == 1 then - rv = File.basename(arguments[0]) - elsif arguments.size == 2 then +# +# basename.rb +# +module Puppet::Parser::Functions + newfunction(:basename, type: :rvalue, doc: <<-DOC + @summary + Strips directory (and optional suffix) from a filename - unless arguments[1].is_a?(String) - raise(Puppet::ParseError, 'basename(): Requires string as second argument') - end + @return [String] The stripped filename + DOC + ) do |arguments| + raise(Puppet::ParseError, 'basename(): No arguments given') if arguments.empty? + raise(Puppet::ParseError, "basename(): Too many arguments given (#{arguments.size})") if arguments.size > 2 + raise(Puppet::ParseError, 'basename(): Requires string as first argument') unless arguments[0].is_a?(String) - rv = File.basename(arguments[0], arguments[1]) - end + rv = File.basename(arguments[0]) if arguments.size == 1 + if arguments.size == 2 + raise(Puppet::ParseError, 'basename(): Requires string as second argument') unless arguments[1].is_a?(String) + rv = File.basename(arguments[0], arguments[1]) end return rv diff --git a/lib/puppet/parser/functions/bool2num.rb b/lib/puppet/parser/functions/bool2num.rb index 6ad6cf4e8..066bb2b10 100644 --- a/lib/puppet/parser/functions/bool2num.rb +++ b/lib/puppet/parser/functions/bool2num.rb @@ -1,18 +1,36 @@ +# frozen_string_literal: true + # # bool2num.rb # - module Puppet::Parser::Functions - newfunction(:bool2num, :type => :rvalue, :doc => <<-EOS - Converts a boolean to a number. Converts the values: + newfunction(:bool2num, type: :rvalue, doc: <<-DOC + @summary + Converts a boolean to a number. + + Converts the values: + ``` false, f, 0, n, and no to 0 true, t, 1, y, and yes to 1 + ``` Requires a single boolean or string as an input. - EOS - ) do |arguments| - raise(Puppet::ParseError, "bool2num(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 + > *Note:* + since Puppet 5.0.0 it is possible to create new data types for almost any + datatype using the type system and the built-in + [`Numeric.new`](https://puppet.com/docs/puppet/latest/function.html#conversion-to-numeric), + [`Integer.new`](https://puppet.com/docs/puppet/latest/function.html#conversion-to-integer), and + [`Float.new`](https://puppet.com/docs/puppet/latest/function.html#conversion-to-float) + function are used to convert to numeric values. + ``` + notice(Integer(false)) # Notices 0 + notice(Float(true)) # Notices 1.0 + ``` + + @return [Integer] The converted value as a number + DOC + ) do |arguments| + raise(Puppet::ParseError, "bool2num(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty? value = function_str2bool([arguments[0]]) diff --git a/lib/puppet/parser/functions/bool2str.rb b/lib/puppet/parser/functions/bool2str.rb index 7e364747c..f94c37e64 100644 --- a/lib/puppet/parser/functions/bool2str.rb +++ b/lib/puppet/parser/functions/bool2str.rb @@ -1,28 +1,45 @@ +# frozen_string_literal: true + # # bool2str.rb # - module Puppet::Parser::Functions - newfunction(:bool2str, :type => :rvalue, :doc => <<-EOS - Converts a boolean to a string using optionally supplied arguments. The - optional second and third arguments represent what true and false will be + newfunction(:bool2str, type: :rvalue, doc: <<-DOC + @summary + Converts a boolean to a string using optionally supplied arguments. + + The optional second and third arguments represent what true and false will be converted to respectively. If only one argument is given, it will be converted from a boolean to a string containing 'true' or 'false'. - *Examples:* + @return + The converted value to string of the given Boolean - bool2str(true) => 'true' - bool2str(true, 'yes', 'no') => 'yes' - bool2str(false, 't', 'f') => 'f' + **Examples of usage** + + ``` + bool2str(true) => 'true' + bool2str(true, 'yes', 'no') => 'yes' + bool2str(false, 't', 'f') => 'f' + ``` Requires a single boolean as an input. - EOS - ) do |arguments| - unless arguments.size == 1 or arguments.size == 3 - raise(Puppet::ParseError, "bool2str(): Wrong number of arguments " + - "given (#{arguments.size} for 3)") - end + > *Note:* + since Puppet 5.0.0 it is possible to create new data types for almost any + datatype using the type system and the built-in + [`String.new`](https://puppet.com/docs/puppet/latest/function.html#boolean-to-string) + function is used to convert to String with many different format options. + + ``` + notice(String(false)) # Notices 'false' + notice(String(true)) # Notices 'true' + notice(String(false, '%y')) # Notices 'yes' + notice(String(true, '%y')) # Notices 'no' + ``` + DOC + ) do |arguments| + raise(Puppet::ParseError, "bool2str(): Wrong number of arguments given (#{arguments.size} for 3)") unless arguments.size == 1 || arguments.size == 3 value = arguments[0] true_string = arguments[1] || 'true' @@ -30,13 +47,9 @@ module Puppet::Parser::Functions klass = value.class # We can have either true or false, and nothing else - unless [FalseClass, TrueClass].include?(klass) - raise(Puppet::ParseError, 'bool2str(): Requires a boolean to work with') - end + raise(Puppet::ParseError, 'bool2str(): Requires a boolean to work with') unless [FalseClass, TrueClass].include?(klass) - unless [true_string, false_string].all?{|x| x.kind_of?(String)} - raise(Puppet::ParseError, "bool2str(): Requires strings to convert to" ) - end + raise(Puppet::ParseError, 'bool2str(): Requires strings to convert to') unless [true_string, false_string].all?(String) return value ? true_string : false_string end diff --git a/lib/puppet/parser/functions/camelcase.rb b/lib/puppet/parser/functions/camelcase.rb deleted file mode 100644 index d7f43f7a7..000000000 --- a/lib/puppet/parser/functions/camelcase.rb +++ /dev/null @@ -1,33 +0,0 @@ -# -# camelcase.rb -# - -module Puppet::Parser::Functions - newfunction(:camelcase, :type => :rvalue, :doc => <<-EOS -Converts the case of a string or all strings in an array to camel case. - EOS - ) do |arguments| - - raise(Puppet::ParseError, "camelcase(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 - - value = arguments[0] - klass = value.class - - unless [Array, String].include?(klass) - raise(Puppet::ParseError, 'camelcase(): Requires either ' + - 'array or string to work with') - end - - if value.is_a?(Array) - # Numbers in Puppet are often string-encoded which is troublesome ... - result = value.collect { |i| i.is_a?(String) ? i.split('_').map{|e| e.capitalize}.join : i } - else - result = value.split('_').map{|e| e.capitalize}.join - end - - return result - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/capitalize.rb b/lib/puppet/parser/functions/capitalize.rb deleted file mode 100644 index 98b2d16c9..000000000 --- a/lib/puppet/parser/functions/capitalize.rb +++ /dev/null @@ -1,33 +0,0 @@ -# -# capitalize.rb -# - -module Puppet::Parser::Functions - newfunction(:capitalize, :type => :rvalue, :doc => <<-EOS - Capitalizes the first letter of a string or array of strings. - Requires either a single string or an array as an input. - EOS - ) do |arguments| - - raise(Puppet::ParseError, "capitalize(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 - - value = arguments[0] - - unless value.is_a?(Array) || value.is_a?(String) - raise(Puppet::ParseError, 'capitalize(): Requires either ' + - 'array or string to work with') - end - - if value.is_a?(Array) - # Numbers in Puppet are often string-encoded which is troublesome ... - result = value.collect { |i| i.is_a?(String) ? i.capitalize : i } - else - result = value.capitalize - end - - return result - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/ceiling.rb b/lib/puppet/parser/functions/ceiling.rb deleted file mode 100644 index 5f3b10b89..000000000 --- a/lib/puppet/parser/functions/ceiling.rb +++ /dev/null @@ -1,25 +0,0 @@ -module Puppet::Parser::Functions - newfunction(:ceiling, :type => :rvalue, :doc => <<-EOS - Returns the smallest integer greater or equal to the argument. - Takes a single numeric value as an argument. - EOS - ) do |arguments| - - raise(Puppet::ParseError, "ceiling(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size != 1 - - begin - arg = Float(arguments[0]) - rescue TypeError, ArgumentError => e - raise(Puppet::ParseError, "ceiling(): Wrong argument type " + - "given (#{arguments[0]} for Numeric)") - end - - raise(Puppet::ParseError, "ceiling(): Wrong argument type " + - "given (#{arg.class} for Numeric)") if arg.is_a?(Numeric) == false - - arg.ceil - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/chomp.rb b/lib/puppet/parser/functions/chomp.rb deleted file mode 100644 index c55841e3c..000000000 --- a/lib/puppet/parser/functions/chomp.rb +++ /dev/null @@ -1,34 +0,0 @@ -# -# chomp.rb -# - -module Puppet::Parser::Functions - newfunction(:chomp, :type => :rvalue, :doc => <<-'EOS' - Removes the record separator from the end of a string or an array of - strings, for example `hello\n` becomes `hello`. - Requires a single string or array as an input. - EOS - ) do |arguments| - - raise(Puppet::ParseError, "chomp(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 - - value = arguments[0] - - unless value.is_a?(Array) || value.is_a?(String) - raise(Puppet::ParseError, 'chomp(): Requires either ' + - 'array or string to work with') - end - - if value.is_a?(Array) - # Numbers in Puppet are often string-encoded which is troublesome ... - result = value.collect { |i| i.is_a?(String) ? i.chomp : i } - else - result = value.chomp - end - - return result - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/chop.rb b/lib/puppet/parser/functions/chop.rb deleted file mode 100644 index b24ab7856..000000000 --- a/lib/puppet/parser/functions/chop.rb +++ /dev/null @@ -1,36 +0,0 @@ -# -# chop.rb -# - -module Puppet::Parser::Functions - newfunction(:chop, :type => :rvalue, :doc => <<-'EOS' - Returns a new string with the last character removed. If the string ends - with `\r\n`, both characters are removed. Applying chop to an empty - string returns an empty string. If you wish to merely remove record - separators then you should use the `chomp` function. - Requires a string or array of strings as input. - EOS - ) do |arguments| - - raise(Puppet::ParseError, "chop(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 - - value = arguments[0] - - unless value.is_a?(Array) || value.is_a?(String) - raise(Puppet::ParseError, 'chop(): Requires either an ' + - 'array or string to work with') - end - - if value.is_a?(Array) - # Numbers in Puppet are often string-encoded which is troublesome ... - result = value.collect { |i| i.is_a?(String) ? i.chop : i } - else - result = value.chop - end - - return result - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/clamp.rb b/lib/puppet/parser/functions/clamp.rb new file mode 100644 index 000000000..d95107da4 --- /dev/null +++ b/lib/puppet/parser/functions/clamp.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +# +# clamp.rb +# +module Puppet::Parser::Functions + newfunction(:clamp, type: :rvalue, arity: -2, doc: <<-DOC + @summary + Keeps value within the range [Min, X, Max] by sort based on integer value + (parameter order doesn't matter). + + Strings are converted and compared numerically. Arrays of values are flattened + into a list for further handling. + + @example Example usage + + clamp('24', [575, 187])` returns 187. + clamp(16, 88, 661)` returns 88. + clamp([4, 3, '99'])` returns 4. + + > *Note:* + From Puppet 6.0.0 this can be done with only core Puppet like this: + `[$minval, $maxval, $value_to_clamp].sort[1]` + + @return [Array[Integer]] The sorted Array + DOC + ) do |args| + args.flatten! + + raise(Puppet::ParseError, 'clamp(): Wrong number of arguments, need three to clamp') if args.size != 3 + + # check values out + args.each do |value| + case [value.class] + when [String] + raise(Puppet::ParseError, "clamp(): Required explicit numeric (#{value}:String)") unless %r{^\d+$}.match?(value) + when [Hash] + raise(Puppet::ParseError, "clamp(): The Hash type is not allowed (#{value})") + end + end + + # convert to numeric each element + # then sort them and get a middle value + args.map(&:to_i).sort[1] + end +end diff --git a/lib/puppet/parser/functions/concat.rb b/lib/puppet/parser/functions/concat.rb index 618e62d49..af9b3eb53 100644 --- a/lib/puppet/parser/functions/concat.rb +++ b/lib/puppet/parser/functions/concat.rb @@ -1,37 +1,42 @@ +# frozen_string_literal: true + # # concat.rb # - module Puppet::Parser::Functions - newfunction(:concat, :type => :rvalue, :doc => <<-EOS -Appends the contents of multiple arrays into array 1. + newfunction(:concat, type: :rvalue, doc: <<-DOC + @summary + Appends the contents of multiple arrays into array 1. -*Example:* + @example Example usage - concat(['1','2','3'],['4','5','6'],['7','8','9']) + concat(['1','2','3'],'4') returns ['1','2','3','4'] + concat(['1','2','3'],'4',['5','6','7']) returns ['1','2','3','4','5','6','7'] -Would result in: + > *Note:* + Since Puppet 4.0, you can use the `+`` operator for concatenation of arrays and + merge of hashes, and the `<<`` operator for appending: - ['1','2','3','4','5','6','7','8','9'] - EOS - ) do |arguments| + `['1','2','3'] + ['4','5','6'] + ['7','8','9']` returns `['1','2','3','4','5','6','7','8','9']` + `[1, 2, 3] << 4` returns `[1, 2, 3, 4]` + `[1, 2, 3] << [4, 5]` returns `[1, 2, 3, [4, 5]]` + @return [Array] The single concatenated array + DOC + ) do |arguments| # Check that more than 2 arguments have been given ... - raise(Puppet::ParseError, "concat(): Wrong number of arguments " + - "given (#{arguments.size} for < 2)") if arguments.size < 2 + raise(Puppet::ParseError, "concat(): Wrong number of arguments given (#{arguments.size} for < 2)") if arguments.size < 2 a = arguments[0] # Check that the first parameter is an array - unless a.is_a?(Array) - raise(Puppet::ParseError, 'concat(): Requires array to work with') - end + raise(Puppet::ParseError, 'concat(): Requires array to work with') unless a.is_a?(Array) result = a arguments.shift arguments.each do |x| - result = result + Array(x) + result += (x.is_a?(Array) ? x : [x]) end return result diff --git a/lib/puppet/parser/functions/convert_base.rb b/lib/puppet/parser/functions/convert_base.rb index 0fcbafeaf..b2bddd36d 100644 --- a/lib/puppet/parser/functions/convert_base.rb +++ b/lib/puppet/parser/functions/convert_base.rb @@ -1,34 +1,48 @@ +# frozen_string_literal: true + +# +# convert_base.rb +# module Puppet::Parser::Functions + newfunction(:convert_base, type: :rvalue, arity: 2, doc: <<-DOC) do |args| + @summary + Converts a given integer or base 10 string representing an integer to a + specified base, as a string. + + @return + converted value as a string - newfunction(:convert_base, :type => :rvalue, :arity => 2, :doc => <<-'ENDHEREDOC') do |args| + @example Example usage - Converts a given integer or base 10 string representing an integer to a specified base, as a string. + convert_base(5, 2)` results in: `'101'` + convert_base('254', '16')` results in: `'fe'` - Usage: + > *Note:* + Since Puppet 4.5.0 this can be done with the built-in + [`String.new`](https://puppet.com/docs/puppet/latest/function.html#integer-to-string) + function and its many formatting options: - $binary_repr = convert_base(5, 2) # $binary_repr is now set to "101" - $hex_repr = convert_base("254", "16") # $hex_repr is now set to "fe" + `$binary_repr = String(5, '%b')` return `"101"` + `$hex_repr = String(254, "%x")` return `"fe"` + `$hex_repr = String(254, "%#x")` return `"0xfe"` - ENDHEREDOC + @return [String] The converted value as a String + DOC - raise Puppet::ParseError, ("convert_base(): First argument must be either a string or an integer") unless (args[0].is_a?(Integer) or args[0].is_a?(String)) - raise Puppet::ParseError, ("convert_base(): Second argument must be either a string or an integer") unless (args[1].is_a?(Integer) or args[1].is_a?(String)) + raise Puppet::ParseError, 'convert_base(): First argument must be either a string or an integer' unless args[0].is_a?(Integer) || args[0].is_a?(String) + raise Puppet::ParseError, 'convert_base(): Second argument must be either a string or an integer' unless args[1].is_a?(Integer) || args[1].is_a?(String) - if args[0].is_a?(String) - raise Puppet::ParseError, ("convert_base(): First argument must be an integer or a string corresponding to an integer in base 10") unless args[0] =~ /^[0-9]+$/ - end + raise Puppet::ParseError, 'convert_base(): First argument must be an integer or a string corresponding to an integer in base 10' if args[0].is_a?(String) && !%r{^[0-9]+$}.match?(args[0]) - if args[1].is_a?(String) - raise Puppet::ParseError, ("convert_base(): First argument must be an integer or a string corresponding to an integer in base 10") unless args[1] =~ /^[0-9]+$/ - end + raise Puppet::ParseError, 'convert_base(): First argument must be an integer or a string corresponding to an integer in base 10' if args[1].is_a?(String) && !%r{^[0-9]+$}.match?(args[1]) number_to_convert = args[0] new_base = args[1] - number_to_convert = number_to_convert.to_i() - new_base = new_base.to_i() + number_to_convert = number_to_convert.to_i + new_base = new_base.to_i - raise Puppet::ParseError, ("convert_base(): base must be at least 2 and must not be greater than 36") unless new_base >= 2 and new_base <= 36 + raise Puppet::ParseError, 'convert_base(): base must be at least 2 and must not be greater than 36' unless new_base >= 2 && new_base <= 36 return number_to_convert.to_s(new_base) end diff --git a/lib/puppet/parser/functions/count.rb b/lib/puppet/parser/functions/count.rb index 52de1b8a5..8e1f7ab98 100644 --- a/lib/puppet/parser/functions/count.rb +++ b/lib/puppet/parser/functions/count.rb @@ -1,22 +1,40 @@ +# frozen_string_literal: true + +# +# count.rb +# module Puppet::Parser::Functions - newfunction(:count, :type => :rvalue, :arity => -2, :doc => <<-EOS -Takes an array as first argument and an optional second argument. -Count the number of elements in array that matches second argument. -If called with only an array it counts the number of elements that are not nil/undef. - EOS - ) do |args| + newfunction(:count, type: :rvalue, arity: -2, doc: <<-DOC + @summary + Counts the number of elements in array. - if (args.size > 2) then - raise(ArgumentError, "count(): Wrong number of arguments "+ - "given #{args.size} for 1 or 2.") - end + Takes an array as first argument and an optional second argument. Counts the number of elements in array that is equal to the second argument. + If called with only an array, it counts the number of elements that are not nil/undef/empty-string. + + > *Note:* + equality is tested with a Ruby method and it is therefore subject to what Ruby considers + to be equal. For strings this means that equality is case sensitive. + + In Puppet core, counting can be done in general by using a combination of the core functions + filter() (since Puppet 4.0.0) and length() (since Puppet 5.5.0, before that in stdlib). + + Example below shows counting values that are not undef. + + ```notice([42, "hello", undef].filter |$x| { $x =~ NotUndef }.length)``` + + Would notice the value 2. + + @return [Integer] The amount of elements counted within the array + DOC + ) do |args| + raise(ArgumentError, "count(): Wrong number of arguments given #{args.size} for 1 or 2.") if args.size > 2 collection, item = args - if item then + if item collection.count item else - collection.count { |obj| obj != nil && obj != :undef && obj != '' } + collection.count { |obj| !obj.nil? && obj != :undef && obj != '' } end end end diff --git a/lib/puppet/parser/functions/deep_merge.rb b/lib/puppet/parser/functions/deep_merge.rb index 6df32e9c5..3669d4afc 100644 --- a/lib/puppet/parser/functions/deep_merge.rb +++ b/lib/puppet/parser/functions/deep_merge.rb @@ -1,26 +1,33 @@ +# frozen_string_literal: true + +# +# deep_merge.rb +# module Puppet::Parser::Functions - newfunction(:deep_merge, :type => :rvalue, :doc => <<-'ENDHEREDOC') do |args| - Recursively merges two or more hashes together and returns the resulting hash. + newfunction(:deep_merge, type: :rvalue, doc: <<-DOC) do |args| + @summary + Recursively merges two or more hashes together and returns the resulting hash. - For example: + @example Example usage - $hash1 = {'one' => 1, 'two' => 2, 'three' => { 'four' => 4 } } - $hash2 = {'two' => 'dos', 'three' => { 'five' => 5 } } - $merged_hash = deep_merge($hash1, $hash2) - # The resulting hash is equivalent to: - # $merged_hash = { 'one' => 1, 'two' => 'dos', 'three' => { 'four' => 4, 'five' => 5 } } + $hash1 = {'one' => 1, 'two' => 2, 'three' => { 'four' => 4 } } + $hash2 = {'two' => 'dos', 'three' => { 'five' => 5 } } + $merged_hash = deep_merge($hash1, $hash2) - When there is a duplicate key that is a hash, they are recursively merged. - When there is a duplicate key that is not a hash, the key in the rightmost hash will "win." + The resulting hash is equivalent to: - ENDHEREDOC + $merged_hash = { 'one' => 1, 'two' => 'dos', 'three' => { 'four' => 4, 'five' => 5 } } - if args.length < 2 - raise Puppet::ParseError, ("deep_merge(): wrong number of arguments (#{args.length}; must be at least 2)") - end + When there is a duplicate key that is a hash, they are recursively merged. + When there is a duplicate key that is not a hash, the key in the rightmost hash will "win." + + @return [Hash] The merged hash + DOC - deep_merge = Proc.new do |hash1,hash2| - hash1.merge(hash2) do |key,old_value,new_value| + raise Puppet::ParseError, "deep_merge(): wrong number of arguments (#{args.length}; must be at least 2)" if args.length < 2 + + deep_merge = proc do |hash1, hash2| + hash1.merge(hash2) do |_key, old_value, new_value| if old_value.is_a?(Hash) && new_value.is_a?(Hash) deep_merge.call(old_value, new_value) else @@ -29,16 +36,14 @@ module Puppet::Parser::Functions end end - result = Hash.new + result = {} args.each do |arg| - next if arg.is_a? String and arg.empty? # empty string is synonym for puppet's undef + next if arg.is_a?(String) && arg.empty? # empty string is synonym for puppet's undef # If the argument was not a hash, skip it. - unless arg.is_a?(Hash) - raise Puppet::ParseError, "deep_merge: unexpected argument type #{arg.class}, only expects hash arguments" - end + raise Puppet::ParseError, "deep_merge: unexpected argument type #{arg.class}, only expects hash arguments" unless arg.is_a?(Hash) result = deep_merge.call(result, arg) end - return( result ) + return(result) end end diff --git a/lib/puppet/parser/functions/defined_with_params.rb b/lib/puppet/parser/functions/defined_with_params.rb index d7df306c7..0b8b338ee 100644 --- a/lib/puppet/parser/functions/defined_with_params.rb +++ b/lib/puppet/parser/functions/defined_with_params.rb @@ -1,35 +1,78 @@ +# frozen_string_literal: true + # Test whether a given class or definition is defined require 'puppet/parser/functions' -Puppet::Parser::Functions.newfunction(:defined_with_params, - :type => :rvalue, - :doc => <<-'ENDOFDOC' -Takes a resource reference and an optional hash of attributes. +Puppet::Parser::Functions.newfunction(:defined_with_params, type: :rvalue, doc: <<-DOC + @summary + Takes a resource reference and an optional hash of attributes. + + Returns `true` if a resource with the specified attributes has already been added + to the catalog, and `false` otherwise. -Returns true if a resource with the specified attributes has already been added -to the catalog, and false otherwise. + ``` + user { 'dan': + ensure => present, + } - user { 'dan': - ensure => present, - } + if ! defined_with_params(User[dan], {'ensure' => 'present' }) { + user { 'dan': ensure => present, } + } + ``` - if ! defined_with_params(User[dan], {'ensure' => 'present' }) { - user { 'dan': ensure => present, } - } -ENDOFDOC + @return [Boolean] + returns `true` or `false` +DOC ) do |vals| reference, params = vals raise(ArgumentError, 'Must specify a reference') unless reference - if (! params) || params == '' - params = {} - end + + params = {} if !params || params == '' ret = false - if resource = findresource(reference.to_s) - matches = params.collect do |key, value| - resource[key] == value + + if Puppet::Util::Package.versioncmp(Puppet.version, '4.6.0') >= 0 + # Workaround for PE-20308 + if reference.is_a?(String) + type_name, title = Puppet::Resource.type_and_title(reference, nil) + type = Puppet::Pops::Evaluator::Runtime3ResourceSupport.find_resource_type_or_class(find_global_scope, type_name.downcase) + elsif reference.is_a?(Puppet::Resource) + type = reference.type + title = reference.title + else + raise(ArgumentError, "Reference is not understood: '#{reference.class}'") + end + # end workaround + else + type = reference.to_s + title = nil + end + + resources = if title.empty? + catalog.resources.select { |r| r.type == type } + else + [findresource(type, title)] + end + + resources.compact.each do |res| + # If you call this from within a defined type, it will find itself + next if res.to_s == resource.to_s + + matches = params.map do |key, value| + # eql? avoids bugs caused by monkeypatching in puppet + res_is_undef = res[key].eql?(:undef) || res[key].nil? + value_is_undef = value.eql?(:undef) || value.nil? + found_match = (res_is_undef && value_is_undef) || (res[key] == value) + + Puppet.debug("Matching resource is #{res}") if found_match + + found_match end ret = params.empty? || !matches.include?(false) + + break if ret end - Puppet.debug("Resource #{reference} was not determined to be defined") + + Puppet.debug("Resource #{reference} was not determined to be defined") unless ret + ret end diff --git a/lib/puppet/parser/functions/delete.rb b/lib/puppet/parser/functions/delete.rb index f548b4444..e66b3c4c8 100644 --- a/lib/puppet/parser/functions/delete.rb +++ b/lib/puppet/parser/functions/delete.rb @@ -1,45 +1,64 @@ +# frozen_string_literal: true + # # delete.rb # +module Puppet::Parser::Functions + newfunction(:delete, type: :rvalue, doc: <<-DOC + @summary + Deletes all instances of a given element from an array, substring from a + string, or key from a hash. -# TODO(Krzysztof Wilczynski): We need to add support for regular expression ... + @example Example usage -module Puppet::Parser::Functions - newfunction(:delete, :type => :rvalue, :doc => <<-EOS -Deletes all instances of a given element from an array, substring from a -string, or key from a hash. + delete(['a','b','c','b'], 'b') + Would return: ['a','c'] -*Examples:* + delete({'a'=>1,'b'=>2,'c'=>3}, 'b') + Would return: {'a'=>1,'c'=>3} - delete(['a','b','c','b'], 'b') - Would return: ['a','c'] + delete({'a'=>1,'b'=>2,'c'=>3}, ['b','c']) + Would return: {'a'=>1} - delete({'a'=>1,'b'=>2,'c'=>3}, 'b') - Would return: {'a'=>1,'c'=>3} + delete('abracadabra', 'bra') + Would return: 'acada' - delete({'a'=>1,'b'=>2,'c'=>3}, ['b','c']) - Would return: {'a'=>1} + ['a', 'b', 'c', 'b'] - 'b' + Would return: ['a', 'c'] - delete('abracadabra', 'bra') - Would return: 'acada' - EOS - ) do |arguments| + {'a'=>1,'b'=>2,'c'=>3} - ['b','c']) + Would return: {'a' => '1'} - if (arguments.size != 2) then - raise(Puppet::ParseError, "delete(): Wrong number of arguments "+ - "given #{arguments.size} for 2.") - end + 'abracadabra'.regsubst(/bra/, '', 'G') + Would return: 'acada' + + > *Note:* + From Puppet 4.0.0 the minus (-) operator deletes values from arrays and keys from a hash + `{'a'=>1,'b'=>2,'c'=>3} - ['b','c'])` + > + A global delete from a string can be performed with the + [`regsubst`](https://puppet.com/docs/puppet/latest/function.html#regsubst) function: + `'abracadabra'.regsubst(/bra/, '', 'G')` + + In general, the built-in [`filter`](https://puppet.com/docs/puppet/latest/function.html#filter) + function can filter out entries from arrays and hashes based on keys and/or values. + + @return [String] The filtered String, if one was given. + @return [Hash] The filtered Hash, if one was given. + @return [Array] The filtered Array, if one was given. + DOC + ) do |arguments| + raise(Puppet::ParseError, "delete(): Wrong number of arguments given #{arguments.size} for 2") unless arguments.size == 2 collection = arguments[0].dup Array(arguments[1]).each do |item| case collection - when Array, Hash - collection.delete item - when String - collection.gsub! item, '' - else - raise(TypeError, "delete(): First argument must be an Array, " + - "String, or Hash. Given an argument of class #{collection.class}.") + when Array, Hash + collection.delete item + when String + collection.gsub! item, '' + else + raise(TypeError, "delete(): First argument must be an Array, String, or Hash. Given an argument of class #{collection.class}.") end end collection diff --git a/lib/puppet/parser/functions/delete_at.rb b/lib/puppet/parser/functions/delete_at.rb index 3eb4b5375..86e7a2960 100644 --- a/lib/puppet/parser/functions/delete_at.rb +++ b/lib/puppet/parser/functions/delete_at.rb @@ -1,44 +1,52 @@ +# frozen_string_literal: true + # # delete_at.rb # - module Puppet::Parser::Functions - newfunction(:delete_at, :type => :rvalue, :doc => <<-EOS -Deletes a determined indexed value from an array. + newfunction(:delete_at, type: :rvalue, doc: <<-DOC) do |arguments| + @summary + Deletes a determined indexed value from an array. + + For example + ```delete_at(['a','b','c'], 1)``` + + Would return: `['a','c']` + + > *Note:* + Since Puppet 4 this can be done in general with the built-in + [`filter`](https://puppet.com/docs/puppet/latest/function.html#filter) function: + + ```['a', 'b', 'c'].filter |$pos, $val | { $pos != 1 }``` -*Examples:* + Or if a delete is wanted from the beginning or end of the array, by using the slice operator [ ]: + ``` + $array[0, -1] # the same as all the values + $array[2, -1] # all but the first 2 elements + $array[0, -3] # all but the last 2 elements + $array[1, -2] # all but the first and last element + ``` - delete_at(['a','b','c'], 1) + @return [Array] The given array, now missing the target value -Would return: ['a','c'] - EOS - ) do |arguments| + DOC - raise(Puppet::ParseError, "delete_at(): Wrong number of arguments " + - "given (#{arguments.size} for 2)") if arguments.size < 2 + raise(Puppet::ParseError, "delete_at(): Wrong number of arguments given (#{arguments.size} for 2)") if arguments.size < 2 array = arguments[0] - unless array.is_a?(Array) - raise(Puppet::ParseError, 'delete_at(): Requires array to work with') - end + raise(Puppet::ParseError, 'delete_at(): Requires array to work with') unless array.is_a?(Array) index = arguments[1] - if index.is_a?(String) and not index.match(/^\d+$/) - raise(Puppet::ParseError, 'delete_at(): You must provide ' + - 'non-negative numeric index') - end + raise(Puppet::ParseError, 'delete_at(): You must provide non-negative numeric index') if index.is_a?(String) && !index.match(%r{^\d+$}) result = array.clone # Numbers in Puppet are often string-encoded which is troublesome ... index = index.to_i - if index > result.size - 1 # First element is at index 0 is it not? - raise(Puppet::ParseError, 'delete_at(): Given index ' + - 'exceeds size of array given') - end + raise(Puppet::ParseError, 'delete_at(): Given index exceeds size of array given') if index > result.size - 1 # First element is at index 0 is it not? result.delete_at(index) # We ignore the element that got deleted ... diff --git a/lib/puppet/parser/functions/delete_regex.rb b/lib/puppet/parser/functions/delete_regex.rb new file mode 100644 index 000000000..0f1417751 --- /dev/null +++ b/lib/puppet/parser/functions/delete_regex.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +# +# delete_regex.rb +# Please note: This function is an implementation of a Ruby class and as such may not be entirely UTF8 compatible. To ensure compatibility please use this function with Ruby 2.4.0 or greater - https://bugs.ruby-lang.org/issues/10085. +# +module Puppet::Parser::Functions + newfunction(:delete_regex, type: :rvalue, doc: <<-DOC + @summary + Deletes all instances of a given element that match a regular expression + from an array or key from a hash. + + Multiple regular expressions are assumed to be matched as an OR. + + @example Example usage + + delete_regex(['a','b','c','b'], 'b') + Would return: ['a','c'] + + delete_regex(['a','b','c','b'], ['b', 'c']) + Would return: ['a'] + + delete_regex({'a'=>1,'b'=>2,'c'=>3}, 'b') + Would return: {'a'=>1,'c'=>3} + + delete_regex({'a'=>1,'b'=>2,'c'=>3}, '^a$') + Would return: {'b'=>2,'c'=>3} + + > *Note:* + Since Puppet 4 this can be done in general with the built-in + [`filter`](https://puppet.com/docs/puppet/latest/function.html#filter) function: + ["aaa", "aba", "aca"].filter |$val| { $val !~ /b/ } + Would return: ['aaa', 'aca'] + + @return [Array] The given array now missing all targeted values. + DOC + ) do |arguments| + raise(Puppet::ParseError, "delete_regex(): Wrong number of arguments given #{arguments.size} for 2") unless arguments.size == 2 + + collection = arguments[0].dup + Array(arguments[1]).each do |item| + case collection + when Array, Hash, String + collection.reject! { |coll_item| (coll_item =~ %r{\b#{item}\b}) } + else + raise(TypeError, "delete_regex(): First argument must be an Array, Hash, or String. Given an argument of class #{collection.class}.") + end + end + collection + end +end + +# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/delete_undef_values.rb b/lib/puppet/parser/functions/delete_undef_values.rb index f94d4da8d..6d71e76df 100644 --- a/lib/puppet/parser/functions/delete_undef_values.rb +++ b/lib/puppet/parser/functions/delete_undef_values.rb @@ -1,33 +1,41 @@ -module Puppet::Parser::Functions - newfunction(:delete_undef_values, :type => :rvalue, :doc => <<-EOS -Returns a copy of input hash or array with all undefs deleted. +# frozen_string_literal: true -*Examples:* +# +# delete_undef_values.rb +# +module Puppet::Parser::Functions + newfunction(:delete_undef_values, type: :rvalue, doc: <<-DOC + @summary + Returns a copy of input hash or array with all undefs deleted. - $hash = delete_undef_values({a=>'A', b=>'', c=>undef, d => false}) + @example Example usage -Would return: {a => 'A', b => '', d => false} + $hash = delete_undef_values({a=>'A', b=>'', c=>undef, d => false}) + Would return: {a => 'A', b => '', d => false} - $array = delete_undef_values(['A','',undef,false]) + While: + $array = delete_undef_values(['A','',undef,false]) + Would return: ['A','',false] -Would return: ['A','',false] + > *Note:* + Since Puppet 4.0.0 the equivalent can be performed with the built-in + [`filter`](https://puppet.com/docs/puppet/latest/function.html#filter) function: + $array.filter |$val| { $val =~ NotUndef } + $hash.filter |$key, $val| { $val =~ NotUndef } - EOS - ) do |args| + @return [Array] The given array now issing of undefined values. + DOC + ) do |args| + raise(Puppet::ParseError, "delete_undef_values(): Wrong number of arguments given (#{args.size})") if args.empty? - raise(Puppet::ParseError, - "delete_undef_values(): Wrong number of arguments given " + - "(#{args.size})") if args.size < 1 + raise(Puppet::ParseError, "delete_undef_values(): expected an array or hash, got #{args[0]} type #{args[0].class} ") unless args[0].is_a?(Array) || args[0].is_a?(Hash) - unless args[0].is_a? Array or args[0].is_a? Hash - raise(Puppet::ParseError, - "delete_undef_values(): expected an array or hash, got #{args[0]} type #{args[0].class} ") - end result = args[0].dup if result.is_a?(Hash) - result.delete_if {|key, val| val.equal? :undef} + result.delete_if { |_, val| val.equal?(:undef) || val.nil? } elsif result.is_a?(Array) result.delete :undef + result.delete nil end result end diff --git a/lib/puppet/parser/functions/delete_values.rb b/lib/puppet/parser/functions/delete_values.rb index f6c8c0e6b..4d2323082 100644 --- a/lib/puppet/parser/functions/delete_values.rb +++ b/lib/puppet/parser/functions/delete_values.rb @@ -1,26 +1,33 @@ -module Puppet::Parser::Functions - newfunction(:delete_values, :type => :rvalue, :doc => <<-EOS -Deletes all instances of a given value from a hash. +# frozen_string_literal: true -*Examples:* +# +# delete_values.rb +# +module Puppet::Parser::Functions + newfunction(:delete_values, type: :rvalue, doc: <<-DOC + @summary + Deletes all instances of a given value from a hash. - delete_values({'a'=>'A','b'=>'B','c'=>'C','B'=>'D'}, 'B') + @example Example usage -Would return: {'a'=>'A','c'=>'C','B'=>'D'} + delete_values({'a'=>'A','b'=>'B','c'=>'C','B'=>'D'}, 'B') + Would return: {'a'=>'A','c'=>'C','B'=>'D'} - EOS - ) do |arguments| + > *Note:* + Since Puppet 4.0.0 the equivalent can be performed with the + built-in [`filter`](https://puppet.com/docs/puppet/latest/function.html#filter) function: + $array.filter |$val| { $val != 'B' } + $hash.filter |$key, $val| { $val != 'B' } - raise(Puppet::ParseError, - "delete_values(): Wrong number of arguments given " + - "(#{arguments.size} of 2)") if arguments.size != 2 + @return [Hash] The given hash now missing all instances of the targeted value + DOC + ) do |arguments| + raise(Puppet::ParseError, "delete_values(): Wrong number of arguments given (#{arguments.size} of 2)") if arguments.size != 2 hash, item = arguments - if not hash.is_a?(Hash) - raise(TypeError, "delete_values(): First argument must be a Hash. " + \ - "Given an argument of class #{hash.class}.") - end - hash.dup.delete_if { |key, val| item == val } + raise(TypeError, "delete_values(): First argument must be a Hash. Given an argument of class #{hash.class}.") unless hash.is_a?(Hash) + + hash.dup.delete_if { |_key, val| item == val } end end diff --git a/lib/puppet/parser/functions/difference.rb b/lib/puppet/parser/functions/difference.rb index cd258f751..e20fc32e2 100644 --- a/lib/puppet/parser/functions/difference.rb +++ b/lib/puppet/parser/functions/difference.rb @@ -1,31 +1,38 @@ +# frozen_string_literal: true + # # difference.rb # - module Puppet::Parser::Functions - newfunction(:difference, :type => :rvalue, :doc => <<-EOS -This function returns the difference between two arrays. -The returned array is a copy of the original array, removing any items that -also appear in the second array. + newfunction(:difference, type: :rvalue, doc: <<-DOC + @summary + This function returns the difference between two arrays. -*Examples:* + The returned array is a copy of the original array, removing any items that + also appear in the second array. - difference(["a","b","c"],["b","c","d"]) + @example Example usage -Would return: ["a"] - EOS - ) do |arguments| + difference(["a","b","c"],["b","c","d"]) + Would return: `["a"]` + > *Note:* + Since Puppet 4 the minus (-) operator in the Puppet language does the same thing: + ['a', 'b', 'c'] - ['b', 'c', 'd'] + Would return: `['a']` + + @return [Array] + The difference between the two given arrays + + DOC + ) do |arguments| # Two arguments are required - raise(Puppet::ParseError, "difference(): Wrong number of arguments " + - "given (#{arguments.size} for 2)") if arguments.size != 2 + raise(Puppet::ParseError, "difference(): Wrong number of arguments given (#{arguments.size} for 2)") if arguments.size != 2 first = arguments[0] second = arguments[1] - unless first.is_a?(Array) && second.is_a?(Array) - raise(Puppet::ParseError, 'difference(): Requires 2 arrays') - end + raise(Puppet::ParseError, 'difference(): Requires 2 arrays') unless first.is_a?(Array) && second.is_a?(Array) result = first - second diff --git a/lib/puppet/parser/functions/dirname.rb b/lib/puppet/parser/functions/dirname.rb index 40b300d89..5ea1f0133 100644 --- a/lib/puppet/parser/functions/dirname.rb +++ b/lib/puppet/parser/functions/dirname.rb @@ -1,18 +1,21 @@ +# frozen_string_literal: true + +# +# dirname.rb +# module Puppet::Parser::Functions - newfunction(:dirname, :type => :rvalue, :doc => <<-EOS - Returns the dirname of a path. - EOS - ) do |arguments| + newfunction(:dirname, type: :rvalue, doc: <<-DOC + @summary + Returns the dirname of a path. - if arguments.size < 1 then - raise(Puppet::ParseError, "dirname(): No arguments given") - end - if arguments.size > 1 then - raise(Puppet::ParseError, "dirname(): Too many arguments given (#{arguments.size})") - end - unless arguments[0].is_a?(String) - raise(Puppet::ParseError, 'dirname(): Requires string as argument') - end + @return [String] the given path's dirname + DOC + ) do |arguments| + raise(Puppet::ParseError, 'dirname(): No arguments given') if arguments.empty? + raise(Puppet::ParseError, "dirname(): Too many arguments given (#{arguments.size})") if arguments.size > 1 + raise(Puppet::ParseError, 'dirname(): Requires string as argument') unless arguments[0].is_a?(String) + # undef is converted to an empty string '' + raise(Puppet::ParseError, 'dirname(): Requires a non-empty string as argument') if arguments[0].empty? return File.dirname(arguments[0]) end diff --git a/lib/puppet/parser/functions/dos2unix.rb b/lib/puppet/parser/functions/dos2unix.rb index ccac89933..b55ebd4d7 100644 --- a/lib/puppet/parser/functions/dos2unix.rb +++ b/lib/puppet/parser/functions/dos2unix.rb @@ -1,15 +1,18 @@ +# frozen_string_literal: true + # Custom Puppet function to convert dos to unix format module Puppet::Parser::Functions - newfunction(:dos2unix, :type => :rvalue, :arity => 1, :doc => <<-EOS - Returns the Unix version of the given string. + newfunction(:dos2unix, type: :rvalue, arity: 1, doc: <<-DOC + @summary + Returns the Unix version of the given string. + Takes a single string argument. - EOS - ) do |arguments| - unless arguments[0].is_a?(String) - raise(Puppet::ParseError, 'dos2unix(): Requires string as argument') - end + @return The retrieved version + DOC + ) do |arguments| + raise(Puppet::ParseError, 'dos2unix(): Requires string as argument') unless arguments[0].is_a?(String) - arguments[0].gsub(/\r\n/, "\n") + arguments[0].gsub(%r{\r\n}, "\n") end end diff --git a/lib/puppet/parser/functions/downcase.rb b/lib/puppet/parser/functions/downcase.rb deleted file mode 100644 index 040b84f56..000000000 --- a/lib/puppet/parser/functions/downcase.rb +++ /dev/null @@ -1,32 +0,0 @@ -# -# downcase.rb -# - -module Puppet::Parser::Functions - newfunction(:downcase, :type => :rvalue, :doc => <<-EOS -Converts the case of a string or all strings in an array to lower case. - EOS - ) do |arguments| - - raise(Puppet::ParseError, "downcase(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 - - value = arguments[0] - - unless value.is_a?(Array) || value.is_a?(String) - raise(Puppet::ParseError, 'downcase(): Requires either ' + - 'array or string to work with') - end - - if value.is_a?(Array) - # Numbers in Puppet are often string-encoded which is troublesome ... - result = value.collect { |i| i.is_a?(String) ? i.downcase : i } - else - result = value.downcase - end - - return result - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/empty.rb b/lib/puppet/parser/functions/empty.rb deleted file mode 100644 index b5a3cdea4..000000000 --- a/lib/puppet/parser/functions/empty.rb +++ /dev/null @@ -1,31 +0,0 @@ -# -# empty.rb -# - -module Puppet::Parser::Functions - newfunction(:empty, :type => :rvalue, :doc => <<-EOS -Returns true if the variable is empty. - EOS - ) do |arguments| - - raise(Puppet::ParseError, "empty(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 - - value = arguments[0] - - unless value.is_a?(Array) || value.is_a?(Hash) || value.is_a?(String) || value.is_a?(Numeric) - raise(Puppet::ParseError, 'empty(): Requires either ' + - 'array, hash, string or integer to work with') - end - - if value.is_a?(Numeric) - return false - else - result = value.empty? - - return result - end - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/enclose_ipv6.rb b/lib/puppet/parser/functions/enclose_ipv6.rb new file mode 100644 index 000000000..b23561d81 --- /dev/null +++ b/lib/puppet/parser/functions/enclose_ipv6.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +# +# enclose_ipv6.rb +# +module Puppet::Parser::Functions + newfunction(:enclose_ipv6, type: :rvalue, doc: <<-DOC + @summary + Takes an array of ip addresses and encloses the ipv6 addresses with square brackets. + + @return + encloses the ipv6 addresses with square brackets. + + DOC + ) do |arguments| + require 'ipaddr' + + rescuable_exceptions = [ArgumentError] + rescuable_exceptions << IPAddr::InvalidAddressError if defined?(IPAddr::InvalidAddressError) + + raise(Puppet::ParseError, "enclose_ipv6(): Wrong number of arguments given #{arguments.size} for 1") if arguments.size != 1 + raise(Puppet::ParseError, "enclose_ipv6(): Wrong argument type given #{arguments[0].class} expected String or Array") unless arguments[0].is_a?(String) || arguments[0].is_a?(Array) + + input = [arguments[0]].flatten.compact + result = [] + + input.each do |val| + unless val == '*' + begin + ip = IPAddr.new(val) + rescue *rescuable_exceptions + raise(Puppet::ParseError, "enclose_ipv6(): Wrong argument given #{val} is not an ip address.") + end + val = "[#{ip}]" if ip.ipv6? + end + result << val + end + + return result.uniq + end +end diff --git a/lib/puppet/parser/functions/ensure_packages.rb b/lib/puppet/parser/functions/ensure_packages.rb deleted file mode 100644 index f1da4aaaa..000000000 --- a/lib/puppet/parser/functions/ensure_packages.rb +++ /dev/null @@ -1,35 +0,0 @@ -# -# ensure_packages.rb -# - -module Puppet::Parser::Functions - newfunction(:ensure_packages, :type => :statement, :doc => <<-EOS -Takes a list of packages and only installs them if they don't already exist. -It optionally takes a hash as a second parameter that will be passed as the -third argument to the ensure_resource() function. - EOS - ) do |arguments| - - if arguments.size > 2 or arguments.size == 0 - raise(Puppet::ParseError, "ensure_packages(): Wrong number of arguments " + - "given (#{arguments.size} for 1 or 2)") - elsif arguments.size == 2 and !arguments[1].is_a?(Hash) - raise(Puppet::ParseError, 'ensure_packages(): Requires second argument to be a Hash') - end - - packages = Array(arguments[0]) - - if arguments[1] - defaults = { 'ensure' => 'present' }.merge(arguments[1]) - else - defaults = { 'ensure' => 'present' } - end - - Puppet::Parser::Functions.function(:ensure_resource) - packages.each { |package_name| - function_ensure_resource(['package', package_name, defaults ]) - } - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/ensure_resource.rb b/lib/puppet/parser/functions/ensure_resource.rb index 1ba6a4478..48497ee54 100644 --- a/lib/puppet/parser/functions/ensure_resource.rb +++ b/lib/puppet/parser/functions/ensure_resource.rb @@ -1,34 +1,41 @@ +# frozen_string_literal: true + # Test whether a given class or definition is defined require 'puppet/parser/functions' -Puppet::Parser::Functions.newfunction(:ensure_resource, - :type => :statement, - :doc => <<-'ENDOFDOC' -Takes a resource type, title, and a list of attributes that describe a -resource. +Puppet::Parser::Functions.newfunction(:ensure_resource, type: :statement, doc: <<-DOC + @summary + Takes a resource type, title, and a list of attributes that describe a + resource. + + user { 'dan': + ensure => present, + } - user { 'dan': - ensure => present, - } + @return + created or recreated the passed resource with the passed type and attributes -This example only creates the resource if it does not already exist: + @example Example usage - ensure_resource('user', 'dan', {'ensure' => 'present' }) + Creates the resource if it does not already exist: -If the resource already exists but does not match the specified parameters, -this function will attempt to recreate the resource leading to a duplicate -resource definition error. + ensure_resource('user', 'dan', {'ensure' => 'present' }) -An array of resources can also be passed in and each will be created with -the type and parameters specified if it doesn't already exist. + If the resource already exists but does not match the specified parameters, + this function will attempt to recreate the resource leading to a duplicate + resource definition error. - ensure_resource('user', ['dan','alex'], {'ensure' => 'present'}) + An array of resources can also be passed in and each will be created with + the type and parameters specified if it doesn't already exist. -ENDOFDOC + ensure_resource('user', ['dan','alex'], {'ensure' => 'present'}) + +DOC ) do |vals| type, title, params = vals raise(ArgumentError, 'Must specify a type') unless type raise(ArgumentError, 'Must specify a title') unless title + params ||= {} items = [title].flatten diff --git a/lib/puppet/parser/functions/ensure_resources.rb b/lib/puppet/parser/functions/ensure_resources.rb new file mode 100644 index 000000000..a7fc9daca --- /dev/null +++ b/lib/puppet/parser/functions/ensure_resources.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +require 'puppet/parser/functions' + +Puppet::Parser::Functions.newfunction(:ensure_resources, type: :statement, doc: <<-DOC + @summary + Takes a resource type, title (only hash), and a list of attributes that describe a + resource. + + @return + created resources with the passed type and attributes + + @example Example usage + + user { 'dan': + gid => 'mygroup', + ensure => present, + } + + An hash of resources should be passed in and each will be created with + the type and parameters specified if it doesn't already exist. + + ensure_resources('user', {'dan' => { gid => 'mygroup', uid => '600' }, 'alex' => { gid => 'mygroup' }}, {'ensure' => 'present'}) + + From Hiera Backend: + + userlist: + dan: + gid: 'mygroup' + uid: '600' + alex: + gid: 'mygroup' + + Call: + ensure_resources('user', hiera_hash('userlist'), {'ensure' => 'present'}) +DOC +) do |vals| + type, title, params = vals + raise(ArgumentError, 'Must specify a type') unless type + raise(ArgumentError, 'Must specify a title') unless title + + params ||= {} + + raise(Puppet::ParseError, 'ensure_resources(): Requires second argument to be a Hash') unless title.is_a?(Hash) + + resource_hash = title.dup + resources = resource_hash.keys + + Puppet::Parser::Functions.function(:ensure_resource) + resources.each do |resource_name| + params_merged = if resource_hash[resource_name] + params.merge(resource_hash[resource_name]) + else + params + end + function_ensure_resource([type, resource_name, params_merged]) + end +end diff --git a/lib/puppet/parser/functions/flatten.rb b/lib/puppet/parser/functions/flatten.rb deleted file mode 100644 index a1ed18329..000000000 --- a/lib/puppet/parser/functions/flatten.rb +++ /dev/null @@ -1,33 +0,0 @@ -# -# flatten.rb -# - -module Puppet::Parser::Functions - newfunction(:flatten, :type => :rvalue, :doc => <<-EOS -This function flattens any deeply nested arrays and returns a single flat array -as a result. - -*Examples:* - - flatten(['a', ['b', ['c']]]) - -Would return: ['a','b','c'] - EOS - ) do |arguments| - - raise(Puppet::ParseError, "flatten(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size != 1 - - array = arguments[0] - - unless array.is_a?(Array) - raise(Puppet::ParseError, 'flatten(): Requires array to work with') - end - - result = array.flatten - - return result - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/floor.rb b/lib/puppet/parser/functions/floor.rb deleted file mode 100644 index 9a6f014d7..000000000 --- a/lib/puppet/parser/functions/floor.rb +++ /dev/null @@ -1,25 +0,0 @@ -module Puppet::Parser::Functions - newfunction(:floor, :type => :rvalue, :doc => <<-EOS - Returns the largest integer less or equal to the argument. - Takes a single numeric value as an argument. - EOS - ) do |arguments| - - raise(Puppet::ParseError, "floor(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size != 1 - - begin - arg = Float(arguments[0]) - rescue TypeError, ArgumentError => e - raise(Puppet::ParseError, "floor(): Wrong argument type " + - "given (#{arguments[0]} for Numeric)") - end - - raise(Puppet::ParseError, "floor(): Wrong argument type " + - "given (#{arg.class} for Numeric)") if arg.is_a?(Numeric) == false - - arg.floor - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/fqdn_rand_string.rb b/lib/puppet/parser/functions/fqdn_rand_string.rb deleted file mode 100644 index 2bb1287e0..000000000 --- a/lib/puppet/parser/functions/fqdn_rand_string.rb +++ /dev/null @@ -1,34 +0,0 @@ -Puppet::Parser::Functions::newfunction( - :fqdn_rand_string, - :arity => -2, - :type => :rvalue, - :doc => "Usage: `fqdn_rand_string(LENGTH, [CHARSET], [SEED])`. LENGTH is - required and must be a positive integer. CHARSET is optional and may be - `undef` or a string. SEED is optional and may be any number or string. - - Generates a random string LENGTH characters long using the character set - provided by CHARSET, combining the `$fqdn` fact and the value of SEED for - repeatable randomness. (That is, each node will get a different random - string from this function, but a given node's result will be the same every - time unless its hostname changes.) Adding a SEED can be useful if you need - more than one unrelated string. CHARSET will default to alphanumeric if - `undef` or an empty string.") do |args| - raise(ArgumentError, "fqdn_rand_string(): wrong number of arguments (0 for 1)") if args.size == 0 - Puppet::Parser::Functions.function('is_integer') - raise(ArgumentError, "fqdn_rand_string(): first argument must be a positive integer") unless function_is_integer([args[0]]) and args[0].to_i > 0 - raise(ArgumentError, "fqdn_rand_string(): second argument must be undef or a string") unless args[1].nil? or args[1].is_a? String - - Puppet::Parser::Functions.function('fqdn_rand') - - length = args.shift.to_i - charset = args.shift.to_s.chars.to_a - - charset = (0..9).map { |i| i.to_s } + ('A'..'Z').to_a + ('a'..'z').to_a if charset.empty? - - rand_string = '' - for current in 1..length - rand_string << charset[function_fqdn_rand([charset.size, (args + [current.to_s]).join(':')]).to_i] - end - - rand_string -end diff --git a/lib/puppet/parser/functions/fqdn_rotate.rb b/lib/puppet/parser/functions/fqdn_rotate.rb deleted file mode 100644 index b66431d1e..000000000 --- a/lib/puppet/parser/functions/fqdn_rotate.rb +++ /dev/null @@ -1,63 +0,0 @@ -# -# fqdn_rotate.rb -# - -Puppet::Parser::Functions.newfunction( - :fqdn_rotate, - :type => :rvalue, - :doc => "Usage: `fqdn_rotate(VALUE, [SEED])`. VALUE is required and - must be an array or a string. SEED is optional and may be any number - or string. - - Rotates VALUE a random number of times, combining the `$fqdn` fact and - the value of SEED for repeatable randomness. (That is, each node will - get a different random rotation from this function, but a given node's - result will be the same every time unless its hostname changes.) Adding - a SEED can be useful if you need more than one unrelated rotation.") do |args| - - raise(Puppet::ParseError, "fqdn_rotate(): Wrong number of arguments " + - "given (#{args.size} for 1)") if args.size < 1 - - value = args.shift - require 'digest/md5' - - unless value.is_a?(Array) || value.is_a?(String) - raise(Puppet::ParseError, 'fqdn_rotate(): Requires either ' + - 'array or string to work with') - end - - result = value.clone - - string = value.is_a?(String) ? true : false - - # Check whether it makes sense to rotate ... - return result if result.size <= 1 - - # We turn any string value into an array to be able to rotate ... - result = string ? result.split('') : result - - elements = result.size - - seed = Digest::MD5.hexdigest([lookupvar('::fqdn'),args].join(':')).hex - # deterministic_rand() was added in Puppet 3.2.0; reimplement if necessary - if Puppet::Util.respond_to?(:deterministic_rand) - offset = Puppet::Util.deterministic_rand(seed, elements).to_i - else - if defined?(Random) == 'constant' && Random.class == Class - offset = Random.new(seed).rand(elements) - else - old_seed = srand(seed) - offset = rand(elements) - srand(old_seed) - end - end - offset.times { - result.push result.shift - } - - result = string ? result.join : result - - return result -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/fqdn_uuid.rb b/lib/puppet/parser/functions/fqdn_uuid.rb new file mode 100644 index 000000000..cbe8a5652 --- /dev/null +++ b/lib/puppet/parser/functions/fqdn_uuid.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +require 'digest/sha1' +# +# fqdn_uuid.rb +# +module Puppet::Parser::Functions + newfunction(:fqdn_uuid, type: :rvalue, doc: <<-DOC) do |args| + @summary + Returns a [RFC 4122](https://tools.ietf.org/html/rfc4122) valid version 5 UUID based + on an FQDN string under the DNS namespace + + @return + Returns a [RFC 4122](https://tools.ietf.org/html/rfc4122) valid version 5 UUID + + @example Example Usage: + fqdn_uuid('puppetlabs.com') # Returns '9c70320f-6815-5fc5-ab0f-debe68bf764c' + fqdn_uuid('google.com') # Returns '64ee70a4-8cc1-5d25-abf2-dea6c79a09c8' + DOC + + raise(ArgumentError, 'fqdn_uuid: No arguments given') if args.empty? + raise(ArgumentError, "fqdn_uuid: Too many arguments given (#{args.length})") unless args.length == 1 + + fqdn = args[0] + + # Code lovingly taken from + # https://github.com/puppetlabs/marionette-collective/blob/master/lib/mcollective/ssl.rb + + # This is the UUID version 5 type DNS name space which is as follows: + # + # 6ba7b810-9dad-11d1-80b4-00c04fd430c8 + # + uuid_name_space_dns = [0x6b, + 0xa7, + 0xb8, + 0x10, + 0x9d, + 0xad, + 0x11, + 0xd1, + 0x80, + 0xb4, + 0x00, + 0xc0, + 0x4f, + 0xd4, + 0x30, + 0xc8].map(&:chr).join + + sha1 = Digest::SHA1.new + sha1.update(uuid_name_space_dns) + sha1.update(fqdn) + + # first 16 bytes.. + bytes = sha1.digest[0, 16].bytes.to_a + + # version 5 adjustments + bytes[6] &= 0x0f + bytes[6] |= 0x50 + + # variant is DCE 1.1 + bytes[8] &= 0x3f + bytes[8] |= 0x80 + + bytes = [4, 2, 2, 2, 6].map do |i| + bytes.slice!(0, i).pack('C*').unpack('H*') + end + + bytes.join('-') + end +end diff --git a/lib/puppet/parser/functions/get_module_path.rb b/lib/puppet/parser/functions/get_module_path.rb index 1421b91f5..cebe550b2 100644 --- a/lib/puppet/parser/functions/get_module_path.rb +++ b/lib/puppet/parser/functions/get_module_path.rb @@ -1,17 +1,33 @@ +# frozen_string_literal: true + +# +# get_module_path.rb +# module Puppet::Parser::Functions - newfunction(:get_module_path, :type =>:rvalue, :doc => <<-EOT - Returns the absolute path of the specified module for the current - environment. + newfunction(:get_module_path, type: :rvalue, doc: <<-DOC + @summary + Returns the absolute path of the specified module for the current + environment. + + @return + Returns the absolute path of the specified module for the current + environment. - Example: + @example Example Usage: $module_path = get_module_path('stdlib') - EOT + + > *Note:* + that since Puppet 5.4.0 the built-in + [`module_directory`](https://puppet.com/docs/puppet/latest/function.html#module_directory) + function in Puppet does the same thing and will return the path to the first found module + if given multiple values or an array. + DOC ) do |args| - raise(Puppet::ParseError, "get_module_path(): Wrong number of arguments, expects one") unless args.size == 1 - if module_path = Puppet::Module.find(args[0], compiler.environment.to_s) - module_path.path - else - raise(Puppet::ParseError, "Could not find module #{args[0]} in environment #{compiler.environment}") - end + raise(Puppet::ParseError, 'get_module_path(): Wrong number of arguments, expects one') unless args.size == 1 + + module_path = Puppet::Module.find(args[0], compiler.environment.to_s) + raise(Puppet::ParseError, "Could not find module #{args[0]} in environment #{compiler.environment}") unless module_path + + module_path.path end end diff --git a/lib/puppet/parser/functions/getparam.rb b/lib/puppet/parser/functions/getparam.rb index 6d510069f..ed59dcd64 100644 --- a/lib/puppet/parser/functions/getparam.rb +++ b/lib/puppet/parser/functions/getparam.rb @@ -1,35 +1,57 @@ +# frozen_string_literal: true + # Test whether a given class or definition is defined require 'puppet/parser/functions' -Puppet::Parser::Functions.newfunction(:getparam, - :type => :rvalue, - :doc => <<-'ENDOFDOC' -Takes a resource reference and name of the parameter and -returns value of resource's parameter. +Puppet::Parser::Functions.newfunction(:getparam, type: :rvalue, doc: <<-DOC + @summary + Returns the value of a resource's parameter. + + @return + value of a resource's parameter. + + Takes a resource reference and name of the parameter and + returns value of resource's parameter. Note that user defined + resource types are evaluated lazily. + + @example Example Usage: + + # define a resource type with a parameter + define example_resource($param) { + } + + # declare an instance of that type + example_resource { "example_resource_instance": + param => "'the value we are getting in this example''" + } -*Examples:* + # Because of order of evaluation, a second definition is needed + # that will be evaluated after the first resource has been declared + # + define example_get_param { + # This will notice the value of the parameter + notice(getparam(Example_resource["example_resource_instance"], "param")) + } - define example_resource($param) { - } + # Declare an instance of the second resource type - this will call notice + example_get_param { 'show_notify': } - example_resource { "example_resource_instance": - param => "param_value" - } + Would notice: 'the value we are getting in this example' - getparam(Example_resource["example_resource_instance"], "param") + > **Note** that since Puppet 4.0.0 it is possible to get a parameter value by using its data type + and the [ ] operator. The example below is equivalent to a call to getparam(): + ```Example_resource['example_resource_instance']['param']`` -Would return: param_value -ENDOFDOC +DOC ) do |vals| reference, param = vals raise(ArgumentError, 'Must specify a reference') unless reference - raise(ArgumentError, 'Must specify name of a parameter') unless param and param.instance_of? String + raise(ArgumentError, 'Must specify name of a parameter') unless param.instance_of?(String) return '' if param.empty? - if resource = findresource(reference.to_s) - return resource[param] if resource[param] - end + resource = findresource(reference.to_s) + return resource[param] if resource && !resource[param].nil? return '' end diff --git a/lib/puppet/parser/functions/getvar.rb b/lib/puppet/parser/functions/getvar.rb deleted file mode 100644 index ae9c869d1..000000000 --- a/lib/puppet/parser/functions/getvar.rb +++ /dev/null @@ -1,31 +0,0 @@ -module Puppet::Parser::Functions - - newfunction(:getvar, :type => :rvalue, :doc => <<-'ENDHEREDOC') do |args| - Lookup a variable in a remote namespace. - - For example: - - $foo = getvar('site::data::foo') - # Equivalent to $foo = $site::data::foo - - This is useful if the namespace itself is stored in a string: - - $datalocation = 'site::data' - $bar = getvar("${datalocation}::bar") - # Equivalent to $bar = $site::data::bar - ENDHEREDOC - - unless args.length == 1 - raise Puppet::ParseError, ("getvar(): wrong number of arguments (#{args.length}; must be 1)") - end - - begin - catch(:undefined_variable) do - self.lookupvar("#{args[0]}") - end - rescue Puppet::ParseError # Eat the exception if strict_variables = true is set - end - - end - -end diff --git a/lib/puppet/parser/functions/glob.rb b/lib/puppet/parser/functions/glob.rb new file mode 100644 index 000000000..94bc77028 --- /dev/null +++ b/lib/puppet/parser/functions/glob.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +# +# glob.rb +# +module Puppet::Parser::Functions + newfunction(:glob, type: :rvalue, doc: <<-DOC + @summary + Uses same patterns as Dir#glob. + + @return + Returns an Array of file entries of a directory or an Array of directories. + + @example Example Usage: + $confs = glob(['/etc/**/*.conf', '/opt/**/*.conf']) + DOC + ) do |arguments| + unless arguments.size == 1 + raise(Puppet::ParseError, 'glob(): Wrong number of arguments given ' \ + "(#{arguments.size} for 1)") + end + + pattern = arguments[0] + + unless pattern.is_a?(String) || pattern.is_a?(Array) + raise(Puppet::ParseError, 'glob(): Requires either array or string ' \ + 'to work') + end + + Dir.glob(pattern) + end +end diff --git a/lib/puppet/parser/functions/grep.rb b/lib/puppet/parser/functions/grep.rb index ceba9ecc8..4ae73c45a 100644 --- a/lib/puppet/parser/functions/grep.rb +++ b/lib/puppet/parser/functions/grep.rb @@ -1,32 +1,31 @@ +# frozen_string_literal: true + # # grep.rb # - module Puppet::Parser::Functions - newfunction(:grep, :type => :rvalue, :doc => <<-EOS -This function searches through an array and returns any elements that match -the provided regular expression. - -*Examples:* - - grep(['aaa','bbb','ccc','aaaddd'], 'aaa') - -Would return: - - ['aaa','aaaddd'] - EOS + newfunction(:grep, type: :rvalue, doc: <<-DOC + @summary + This function searches through an array and returns any elements that match + the provided regular expression. + + @return + array of elements that match the provided regular expression. + @example Example Usage: + grep(['aaa','bbb','ccc','aaaddd'], 'aaa') # Returns ['aaa','aaaddd'] + + > **Note:** that since Puppet 4.0.0, the built-in + [`filter`](https://puppet.com/docs/puppet/latest/function.html#filter) function does + the "same" - as any logic can be used to filter, as opposed to just regular expressions: + ```['aaa', 'bbb', 'ccc', 'aaaddd']. filter |$x| { $x =~ 'aaa' }``` + DOC ) do |arguments| - - if (arguments.size != 2) then - raise(Puppet::ParseError, "grep(): Wrong number of arguments "+ - "given #{arguments.size} for 2") - end + raise(Puppet::ParseError, "grep(): Wrong number of arguments given #{arguments.size} for 2") if arguments.size != 2 a = arguments[0] pattern = Regexp.new(arguments[1]) a.grep(pattern) - end end diff --git a/lib/puppet/parser/functions/has_interface_with.rb b/lib/puppet/parser/functions/has_interface_with.rb deleted file mode 100644 index e7627982d..000000000 --- a/lib/puppet/parser/functions/has_interface_with.rb +++ /dev/null @@ -1,71 +0,0 @@ -# -# has_interface_with -# - -module Puppet::Parser::Functions - newfunction(:has_interface_with, :type => :rvalue, :doc => <<-EOS -Returns boolean based on kind and value: - * macaddress - * netmask - * ipaddress - * network - -has_interface_with("macaddress", "x:x:x:x:x:x") -has_interface_with("ipaddress", "127.0.0.1") => true -etc. - -If no "kind" is given, then the presence of the interface is checked: -has_interface_with("lo") => true - EOS - ) do |args| - - raise(Puppet::ParseError, "has_interface_with(): Wrong number of arguments " + - "given (#{args.size} for 1 or 2)") if args.size < 1 or args.size > 2 - - interfaces = lookupvar('interfaces') - - # If we do not have any interfaces, then there are no requested attributes - return false if (interfaces == :undefined || interfaces.nil?) - - interfaces = interfaces.split(',') - - if args.size == 1 - return interfaces.member?(args[0]) - end - - kind, value = args - - # Bug with 3.7.1 - 3.7.3 when using future parser throws :undefined_variable - # https://tickets.puppetlabs.com/browse/PUP-3597 - factval = nil - begin - catch :undefined_variable do - factval = lookupvar(kind) - end - rescue Puppet::ParseError # Eat the exception if strict_variables = true is set - end - if factval == value - return true - end - - result = false - interfaces.each do |iface| - iface.downcase! - factval = nil - begin - # Bug with 3.7.1 - 3.7.3 when using future parser throws :undefined_variable - # https://tickets.puppetlabs.com/browse/PUP-3597 - catch :undefined_variable do - factval = lookupvar("#{kind}_#{iface}") - end - rescue Puppet::ParseError # Eat the exception if strict_variables = true is set - end - if value == factval - result = true - break - end - end - - result - end -end diff --git a/lib/puppet/parser/functions/has_ip_address.rb b/lib/puppet/parser/functions/has_ip_address.rb deleted file mode 100644 index 842c8ec67..000000000 --- a/lib/puppet/parser/functions/has_ip_address.rb +++ /dev/null @@ -1,25 +0,0 @@ -# -# has_ip_address -# - -module Puppet::Parser::Functions - newfunction(:has_ip_address, :type => :rvalue, :doc => <<-EOS -Returns true if the client has the requested IP address on some interface. - -This function iterates through the 'interfaces' fact and checks the -'ipaddress_IFACE' facts, performing a simple string comparison. - EOS - ) do |args| - - raise(Puppet::ParseError, "has_ip_address(): Wrong number of arguments " + - "given (#{args.size} for 1)") if args.size != 1 - - Puppet::Parser::Functions.autoloader.load(:has_interface_with) \ - unless Puppet::Parser::Functions.autoloader.loaded?(:has_interface_with) - - function_has_interface_with(['ipaddress', args[0]]) - - end -end - -# vim:sts=2 sw=2 diff --git a/lib/puppet/parser/functions/has_ip_network.rb b/lib/puppet/parser/functions/has_ip_network.rb deleted file mode 100644 index 9ccf9024f..000000000 --- a/lib/puppet/parser/functions/has_ip_network.rb +++ /dev/null @@ -1,25 +0,0 @@ -# -# has_ip_network -# - -module Puppet::Parser::Functions - newfunction(:has_ip_network, :type => :rvalue, :doc => <<-EOS -Returns true if the client has an IP address within the requested network. - -This function iterates through the 'interfaces' fact and checks the -'network_IFACE' facts, performing a simple string comparision. - EOS - ) do |args| - - raise(Puppet::ParseError, "has_ip_network(): Wrong number of arguments " + - "given (#{args.size} for 1)") if args.size != 1 - - Puppet::Parser::Functions.autoloader.load(:has_interface_with) \ - unless Puppet::Parser::Functions.autoloader.loaded?(:has_interface_with) - - function_has_interface_with(['network', args[0]]) - - end -end - -# vim:sts=2 sw=2 diff --git a/lib/puppet/parser/functions/has_key.rb b/lib/puppet/parser/functions/has_key.rb deleted file mode 100644 index 4657cc29c..000000000 --- a/lib/puppet/parser/functions/has_key.rb +++ /dev/null @@ -1,28 +0,0 @@ -module Puppet::Parser::Functions - - newfunction(:has_key, :type => :rvalue, :doc => <<-'ENDHEREDOC') do |args| - Determine if a hash has a certain key value. - - Example: - - $my_hash = {'key_one' => 'value_one'} - if has_key($my_hash, 'key_two') { - notice('we will not reach here') - } - if has_key($my_hash, 'key_one') { - notice('this will be printed') - } - - ENDHEREDOC - - unless args.length == 2 - raise Puppet::ParseError, ("has_key(): wrong number of arguments (#{args.length}; must be 2)") - end - unless args[0].is_a?(Hash) - raise Puppet::ParseError, "has_key(): expects the first argument to be a hash, got #{args[0].inspect} which is of type #{args[0].class}" - end - args[0].has_key?(args[1]) - - end - -end diff --git a/lib/puppet/parser/functions/hash.rb b/lib/puppet/parser/functions/hash.rb deleted file mode 100644 index 8cc4823be..000000000 --- a/lib/puppet/parser/functions/hash.rb +++ /dev/null @@ -1,41 +0,0 @@ -# -# hash.rb -# - -module Puppet::Parser::Functions - newfunction(:hash, :type => :rvalue, :doc => <<-EOS -This function converts an array into a hash. - -*Examples:* - - hash(['a',1,'b',2,'c',3]) - -Would return: {'a'=>1,'b'=>2,'c'=>3} - EOS - ) do |arguments| - - raise(Puppet::ParseError, "hash(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 - - array = arguments[0] - - unless array.is_a?(Array) - raise(Puppet::ParseError, 'hash(): Requires array to work with') - end - - result = {} - - begin - # This is to make it compatible with older version of Ruby ... - array = array.flatten - result = Hash[*array] - rescue Exception - raise(Puppet::ParseError, 'hash(): Unable to compute ' + - 'hash from array given') - end - - return result - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/intersection.rb b/lib/puppet/parser/functions/intersection.rb index bfbb4babb..0f729faca 100644 --- a/lib/puppet/parser/functions/intersection.rb +++ b/lib/puppet/parser/functions/intersection.rb @@ -1,29 +1,28 @@ +# frozen_string_literal: true + # # intersection.rb # - module Puppet::Parser::Functions - newfunction(:intersection, :type => :rvalue, :doc => <<-EOS -This function returns an array of the intersection of two. + newfunction(:intersection, type: :rvalue, doc: <<-DOC + @summary + This function returns an array of the intersection of two. -*Examples:* + @return + an array of the intersection of two. - intersection(["a","b","c"],["b","c","d"]) # returns ["b","c"] - intersection(["a","b","c"],[1,2,3,4]) # returns [] (true, when evaluated as a Boolean) - - EOS + @example Example Usage: + intersection(["a","b","c"],["b","c","d"]) # returns ["b","c"] + intersection(["a","b","c"],[1,2,3,4]) # returns [] (true, when evaluated as a Boolean) + DOC ) do |arguments| - # Two arguments are required - raise(Puppet::ParseError, "intersection(): Wrong number of arguments " + - "given (#{arguments.size} for 2)") if arguments.size != 2 + raise(Puppet::ParseError, "intersection(): Wrong number of arguments given (#{arguments.size} for 2)") if arguments.size != 2 first = arguments[0] second = arguments[1] - unless first.is_a?(Array) && second.is_a?(Array) - raise(Puppet::ParseError, 'intersection(): Requires 2 arrays') - end + raise(Puppet::ParseError, "intersection(): Requires 2 arrays, got #{first.class} and #{second.class}") unless first.is_a?(Array) && second.is_a?(Array) result = first & second diff --git a/lib/puppet/parser/functions/is_array.rb b/lib/puppet/parser/functions/is_array.rb deleted file mode 100644 index b39e184ae..000000000 --- a/lib/puppet/parser/functions/is_array.rb +++ /dev/null @@ -1,22 +0,0 @@ -# -# is_array.rb -# - -module Puppet::Parser::Functions - newfunction(:is_array, :type => :rvalue, :doc => <<-EOS -Returns true if the variable passed to this function is an array. - EOS - ) do |arguments| - - raise(Puppet::ParseError, "is_array(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 - - type = arguments[0] - - result = type.is_a?(Array) - - return result - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/is_bool.rb b/lib/puppet/parser/functions/is_bool.rb deleted file mode 100644 index 8bbdbc8a1..000000000 --- a/lib/puppet/parser/functions/is_bool.rb +++ /dev/null @@ -1,22 +0,0 @@ -# -# is_bool.rb -# - -module Puppet::Parser::Functions - newfunction(:is_bool, :type => :rvalue, :doc => <<-EOS -Returns true if the variable passed to this function is a boolean. - EOS - ) do |arguments| - - raise(Puppet::ParseError, "is_bool(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size != 1 - - type = arguments[0] - - result = type.is_a?(TrueClass) || type.is_a?(FalseClass) - - return result - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/is_domain_name.rb b/lib/puppet/parser/functions/is_domain_name.rb deleted file mode 100644 index 90ede3272..000000000 --- a/lib/puppet/parser/functions/is_domain_name.rb +++ /dev/null @@ -1,54 +0,0 @@ -# -# is_domain_name.rb -# - -module Puppet::Parser::Functions - newfunction(:is_domain_name, :type => :rvalue, :doc => <<-EOS -Returns true if the string passed to this function is a syntactically correct domain name. - EOS - ) do |arguments| - - if (arguments.size != 1) then - raise(Puppet::ParseError, "is_domain_name(): Wrong number of arguments "+ - "given #{arguments.size} for 1") - end - - # Only allow string types - return false unless arguments[0].is_a?(String) - - domain = arguments[0].dup - - # Limits (rfc1035, 3.1) - domain_max_length=255 - label_min_length=1 - label_max_length=63 - - # Allow ".", it is the top level domain - return true if domain == '.' - - # Remove the final dot, if present. - domain.chomp!('.') - - # Check the whole domain - return false if domain.empty? - return false if domain.length > domain_max_length - - # The top level domain must be alphabetic if there are multiple labels. - # See rfc1123, 2.1 - return false if domain.include? '.' and not /\.[A-Za-z]+$/.match(domain) - - # Check each label in the domain - labels = domain.split('.') - vlabels = labels.each do |label| - break if label.length < label_min_length - break if label.length > label_max_length - break if label[-1..-1] == '-' - break if label[0..0] == '-' - break unless /^[a-z\d-]+$/i.match(label) - end - return vlabels == labels - - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/is_float.rb b/lib/puppet/parser/functions/is_float.rb deleted file mode 100644 index a2da94385..000000000 --- a/lib/puppet/parser/functions/is_float.rb +++ /dev/null @@ -1,30 +0,0 @@ -# -# is_float.rb -# - -module Puppet::Parser::Functions - newfunction(:is_float, :type => :rvalue, :doc => <<-EOS -Returns true if the variable passed to this function is a float. - EOS - ) do |arguments| - - if (arguments.size != 1) then - raise(Puppet::ParseError, "is_float(): Wrong number of arguments "+ - "given #{arguments.size} for 1") - end - - value = arguments[0] - - # Only allow Numeric or String types - return false unless value.is_a?(Numeric) or value.is_a?(String) - - if value != value.to_f.to_s and !value.is_a? Float then - return false - else - return true - end - - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/is_function_available.rb b/lib/puppet/parser/functions/is_function_available.rb deleted file mode 100644 index 6da82c8c1..000000000 --- a/lib/puppet/parser/functions/is_function_available.rb +++ /dev/null @@ -1,26 +0,0 @@ -# -# is_function_available.rb -# - -module Puppet::Parser::Functions - newfunction(:is_function_available, :type => :rvalue, :doc => <<-EOS -This function accepts a string as an argument, determines whether the -Puppet runtime has access to a function by that name. It returns a -true if the function exists, false if not. - EOS - ) do |arguments| - - if (arguments.size != 1) then - raise(Puppet::ParseError, "is_function_available?(): Wrong number of arguments "+ - "given #{arguments.size} for 1") - end - - # Only allow String types - return false unless arguments[0].is_a?(String) - - function = Puppet::Parser::Functions.function(arguments[0].to_sym) - function.is_a?(String) and not function.empty? - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/is_hash.rb b/lib/puppet/parser/functions/is_hash.rb deleted file mode 100644 index ad907f086..000000000 --- a/lib/puppet/parser/functions/is_hash.rb +++ /dev/null @@ -1,22 +0,0 @@ -# -# is_hash.rb -# - -module Puppet::Parser::Functions - newfunction(:is_hash, :type => :rvalue, :doc => <<-EOS -Returns true if the variable passed to this function is a hash. - EOS - ) do |arguments| - - raise(Puppet::ParseError, "is_hash(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size != 1 - - type = arguments[0] - - result = type.is_a?(Hash) - - return result - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/is_integer.rb b/lib/puppet/parser/functions/is_integer.rb deleted file mode 100644 index c03d28df9..000000000 --- a/lib/puppet/parser/functions/is_integer.rb +++ /dev/null @@ -1,45 +0,0 @@ -# -# is_integer.rb -# - -module Puppet::Parser::Functions - newfunction(:is_integer, :type => :rvalue, :doc => <<-EOS -Returns true if the variable passed to this function is an Integer or -a decimal (base 10) integer in String form. The string may -start with a '-' (minus). A value of '0' is allowed, but a leading '0' digit may not -be followed by other digits as this indicates that the value is octal (base 8). - -If given any other argument `false` is returned. - EOS - ) do |arguments| - - if (arguments.size != 1) then - raise(Puppet::ParseError, "is_integer(): Wrong number of arguments "+ - "given #{arguments.size} for 1") - end - - value = arguments[0] - - # Regex is taken from the lexer of puppet - # puppet/pops/parser/lexer.rb but modified to match also - # negative values and disallow numbers prefixed with multiple - # 0's - # - # TODO these parameter should be a constant but I'm not sure - # if there is no risk to declare it inside of the module - # Puppet::Parser::Functions - - # Integer numbers like - # -1234568981273 - # 47291 - numeric = %r{^-?(?:(?:[1-9]\d*)|0)$} - - if value.is_a? Integer or (value.is_a? String and value.match numeric) - return true - else - return false - end - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/is_ip_address.rb b/lib/puppet/parser/functions/is_ip_address.rb deleted file mode 100644 index a90adabe1..000000000 --- a/lib/puppet/parser/functions/is_ip_address.rb +++ /dev/null @@ -1,32 +0,0 @@ -# -# is_ip_address.rb -# - -module Puppet::Parser::Functions - newfunction(:is_ip_address, :type => :rvalue, :doc => <<-EOS -Returns true if the string passed to this function is a valid IP address. - EOS - ) do |arguments| - - require 'ipaddr' - - if (arguments.size != 1) then - raise(Puppet::ParseError, "is_ip_address(): Wrong number of arguments "+ - "given #{arguments.size} for 1") - end - - begin - ip = IPAddr.new(arguments[0]) - rescue ArgumentError - return false - end - - if ip.ipv4? or ip.ipv6? then - return true - else - return false - end - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/is_mac_address.rb b/lib/puppet/parser/functions/is_mac_address.rb deleted file mode 100644 index 2619d44a3..000000000 --- a/lib/puppet/parser/functions/is_mac_address.rb +++ /dev/null @@ -1,27 +0,0 @@ -# -# is_mac_address.rb -# - -module Puppet::Parser::Functions - newfunction(:is_mac_address, :type => :rvalue, :doc => <<-EOS -Returns true if the string passed to this function is a valid mac address. - EOS - ) do |arguments| - - if (arguments.size != 1) then - raise(Puppet::ParseError, "is_mac_address(): Wrong number of arguments "+ - "given #{arguments.size} for 1") - end - - mac = arguments[0] - - if /^[a-f0-9]{1,2}(:[a-f0-9]{1,2}){5}$/i.match(mac) then - return true - else - return false - end - - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/is_numeric.rb b/lib/puppet/parser/functions/is_numeric.rb deleted file mode 100644 index e7e1d2a74..000000000 --- a/lib/puppet/parser/functions/is_numeric.rb +++ /dev/null @@ -1,75 +0,0 @@ -# -# is_numeric.rb -# - -module Puppet::Parser::Functions - newfunction(:is_numeric, :type => :rvalue, :doc => <<-EOS -Returns true if the given argument is a Numeric (Integer or Float), -or a String containing either a valid integer in decimal base 10 form, or -a valid floating point string representation. - -The function recognizes only decimal (base 10) integers and float but not -integers in hex (base 16) or octal (base 8) form. - -The string representation may start with a '-' (minus). If a decimal '.' is used, -it must be followed by at least one digit. - -Valid examples: - - 77435 - 10e-12 - -8475 - 0.2343 - -23.561e3 - EOS - ) do |arguments| - - if (arguments.size != 1) then - raise(Puppet::ParseError, "is_numeric(): Wrong number of arguments "+ - "given #{arguments.size} for 1") - end - - value = arguments[0] - - # Regex is taken from the lexer of puppet - # puppet/pops/parser/lexer.rb but modified to match also - # negative values and disallow invalid octal numbers or - # numbers prefixed with multiple 0's (except in hex numbers) - # - # TODO these parameters should be constants but I'm not sure - # if there is no risk to declare them inside of the module - # Puppet::Parser::Functions - - # TODO decide if this should be used - # HEX numbers like - # 0xaa230F - # 0X1234009C - # 0x0012 - # -12FcD - #numeric_hex = %r{^-?0[xX][0-9A-Fa-f]+$} - - # TODO decide if this should be used - # OCTAL numbers like - # 01234567 - # -045372 - #numeric_oct = %r{^-?0[1-7][0-7]*$} - - # Integer/Float numbers like - # -0.1234568981273 - # 47291 - # 42.12345e-12 - numeric = %r{^-?(?:(?:[1-9]\d*)|0)(?:\.\d+)?(?:[eE]-?\d+)?$} - - if value.is_a? Numeric or (value.is_a? String and ( - value.match(numeric) #or - # value.match(numeric_hex) or - # value.match(numeric_oct) - )) - return true - else - return false - end - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/is_string.rb b/lib/puppet/parser/functions/is_string.rb deleted file mode 100644 index f5bef0457..000000000 --- a/lib/puppet/parser/functions/is_string.rb +++ /dev/null @@ -1,26 +0,0 @@ -# -# is_string.rb -# - -module Puppet::Parser::Functions - newfunction(:is_string, :type => :rvalue, :doc => <<-EOS -Returns true if the variable passed to this function is a string. - EOS - ) do |arguments| - - raise(Puppet::ParseError, "is_string(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 - - type = arguments[0] - - result = type.is_a?(String) - - if result and (type == type.to_f.to_s or type == type.to_i.to_s) then - return false - end - - return result - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/join.rb b/lib/puppet/parser/functions/join.rb deleted file mode 100644 index 6c0a6ba02..000000000 --- a/lib/puppet/parser/functions/join.rb +++ /dev/null @@ -1,41 +0,0 @@ -# -# join.rb -# - -module Puppet::Parser::Functions - newfunction(:join, :type => :rvalue, :doc => <<-EOS -This function joins an array into a string using a separator. - -*Examples:* - - join(['a','b','c'], ",") - -Would result in: "a,b,c" - EOS - ) do |arguments| - - # Technically we support two arguments but only first is mandatory ... - raise(Puppet::ParseError, "join(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 - - array = arguments[0] - - unless array.is_a?(Array) - raise(Puppet::ParseError, 'join(): Requires array to work with') - end - - suffix = arguments[1] if arguments[1] - - if suffix - unless suffix.is_a?(String) - raise(Puppet::ParseError, 'join(): Requires string to work with') - end - end - - result = suffix ? array.join(suffix) : array.join - - return result - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/join_keys_to_values.rb b/lib/puppet/parser/functions/join_keys_to_values.rb index e9924fe2e..d456a4e4b 100644 --- a/lib/puppet/parser/functions/join_keys_to_values.rb +++ b/lib/puppet/parser/functions/join_keys_to_values.rb @@ -1,46 +1,52 @@ +# frozen_string_literal: true + # -# join.rb +# join_keys_to_values.rb # - module Puppet::Parser::Functions - newfunction(:join_keys_to_values, :type => :rvalue, :doc => <<-EOS -This function joins each key of a hash to that key's corresponding value with a -separator. Keys and values are cast to strings. The return value is an array in -which each element is one joined key/value pair. - -*Examples:* - - join_keys_to_values({'a'=>1,'b'=>2}, " is ") - -Would result in: ["a is 1","b is 2"] - EOS + newfunction(:join_keys_to_values, type: :rvalue, doc: <<-DOC + @summary + This function joins each key of a hash to that key's corresponding value with a + separator. + + Keys are cast to strings. If values are arrays, multiple keys + are added for each element. The return value is an array in + which each element is one joined key/value pair. + + @example Example Usage: + join_keys_to_values({'a'=>1,'b'=>2}, " is ") # Results in: ["a is 1","b is 2"] + join_keys_to_values({'a'=>1,'b'=>[2,3]}, " is ") # Results in: ["a is 1","b is 2","b is 3"] + + @return [Hash] + The joined hash + + > **Note:** Since Puppet 5.0.0 - for more detailed control over the formatting (including indentations and + line breaks, delimiters around arrays and hash entries, between key/values in hash entries, and individual + formatting of values in the array) - see the `new` function for `String` and its formatting + options for `Array` and `Hash`. + DOC ) do |arguments| - # Validate the number of arguments. - if arguments.size != 2 - raise(Puppet::ParseError, "join_keys_to_values(): Takes exactly two " + - "arguments, but #{arguments.size} given.") - end + raise(Puppet::ParseError, "join_keys_to_values(): Takes exactly two arguments, but #{arguments.size} given.") if arguments.size != 2 # Validate the first argument. hash = arguments[0] - if not hash.is_a?(Hash) - raise(TypeError, "join_keys_to_values(): The first argument must be a " + - "hash, but a #{hash.class} was given.") - end + raise(TypeError, "join_keys_to_values(): The first argument must be a hash, but a #{hash.class} was given.") unless hash.is_a?(Hash) # Validate the second argument. separator = arguments[1] - if not separator.is_a?(String) - raise(TypeError, "join_keys_to_values(): The second argument must be a " + - "string, but a #{separator.class} was given.") - end + raise(TypeError, "join_keys_to_values(): The second argument must be a string, but a #{separator.class} was given.") unless separator.is_a?(String) # Join the keys to their values. - hash.map do |k,v| - String(k) + separator + String(v) - end - + hash.map { |k, v| + if v.is_a?(Array) + v.map { |va| String(k) + separator + String(va) } + elsif String(v) == 'undef' + String(k) + else + String(k) + separator + String(v) + end + }.flatten end end diff --git a/lib/puppet/parser/functions/keys.rb b/lib/puppet/parser/functions/keys.rb deleted file mode 100644 index f0d13b647..000000000 --- a/lib/puppet/parser/functions/keys.rb +++ /dev/null @@ -1,26 +0,0 @@ -# -# keys.rb -# - -module Puppet::Parser::Functions - newfunction(:keys, :type => :rvalue, :doc => <<-EOS -Returns the keys of a hash as an array. - EOS - ) do |arguments| - - raise(Puppet::ParseError, "keys(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 - - hash = arguments[0] - - unless hash.is_a?(Hash) - raise(Puppet::ParseError, 'keys(): Requires hash to work with') - end - - result = hash.keys - - return result - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/load_module_metadata.rb b/lib/puppet/parser/functions/load_module_metadata.rb index c9b84885b..d5c6672b8 100644 --- a/lib/puppet/parser/functions/load_module_metadata.rb +++ b/lib/puppet/parser/functions/load_module_metadata.rb @@ -1,22 +1,38 @@ +# frozen_string_literal: true + +# +# load_module_metadata.rb +# module Puppet::Parser::Functions - newfunction(:load_module_metadata, :type => :rvalue, :doc => <<-EOT - EOT + newfunction(:load_module_metadata, type: :rvalue, doc: <<-DOC + @summary + This function loads the metadata of a given module. + + @example Example Usage: + $metadata = load_module_metadata('archive') + notify { $metadata['author']: } + + @return + The modules metadata + DOC ) do |args| - raise(Puppet::ParseError, "load_module_metadata(): Wrong number of arguments, expects one or two") unless [1,2].include?(args.size) + raise(Puppet::ParseError, 'load_module_metadata(): Wrong number of arguments, expects one or two') unless [1, 2].include?(args.size) + mod = args[0] allow_empty_metadata = args[1] module_path = function_get_module_path([mod]) metadata_json = File.join(module_path, 'metadata.json') - metadata_exists = File.exists?(metadata_json) + metadata_exists = File.exist?(metadata_json) if metadata_exists - metadata = PSON.load(File.read(metadata_json)) + metadata = if Puppet::Util::Package.versioncmp(Puppet.version, '8.0.0').negative? + PSON.load(File.read(metadata_json)) + else + JSON.parse(File.read(metadata_json)) + end else - if allow_empty_metadata - metadata = {} - else - raise(Puppet::ParseError, "load_module_metadata(): No metadata.json file for module #{mod}") - end + metadata = {} + raise(Puppet::ParseError, "load_module_metadata(): No metadata.json file for module #{mod}") unless allow_empty_metadata end return metadata diff --git a/lib/puppet/parser/functions/loadjson.rb b/lib/puppet/parser/functions/loadjson.rb new file mode 100644 index 000000000..a85cd18ee --- /dev/null +++ b/lib/puppet/parser/functions/loadjson.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +# +# loadjson.rb +# + +module Puppet::Parser::Functions + newfunction(:loadjson, type: :rvalue, arity: -2, doc: <<-DOC) do |args| + @summary + Load a JSON file containing an array, string, or hash, and return the data + in the corresponding native data type. + + The first parameter can be a file path or a URL. + The second parameter is the default value. It will be returned if the file + was not found or could not be parsed. + + @return [Array|String|Hash] + The data stored in the JSON file, the type depending on the type of data that was stored. + + @example Example Usage: + $myhash = loadjson('/etc/puppet/data/myhash.json') + $myhash = loadjson('https://example.local/my_hash.json') + $myhash = loadjson('https://username:password@example.local/my_hash.json') + $myhash = loadjson('no-file.json', {'default' => 'value'}) + DOC + + raise ArgumentError, 'Wrong number of arguments. 1 or 2 arguments should be provided.' unless args.length >= 1 + + require 'open-uri' + begin + if args[0].start_with?('http://', 'https://') + http_options = {} + if (match = args[0].match(%r{(http://|https://)(.*):(.*)@(.*)})) + # If URL is in the format of https://username:password@example.local/my_hash.yaml + protocol, username, password, path = match.captures + url = "#{protocol}#{path}" + http_options[:http_basic_authentication] = [username, password] + elsif (match = args[0].match(%r{(http://|https://)(.*)@(.*)})) + # If URL is in the format of https://username@example.local/my_hash.yaml + protocol, username, path = match.captures + url = "#{protocol}#{path}" + http_options[:http_basic_authentication] = [username, ''] + else + url = args[0] + end + begin + contents = OpenURI.open_uri(url, http_options) + rescue OpenURI::HTTPError => e + res = e.io + warning("Can't load '#{url}' HTTP Error Code: '#{res.status[0]}'") + args[1] + end + if Puppet::Util::Package.versioncmp(Puppet.version, '8.0.0').negative? + PSON.load(contents) || args[1] + else + JSON.parse(contents) || args[1] + end + elsif File.exist?(args[0]) + content = File.read(args[0]) + if Puppet::Util::Package.versioncmp(Puppet.version, '8.0.0').negative? + PSON.load(content) || args[1] + else + JSON.parse(content) || args[1] + end + else + warning("Can't load '#{args[0]}' File does not exist!") + args[1] + end + rescue StandardError => e + raise e unless args[1] + + args[1] + end + end +end diff --git a/lib/puppet/parser/functions/loadyaml.rb b/lib/puppet/parser/functions/loadyaml.rb index ca655f6ea..22bceb72b 100644 --- a/lib/puppet/parser/functions/loadyaml.rb +++ b/lib/puppet/parser/functions/loadyaml.rb @@ -1,25 +1,68 @@ +# frozen_string_literal: true + +# +# loadyaml.rb +# module Puppet::Parser::Functions + newfunction(:loadyaml, type: :rvalue, arity: -2, doc: <<-DOC) do |args| + @summary + Load a YAML file containing an array, string, or hash, and return the data + in the corresponding native data type. - newfunction(:loadyaml, :type => :rvalue, :doc => <<-'ENDHEREDOC') do |args| - Load a YAML file containing an array, string, or hash, and return the data - in the corresponding native data type. + The first parameter can be a file path or a URL. + The second parameter is the default value. It will be returned if the file + was not found or could not be parsed. - For example: + @return [Array|String|Hash] + The data stored in the YAML file, the type depending on the type of data that was stored. + @example Example Usage: $myhash = loadyaml('/etc/puppet/data/myhash.yaml') - ENDHEREDOC + $myhash = loadyaml('https://example.local/my_hash.yaml') + $myhash = loadyaml('https://username:password@example.local/my_hash.yaml') + $myhash = loadyaml('no-file.yaml', {'default' => 'value'}) + DOC - unless args.length == 1 - raise Puppet::ParseError, ("loadyaml(): wrong number of arguments (#{args.length}; must be 1)") - end + raise ArgumentError, 'Wrong number of arguments. 1 or 2 arguments should be provided.' unless args.length >= 1 - if File.exists?(args[0]) then - YAML.load_file(args[0]) - else - warning("Can't load " + args[0] + ". File does not exist!") - nil - end + require 'yaml' + require 'open-uri' + begin + if args[0].start_with?('http://', 'https://') + username = '' + password = '' + if (match = args[0].match(%r{(http://|https://)(.*):(.*)@(.*)})) + # If URL is in the format of https://username:password@example.local/my_hash.yaml + protocol, username, password, path = match.captures + url = "#{protocol}#{path}" + elsif (match = args[0].match(%r{(http://|https://)(.*)@(.*)})) + # If URL is in the format of https://username@example.local/my_hash.yaml + protocol, username, path = match.captures + url = "#{protocol}#{path}" + else + url = args[0] + end + begin + contents = OpenURI.open_uri(url, http_basic_authentication: [username, password]) + rescue OpenURI::HTTPError => e + res = e.io + warning("Can't load '#{url}' HTTP Error Code: '#{res.status[0]}'") + args[1] + end + YAML.safe_load(contents, aliases: true) || args[1] + elsif File.exist?(args[0]) + # Read the file first rather than calling YAML.load_file as ruby2.7 + # doesn't support the aliases option on YAML.load_file + contents = File.read(args[0]) + YAML.safe_load(contents, aliases: true) || args[1] + else + warning("Can't load '#{args[0]}' File does not exist!") + args[1] + end + rescue StandardError => e + raise e unless args[1] + args[1] + end end - end diff --git a/lib/puppet/parser/functions/lstrip.rb b/lib/puppet/parser/functions/lstrip.rb deleted file mode 100644 index 624e4c846..000000000 --- a/lib/puppet/parser/functions/lstrip.rb +++ /dev/null @@ -1,32 +0,0 @@ -# -# lstrip.rb -# - -module Puppet::Parser::Functions - newfunction(:lstrip, :type => :rvalue, :doc => <<-EOS -Strips leading spaces to the left of a string. - EOS - ) do |arguments| - - raise(Puppet::ParseError, "lstrip(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 - - value = arguments[0] - - unless value.is_a?(Array) || value.is_a?(String) - raise(Puppet::ParseError, 'lstrip(): Requires either ' + - 'array or string to work with') - end - - if value.is_a?(Array) - # Numbers in Puppet are often string-encoded which is troublesome ... - result = value.collect { |i| i.is_a?(String) ? i.lstrip : i } - else - result = value.lstrip - end - - return result - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/max.rb b/lib/puppet/parser/functions/max.rb deleted file mode 100644 index 60fb94ac0..000000000 --- a/lib/puppet/parser/functions/max.rb +++ /dev/null @@ -1,21 +0,0 @@ -module Puppet::Parser::Functions - newfunction(:max, :type => :rvalue, :doc => <<-EOS - Returns the highest value of all arguments. - Requires at least one argument. - EOS - ) do |args| - - raise(Puppet::ParseError, "max(): Wrong number of arguments " + - "need at least one") if args.size == 0 - - # Sometimes we get numbers as numerics and sometimes as strings. - # We try to compare them as numbers when possible - return args.max do |a,b| - if a.to_s =~ /\A-?\d+(.\d+)?\z/ and b.to_s =~ /\A-?\d+(.\d+)?\z/ then - a.to_f <=> b.to_f - else - a.to_s <=> b.to_s - end - end - end -end diff --git a/lib/puppet/parser/functions/member.rb b/lib/puppet/parser/functions/member.rb index 1e5b3def9..b9bbeb717 100644 --- a/lib/puppet/parser/functions/member.rb +++ b/lib/puppet/parser/functions/member.rb @@ -1,57 +1,57 @@ -# -# member.rb -# +# frozen_string_literal: true # TODO(Krzysztof Wilczynski): We need to add support for regular expression ... # TODO(Krzysztof Wilczynski): Support for strings and hashes too ... - +# +# member.rb +# module Puppet::Parser::Functions - newfunction(:member, :type => :rvalue, :doc => <<-EOS -This function determines if a variable is a member of an array. -The variable can be a string, fixnum, or array. - -*Examples:* - - member(['a','b'], 'b') - -Would return: true - - member(['a', 'b', 'c'], ['a', 'b']) - -would return: true - - member(['a','b'], 'c') - -Would return: false - - member(['a', 'b', 'c'], ['d', 'b']) - -would return: false - EOS + newfunction(:member, type: :rvalue, doc: <<-DOC + @summary + This function determines if a variable is a member of an array. + + The variable can be a string, fixnum, or array. + + > **Note**: This function does not support nested arrays. If the first argument contains + nested arrays, it will not recurse through them. + + @example **Usage** + member(['a','b'], 'b') # Returns: true + member(['a', 'b', 'c'], ['a', 'b']) # Returns: true + member(['a','b'], 'c') # Returns: false + member(['a', 'b', 'c'], ['d', 'b']) # Returns: false + + > *Note:* + Since Puppet 4.0.0 the same can be performed in the Puppet language. + For single values the operator `in` can be used: + `'a' in ['a', 'b'] # true` + For arrays by using operator `-` to compute a diff: + `['d', 'b'] - ['a', 'b', 'c'] == [] # false because 'd' is not subtracted` + `['a', 'b'] - ['a', 'b', 'c'] == [] # true because both 'a' and 'b' are subtracted` + + @return + Returns whether the given value was a member of the array + + > **Note** that since Puppet 5.2.0, the general form to test the content of an array or + hash is to use the built-in [`any`](https://puppet.com/docs/puppet/latest/function.html#any) + and [`all`](https://puppet.com/docs/puppet/latest/function.html#all) functions. + DOC ) do |arguments| - - raise(Puppet::ParseError, "member(): Wrong number of arguments " + - "given (#{arguments.size} for 2)") if arguments.size < 2 + raise(Puppet::ParseError, "member(): Wrong number of arguments given (#{arguments.size} for 2)") if arguments.size < 2 array = arguments[0] - unless array.is_a?(Array) - raise(Puppet::ParseError, 'member(): Requires array to work with') - end - - unless arguments[1].is_a? String or arguments[1].is_a? Fixnum or arguments[1].is_a? Array - raise(Puppet::ParseError, 'member(): Item to search for must be a string, fixnum, or array') - end + raise(Puppet::ParseError, 'member(): Requires array to work with') unless array.is_a?(Array) - if arguments[1].is_a? String or arguments[1].is_a? Fixnum - item = [arguments[1]] - else - item = arguments[1] - end + raise(Puppet::ParseError, 'member(): Item to search for must be a string, fixnum, or array') unless arguments[1].is_a?(String) || arguments[1].is_a?(Integer) || arguments[1].is_a?(Array) + item = if arguments[1].is_a?(String) || arguments[1].is_a?(Integer) + [arguments[1]] + else + arguments[1] + end - raise(Puppet::ParseError, 'member(): You must provide item ' + - 'to search for within array given') if item.respond_to?('empty?') && item.empty? + raise(Puppet::ParseError, 'member(): You must provide item to search for within array given') if item.respond_to?(:empty?) && item.empty? result = (item - array).empty? diff --git a/lib/puppet/parser/functions/merge.rb b/lib/puppet/parser/functions/merge.rb index 1b39f2060..5e9d79d47 100644 --- a/lib/puppet/parser/functions/merge.rb +++ b/lib/puppet/parser/functions/merge.rb @@ -1,31 +1,36 @@ -module Puppet::Parser::Functions - newfunction(:merge, :type => :rvalue, :doc => <<-'ENDHEREDOC') do |args| - Merges two or more hashes together and returns the resulting hash. +# frozen_string_literal: true - For example: +# +# merge.rb +# +module Puppet::Parser::Functions + newfunction(:merge, type: :rvalue, doc: <<-DOC) do |args| + @summary + Merges two or more hashes together and returns the resulting hash. - $hash1 = {'one' => 1, 'two', => 2} - $hash2 = {'two' => 'dos', 'three', => 'tres'} - $merged_hash = merge($hash1, $hash2) - # The resulting hash is equivalent to: - # $merged_hash = {'one' => 1, 'two' => 'dos', 'three' => 'tres'} + @example **Usage** + $hash1 = {'one' => 1, 'two', => 2} + $hash2 = {'two' => 'dos', 'three', => 'tres'} + $merged_hash = merge($hash1, $hash2) # $merged_hash = {'one' => 1, 'two' => 'dos', 'three' => 'tres'} When there is a duplicate key, the key in the rightmost hash will "win." - ENDHEREDOC + @return [Hash] + The merged hash - if args.length < 2 - raise Puppet::ParseError, ("merge(): wrong number of arguments (#{args.length}; must be at least 2)") - end + Note that since Puppet 4.0.0 the same merge can be achieved with the + operator. + `$merged_hash = $hash1 + $hash2` + DOC + + raise Puppet::ParseError, "merge(): wrong number of arguments (#{args.length}; must be at least 2)" if args.length < 2 # The hash we accumulate into - accumulator = Hash.new + accumulator = {} # Merge into the accumulator hash args.each do |arg| - next if arg.is_a? String and arg.empty? # empty string is synonym for puppet's undef - unless arg.is_a?(Hash) - raise Puppet::ParseError, "merge: unexpected argument type #{arg.class}, only expects hash arguments" - end + next if arg.is_a?(String) && arg.empty? # empty string is synonym for puppet's undef + raise Puppet::ParseError, "merge: unexpected argument type #{arg.class}, only expects hash arguments" unless arg.is_a?(Hash) + accumulator.merge!(arg) end # Return the fully merged hash diff --git a/lib/puppet/parser/functions/min.rb b/lib/puppet/parser/functions/min.rb deleted file mode 100644 index 6bd6ebf20..000000000 --- a/lib/puppet/parser/functions/min.rb +++ /dev/null @@ -1,21 +0,0 @@ -module Puppet::Parser::Functions - newfunction(:min, :type => :rvalue, :doc => <<-EOS - Returns the lowest value of all arguments. - Requires at least one argument. - EOS - ) do |args| - - raise(Puppet::ParseError, "min(): Wrong number of arguments " + - "need at least one") if args.size == 0 - - # Sometimes we get numbers as numerics and sometimes as strings. - # We try to compare them as numbers when possible - return args.min do |a,b| - if a.to_s =~ /\A^-?\d+(.\d+)?\z/ and b.to_s =~ /\A-?\d+(.\d+)?\z/ then - a.to_f <=> b.to_f - else - a.to_s <=> b.to_s - end - end - end -end diff --git a/lib/puppet/parser/functions/num2bool.rb b/lib/puppet/parser/functions/num2bool.rb index af0e6ed78..50891df3b 100644 --- a/lib/puppet/parser/functions/num2bool.rb +++ b/lib/puppet/parser/functions/num2bool.rb @@ -1,17 +1,23 @@ +# frozen_string_literal: true + # # num2bool.rb # - module Puppet::Parser::Functions - newfunction(:num2bool, :type => :rvalue, :doc => <<-EOS -This function converts a number or a string representation of a number into a -true boolean. Zero or anything non-numeric becomes false. Numbers higher then 0 -become true. - EOS - ) do |arguments| + newfunction(:num2bool, type: :rvalue, doc: <<-DOC + @summary + This function converts a number or a string representation of a number into a + true boolean. - raise(Puppet::ParseError, "num2bool(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size != 1 + > *Note:* that since Puppet 5.0.0 the same can be achieved with the Puppet Type System. + See the new() function in Puppet for the many available type conversions. + + @return [Boolean] + Boolean(0) # false for any zero or negative number + Boolean(1) # true for any positive number + DOC + ) do |arguments| + raise(Puppet::ParseError, "num2bool(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.size != 1 number = arguments[0] @@ -21,14 +27,14 @@ module Puppet::Parser::Functions when String begin number = Float(number) - rescue ArgumentError => ex - raise(Puppet::ParseError, "num2bool(): '#{number}' does not look like a number: #{ex.message}") + rescue ArgumentError => e + raise(Puppet::ParseError, "num2bool(): '#{number}' does not look like a number: #{e.message}") end else begin number = number.to_s - rescue NoMethodError => ex - raise(Puppet::ParseError, "num2bool(): Unable to parse argument: #{ex.message}") + rescue NoMethodError => e + raise(Puppet::ParseError, "num2bool(): Unable to parse argument: #{e.message}") end end @@ -36,7 +42,7 @@ module Puppet::Parser::Functions number = number.to_i # Return true for any positive number and false otherwise - return number > 0 + return number.positive? end end diff --git a/lib/puppet/parser/functions/parsejson.rb b/lib/puppet/parser/functions/parsejson.rb index b4af40e7e..fa7c66f30 100644 --- a/lib/puppet/parser/functions/parsejson.rb +++ b/lib/puppet/parser/functions/parsejson.rb @@ -1,28 +1,33 @@ +# frozen_string_literal: true + +require 'puppet/util/json' # # parsejson.rb # - module Puppet::Parser::Functions - newfunction(:parsejson, :type => :rvalue, :doc => <<-EOS -This function accepts JSON as a string and converts it into the correct -Puppet structure. + newfunction(:parsejson, type: :rvalue, doc: <<-DOC + @summary + This function accepts JSON as a string and converts it into the correct + Puppet structure. + + @return + convert JSON into Puppet structure -The optional second argument can be used to pass a default value that will -be returned if the parsing of YAML string have failed. - EOS + > *Note:* + The optional second argument can be used to pass a default value that will + be returned if the parsing of the JSON string failed or if the JSON parse + evaluated to nil. + DOC ) do |arguments| raise ArgumentError, 'Wrong number of arguments. 1 or 2 arguments should be provided.' unless arguments.length >= 1 begin - PSON::load(arguments[0]) || arguments[1] - rescue Exception => e - if arguments[1] - arguments[1] - else - raise e - end - end + Puppet::Util::Json.load(arguments[0]) || arguments[1] + rescue StandardError => e + raise e unless arguments[1] + arguments[1] + end end end diff --git a/lib/puppet/parser/functions/parseyaml.rb b/lib/puppet/parser/functions/parseyaml.rb index 66d04131e..014c12d26 100644 --- a/lib/puppet/parser/functions/parseyaml.rb +++ b/lib/puppet/parser/functions/parseyaml.rb @@ -1,29 +1,36 @@ +# frozen_string_literal: true + # # parseyaml.rb # - module Puppet::Parser::Functions - newfunction(:parseyaml, :type => :rvalue, :doc => <<-EOS -This function accepts YAML as a string and converts it into the correct -Puppet structure. + newfunction(:parseyaml, type: :rvalue, doc: <<-DOC + @summary + This function accepts YAML as a string and converts it into the correct + Puppet structure. + + @return + converted YAML into Puppet structure -The optional second argument can be used to pass a default value that will -be returned if the parsing of YAML string have failed. - EOS + > *Note:* + The optional second argument can be used to pass a default value that will + be returned if the parsing of YAML string have failed. + DOC ) do |arguments| raise ArgumentError, 'Wrong number of arguments. 1 or 2 arguments should be provided.' unless arguments.length >= 1 + require 'yaml' begin - YAML::load(arguments[0]) || arguments[1] - rescue Exception => e - if arguments[1] - arguments[1] - else - raise e - end - end + YAML.load(arguments[0]) || arguments[1] # : using YAML.safe_load causes the code to break + # in ruby 1.9.3 Psych::SyntaxError is a RuntimeException + # this still needs to catch that and work also on rubies that + # do not have Psych available. + rescue StandardError, Psych::SyntaxError => e # rubocop:disable Lint/ShadowedException : See above + raise e unless arguments[1] + arguments[1] + end end end diff --git a/lib/puppet/parser/functions/pick.rb b/lib/puppet/parser/functions/pick.rb index fdd0aefd7..c344f7bbc 100644 --- a/lib/puppet/parser/functions/pick.rb +++ b/lib/puppet/parser/functions/pick.rb @@ -1,29 +1,37 @@ +# frozen_string_literal: true + +# +# pick.rb +# module Puppet::Parser::Functions - newfunction(:pick, :type => :rvalue, :doc => <<-EOS + newfunction(:pick, type: :rvalue, doc: <<-EOS + @summary + This function will return + the first value in a list of values that is not undefined or an empty string. + + This function is similar to a coalesce function in SQL. + + @return + the first value in a list of values that is not undefined or an empty string. -This function is similar to a coalesce function in SQL in that it will return -the first value in a list of values that is not undefined or an empty string -(two things in Puppet that will return a boolean false value). Typically, -this function is used to check for a value in the Puppet Dashboard/Enterprise -Console, and failover to a default value like the following: + Typically, this function is used to check for a value in the Puppet + Dashboard/Enterprise Console, and failover to a default value like the following: - $real_jenkins_version = pick($::jenkins_version, '1.449') + ```$real_jenkins_version = pick($::jenkins_version, '1.449')``` -The value of $real_jenkins_version will first look for a top-scope variable -called 'jenkins_version' (note that parameters set in the Puppet Dashboard/ -Enterprise Console are brought into Puppet as top-scope variables), and, -failing that, will use a default value of 1.449. + > *Note:* + The value of $real_jenkins_version will first look for a top-scope variable + called 'jenkins_version' (note that parameters set in the Puppet Dashboard/ + Enterprise Console are brought into Puppet as top-scope variables), and, + failing that, will use a default value of 1.449. + EOS + ) do |args| + args = args.compact + args.delete(:undef) + args.delete(:undefined) + args.delete('') + raise Puppet::ParseError, 'pick(): must receive at least one non empty value' if args[0].to_s.empty? -EOS -) do |args| - args = args.compact - args.delete(:undef) - args.delete(:undefined) - args.delete("") - if args[0].to_s.empty? then - fail Puppet::ParseError, "pick(): must receive at least one non empty value" - else - return args[0] - end - end + return args[0] + end end diff --git a/lib/puppet/parser/functions/pick_default.rb b/lib/puppet/parser/functions/pick_default.rb index 36e33abfa..f1d546493 100644 --- a/lib/puppet/parser/functions/pick_default.rb +++ b/lib/puppet/parser/functions/pick_default.rb @@ -1,35 +1,43 @@ +# frozen_string_literal: true + +# +# pick_default.rb +# module Puppet::Parser::Functions - newfunction(:pick_default, :type => :rvalue, :doc => <<-EOS + newfunction(:pick_default, type: :rvalue, doc: <<-DOC + @summary + This function will return the first value in a list of values that is not undefined or an empty string. -This function is similar to a coalesce function in SQL in that it will return -the first value in a list of values that is not undefined or an empty string -(two things in Puppet that will return a boolean false value). If no value is -found, it will return the last argument. + @return + This function is similar to a coalesce function in SQL in that it will return + the first value in a list of values that is not undefined or an empty string + If no value is found, it will return the last argument. -Typically, this function is used to check for a value in the Puppet -Dashboard/Enterprise Console, and failover to a default value like the -following: + Typically, this function is used to check for a value in the Puppet + Dashboard/Enterprise Console, and failover to a default value like the + following: - $real_jenkins_version = pick_default($::jenkins_version, '1.449') + $real_jenkins_version = pick_default($::jenkins_version, '1.449') -The value of $real_jenkins_version will first look for a top-scope variable -called 'jenkins_version' (note that parameters set in the Puppet Dashboard/ -Enterprise Console are brought into Puppet as top-scope variables), and, -failing that, will use a default value of 1.449. + > *Note:* + The value of $real_jenkins_version will first look for a top-scope variable + called 'jenkins_version' (note that parameters set in the Puppet Dashboard/ + Enterprise Console are brought into Puppet as top-scope variables), and, + failing that, will use a default value of 1.449. -Note that, contrary to the pick() function, the pick_default does not fail if -all arguments are empty. This allows pick_default to use an empty value as -default. + Contrary to the pick() function, the pick_default does not fail if + all arguments are empty. This allows pick_default to use an empty value as + default. + DOC + ) do |args| + raise 'Must receive at least one argument.' if args.empty? -EOS -) do |args| - fail "Must receive at least one argument." if args.empty? - default = args.last - args = args[0..-2].compact - args.delete(:undef) - args.delete(:undefined) - args.delete("") - args << default - return args[0] - end + default = args.last + args = args[0..-2].compact + args.delete(:undef) + args.delete(:undefined) + args.delete('') + args << default + return args[0] + end end diff --git a/lib/puppet/parser/functions/prefix.rb b/lib/puppet/parser/functions/prefix.rb index ac1c58a55..4f8f0767a 100644 --- a/lib/puppet/parser/functions/prefix.rb +++ b/lib/puppet/parser/functions/prefix.rb @@ -1,49 +1,48 @@ +# frozen_string_literal: true + # # prefix.rb # - module Puppet::Parser::Functions - newfunction(:prefix, :type => :rvalue, :doc => <<-EOS -This function applies a prefix to all elements in an array or a hash. + newfunction(:prefix, type: :rvalue, doc: <<-DOC + @summary + This function applies a prefix to all elements in an array or a hash. -*Examples:* + @example **Usage** - prefix(['a','b','c'], 'p') + prefix(['a','b','c'], 'p') + Will return: ['pa','pb','pc'] -Will return: ['pa','pb','pc'] - EOS - ) do |arguments| + > *Note:* since Puppet 4.0.0 the general way to modify values is in array is by using the map + function in Puppet. This example does the same as the example above: + ['a', 'b', 'c'].map |$x| { "p${x}" } + @return [Hash] or [Array] The passed values now contains the passed prefix + DOC + ) do |arguments| # Technically we support two arguments but only first is mandatory ... - raise(Puppet::ParseError, "prefix(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 + raise(Puppet::ParseError, "prefix(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty? enumerable = arguments[0] - unless enumerable.is_a?(Array) or enumerable.is_a?(Hash) - raise Puppet::ParseError, "prefix(): expected first argument to be an Array or a Hash, got #{enumerable.inspect}" - end + raise Puppet::ParseError, "prefix(): expected first argument to be an Array or a Hash, got #{enumerable.inspect}" unless enumerable.is_a?(Array) || enumerable.is_a?(Hash) prefix = arguments[1] if arguments[1] - if prefix - unless prefix.is_a?(String) - raise Puppet::ParseError, "prefix(): expected second argument to be a String, got #{prefix.inspect}" - end - end - - if enumerable.is_a?(Array) - # Turn everything into string same as join would do ... - result = enumerable.collect do |i| - i = i.to_s - prefix ? prefix + i : i - end - else - result = Hash[enumerable.map do |k,v| - k = k.to_s - [ prefix ? prefix + k : k, v ] - end] - end + raise Puppet::ParseError, "prefix(): expected second argument to be a String, got #{prefix.inspect}" if prefix && !prefix.is_a?(String) + + result = if enumerable.is_a?(Array) + # Turn everything into string same as join would do ... + enumerable.map do |i| + i = i.to_s + prefix ? prefix + i : i + end + else + enumerable.to_h do |k, v| + k = k.to_s + [prefix ? prefix + k : k, v] + end + end return result end diff --git a/lib/puppet/parser/functions/private.rb b/lib/puppet/parser/functions/private.rb deleted file mode 100644 index 3b00ba12f..000000000 --- a/lib/puppet/parser/functions/private.rb +++ /dev/null @@ -1,17 +0,0 @@ -# -# private.rb -# - -module Puppet::Parser::Functions - newfunction(:private, :doc => <<-'EOS' - DEPRECATED: Sets the current class or definition as private. - Calling the class or definition from outside the current module will fail. - EOS - ) do |args| - warning("private() DEPRECATED: This function will cease to function on Puppet 4; please use assert_private() before upgrading to puppet 4 for backwards-compatibility, or migrate to the new parser's typing system.") - if !Puppet::Parser::Functions.autoloader.loaded?(:assert_private) - Puppet::Parser::Functions.autoloader.load(:assert_private) - end - function_assert_private([(args[0] unless args.size < 1)]) - end -end diff --git a/lib/puppet/parser/functions/pry.rb b/lib/puppet/parser/functions/pry.rb new file mode 100644 index 000000000..8bafe940f --- /dev/null +++ b/lib/puppet/parser/functions/pry.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +# +# pry.rb +# +module Puppet::Parser::Functions + newfunction(:pry, type: :statement, doc: <<-DOC + @summary + This function invokes a pry debugging session in the current scope object. + This is useful for debugging manifest code at specific points during a compilation. + + @return + debugging information + + @example **Usage** + + `pry()` + + DOC + ) do |arguments| + begin + require 'pry' + rescue LoadError + raise(Puppet::Error, "pry(): Requires the 'pry' rubygem to use, but it was not found") + end + # + ## Run `catalog` to see the contents currently compiling catalog + ## Run `cd catalog` and `ls` to see catalog methods and instance variables + ## Run `@resource_table` to see the current catalog resource table + # + if $stdout.isatty + binding.pry # rubocop:disable Lint/Debugger + else + Puppet.warning 'pry(): cowardly refusing to start the debugger on a daemonized server' + end + end +end diff --git a/lib/puppet/parser/functions/pw_hash.rb b/lib/puppet/parser/functions/pw_hash.rb index 41d42238d..7bd8fd62a 100644 --- a/lib/puppet/parser/functions/pw_hash.rb +++ b/lib/puppet/parser/functions/pw_hash.rb @@ -1,56 +1,89 @@ -Puppet::Parser::Functions::newfunction( - :pw_hash, - :type => :rvalue, - :arity => 3, - :doc => "Hashes a password using the crypt function. Provides a hash - usable on most POSIX systems. +# frozen_string_literal: true + +# Please note: This function is an implementation of a Ruby class and as such may not be entirely UTF8 compatible. +# To ensure compatibility please use this function with Ruby 2.4.0 or greater - https://bugs.ruby-lang.org/issues/10085. +# +Puppet::Parser::Functions.newfunction(:pw_hash, type: :rvalue, arity: 3, doc: <<-DOC + @summary + Hashes a password using the crypt function. Provides a hash usable + on most POSIX systems. The first argument to this function is the password to hash. If it is undef or an empty string, this function returns undef. - The second argument to this function is which type of hash to use. It + The second argument to this function is which hash algorithm to use. It will be converted into the appropriate crypt(3) hash specifier. Valid hash types are: - |Hash type |Specifier| - |---------------------|---------| - |MD5 |1 | - |SHA-256 |5 | - |SHA-512 (recommended)|6 | - - The third argument to this function is the salt to use. - - Note: this uses the Puppet Master's implementation of crypt(3). If your - environment contains several different operating systems, ensure that they - are compatible before using this function.") do |args| - raise ArgumentError, "pw_hash(): wrong number of arguments (#{args.size} for 3)" if args.size != 3 - raise ArgumentError, "pw_hash(): first argument must be a string" unless args[0].is_a? String or args[0].nil? - raise ArgumentError, "pw_hash(): second argument must be a string" unless args[1].is_a? String - hashes = { 'md5' => '1', - 'sha-256' => '5', - 'sha-512' => '6' } - hash_type = hashes[args[1].downcase] - raise ArgumentError, "pw_hash(): #{args[1]} is not a valid hash type" if hash_type.nil? - raise ArgumentError, "pw_hash(): third argument must be a string" unless args[2].is_a? String - raise ArgumentError, "pw_hash(): third argument must not be empty" if args[2].empty? - raise ArgumentError, "pw_hash(): characters in salt must be in the set [a-zA-Z0-9./]" unless args[2].match(/\A[a-zA-Z0-9.\/]+\z/) - - password = args[0] - return nil if password.nil? or password.empty? - - salt = "$#{hash_type}$#{args[2]}" - - # handle weak implementations of String#crypt - if 'test'.crypt('$1$1') != '$1$1$Bp8CU9Oujr9SSEw53WV6G.' - # JRuby < 1.7.17 - if RUBY_PLATFORM == 'java' - # puppetserver bundles Apache Commons Codec - org.apache.commons.codec.digest.Crypt.crypt(password.to_java_bytes, salt) - else - # MS Windows and other systems that don't support enhanced salts - raise Puppet::ParseError, 'system does not support enhanced salts' - end + |Hash type|Prefix|Note | + |---------|------|---------------------| + |MD5 |1 | | + |SHA-256 |5 | | + |SHA-512 |6 |Recommended | + |bcrypt |2b | | + |bcrypt-a |2a |bug compatible | + |bcrypt-x |2x |bug compatible | + |bcrypt-y |2y |historic alias for 2b| + + The third argument to this function is the salt to use. For bcrypt-type hashes, + the first two characters of the salt represent a strength parameter, with a value + between 4 and 31 inclusive. + + @return [String] + Provides a crypt hash usable on most POSIX systems. + + > *Note:*: this uses the Puppet Server's implementation of crypt(3). If your + environment contains several different operating systems, ensure that they + are compatible before using this function. +DOC +) do |args| + raise ArgumentError, "pw_hash(): wrong number of arguments (#{args.size} for 3)" if args.size != 3 + + args.map! do |arg| + if (defined? Puppet::Pops::Types::PSensitiveType::Sensitive) && (arg.is_a? Puppet::Pops::Types::PSensitiveType::Sensitive) + arg.unwrap else - password.crypt(salt) + arg end + end + + hashes = { + 'md5' => { prefix: '1' }, + 'sha-256' => { prefix: '5' }, + 'sha-512' => { prefix: '6' }, + 'bcrypt' => { prefix: '2b', salt: %r{^(0[4-9]|[12][0-9]|3[01])\$[./A-Za-z0-9]{22}} }, + 'bcrypt-a' => { prefix: '2a', salt: %r{^(0[4-9]|[12][0-9]|3[01])\$[./A-Za-z0-9]{22}} }, + 'bcrypt-x' => { prefix: '2x', salt: %r{^(0[4-9]|[12][0-9]|3[01])\$[./A-Za-z0-9]{22}} }, + 'bcrypt-y' => { prefix: '2y', salt: %r{^(0[4-9]|[12][0-9]|3[01])\$[./A-Za-z0-9]{22}} } + } + + raise ArgumentError, 'pw_hash(): first argument must be a string' unless args[0].is_a?(String) || args[0].nil? + raise ArgumentError, 'pw_hash(): second argument must be a string' unless args[1].is_a? String + + hash_type = hashes[args[1].downcase] + raise ArgumentError, "pw_hash(): #{args[1]} is not a valid hash type" if hash_type.nil? + raise ArgumentError, 'pw_hash(): third argument must be a string' unless args[2].is_a? String + raise ArgumentError, 'pw_hash(): third argument must not be empty' if args[2].empty? + + salt_doc = hash_type.include?(:salt) ? "match #{hash_type[:salt]}" : 'be in the set [a-zA-Z0-9./]' + salt_regex = hash_type.fetch(:salt, %r{\A[a-zA-Z0-9./]+\z}) + raise ArgumentError, "pw_hash(): characters in salt must #{salt_doc}" unless salt_regex.match?(args[2]) + + password = args[0] + return nil if password.nil? || password.empty? + + salt = "$#{hash_type[:prefix]}$#{args[2]}" + + # handle weak implementations of String#crypt + # dup the string to get rid of frozen status for testing + if RUBY_PLATFORM == 'java' && !args[1].downcase.start_with?('bcrypt') + # puppetserver bundles Apache Commons Codec + org.apache.commons.codec.digest.Crypt.crypt(password.to_java_bytes, salt) + elsif (+'test').crypt('$1$1') == '$1$1$Bp8CU9Oujr9SSEw53WV6G.' + password.crypt(salt) + else + # JRuby < 1.7.17 + # MS Windows and other systems that don't support enhanced salts + raise Puppet::ParseError, 'system does not support enhanced salts' + end end diff --git a/lib/puppet/parser/functions/range.rb b/lib/puppet/parser/functions/range.rb index 2fc211329..13f93facd 100644 --- a/lib/puppet/parser/functions/range.rb +++ b/lib/puppet/parser/functions/range.rb @@ -1,71 +1,80 @@ +# frozen_string_literal: true + # # range.rb # - # TODO(Krzysztof Wilczynski): We probably need to approach numeric values differently ... - module Puppet::Parser::Functions - newfunction(:range, :type => :rvalue, :doc => <<-EOS -When given range in the form of (start, stop) it will extrapolate a range as -an array. - -*Examples:* + newfunction(:range, type: :rvalue, doc: <<-DOC + @summary + When given range in the form of (start, stop) it will extrapolate a range as + an array. - range("0", "9") + @return + the range is extrapolated as an array -Will return: [0,1,2,3,4,5,6,7,8,9] + @example **Usage** + range("0", "9") + Will return: [0,1,2,3,4,5,6,7,8,9] - range("00", "09") + range("00", "09") + Will return: [0,1,2,3,4,5,6,7,8,9] + (Zero padded strings are converted to integers automatically) -Will return: [0,1,2,3,4,5,6,7,8,9] (Zero padded strings are converted to -integers automatically) + range("a", "c") + Will return: ["a","b","c"] - range("a", "c") + range("host01", "host10") + Will return: ["host01", "host02", ..., "host09", "host10"] -Will return: ["a","b","c"] + range("0", "9", "2") + Will return: [0,2,4,6,8] - range("host01", "host10") + NB Be explicit in including trailing zeros. Otherwise the underlying ruby function will fail. -Will return: ["host01", "host02", ..., "host09", "host10"] + > *Note:* + Passing a third argument will cause the generated range to step by that + interval, e.g. -Passing a third argument will cause the generated range to step by that -interval, e.g. + The Puppet Language support Integer and Float ranges by using the type system. Those are suitable for + iterating a given number of times. - range("0", "9", "2") + @see + the step() function in Puppet for skipping values. -Will return: [0,2,4,6,8] - EOS + Integer[0, 9].each |$x| { notice($x) } # notices 0, 1, 2, ... 9 + DOC ) do |arguments| - - raise(Puppet::ParseError, 'range(): Wrong number of ' + - 'arguments given (0 for 1)') if arguments.size == 0 + raise(Puppet::ParseError, 'range(): Wrong number of arguments given (0 for 1)') if arguments.empty? if arguments.size > 1 start = arguments[0] stop = arguments[1] step = arguments[2].nil? ? 1 : arguments[2].to_i.abs + raise(ArgumentError, 'range(): 3rd arg (step size) must be a non zero integer (e.g. 1 or -1)') if step.zero? + type = '..' # Use the simplest type of Range available in Ruby else # arguments.size == 1 value = arguments[0] - if m = value.match(/^(\w+)(\.\.\.?|\-)(\w+)$/) + m = value.match(%r{^(\w+)(\.\.\.?|-)(\w+)$}) + if m start = m[1] stop = m[3] type = m[2] step = 1 - elsif value.match(/^.+$/) - raise(Puppet::ParseError, "range(): Unable to compute range " + - "from the value: #{value}") + elsif %r{^.+$}.match?(value) + raise(Puppet::ParseError, "range(): Unable to compute range from the value: #{value}") else raise(Puppet::ParseError, "range(): Unknown range format: #{value}") end end # If we were given an integer, ensure we work with one - if start.to_s.match(/^\d+$/) + if %r{^\d+$}.match?(start.to_s) start = start.to_i stop = stop.to_i else @@ -74,11 +83,11 @@ module Puppet::Parser::Functions end range = case type - when /^(\.\.|\-)$/ then (start .. stop) - when '...' then (start ... stop) # Exclusive of last element - end + when %r{^(..|-)$} then (start..stop) + when '...' then (start...stop) # Exclusive of last element + end - result = range.step(step).to_a + result = range.step(step).first(1_000_000).to_a return result end diff --git a/lib/puppet/parser/functions/regexpescape.rb b/lib/puppet/parser/functions/regexpescape.rb new file mode 100644 index 000000000..a67138a7b --- /dev/null +++ b/lib/puppet/parser/functions/regexpescape.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +# +# regexpescape.rb +# +module Puppet::Parser::Functions + newfunction(:regexpescape, type: :rvalue, doc: <<-DOC + @summary + Regexp escape a string or array of strings. + Requires either a single string or an array as an input. + @return [String] + A string of characters with metacharacters converted to their escaped form. + DOC + ) do |arguments| + raise(Puppet::ParseError, "regexpescape(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty? + + value = arguments[0] + + raise(Puppet::ParseError, 'regexpescape(): Requires either array or string to work with') unless value.is_a?(Array) || value.is_a?(String) + + result = if value.is_a?(Array) + # Numbers in Puppet are often string-encoded which is troublesome ... + value.map { |i| i.is_a?(String) ? Regexp.escape(i) : i } + else + Regexp.escape(value) + end + + return result + end +end + +# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/reject.rb b/lib/puppet/parser/functions/reject.rb index 1953ffcf1..ecda3efed 100644 --- a/lib/puppet/parser/functions/reject.rb +++ b/lib/puppet/parser/functions/reject.rb @@ -1,30 +1,37 @@ +# frozen_string_literal: true + # # reject.rb # - module Puppet::Parser::Functions - newfunction(:reject, :type => :rvalue, :doc => <<-EOS) do |args| -This function searches through an array and rejects all elements that match -the provided regular expression. + newfunction(:reject, type: :rvalue, doc: <<-DOC) do |args| + @summary + This function searches through an array and rejects all elements that match + the provided regular expression. + + @return + an array containing all the elements which doesn'' match the provided regular expression -*Examples:* + @example **Usage** - reject(['aaa','bbb','ccc','aaaddd'], 'aaa') + reject(['aaa','bbb','ccc','aaaddd'], 'aaa') -Would return: + Would return: ['bbb','ccc'] - ['bbb','ccc'] -EOS + > *Note:* + Since Puppet 4.0.0 the same is in general done with the filter function. Here is the equivalence of the reject() function: + ['aaa','bbb','ccc','aaaddd'].filter |$x| { $x !~ /aaa/ } + DOC - if (args.size != 2) + if args.size != 2 raise Puppet::ParseError, - "reject(): Wrong number of arguments given #{args.size} for 2" + "reject(): Wrong number of arguments given #{args.size} for 2" end ary = args[0] pattern = Regexp.new(args[1]) - ary.reject { |e| e =~ pattern } + ary.grep_v(pattern) end end diff --git a/lib/puppet/parser/functions/reverse.rb b/lib/puppet/parser/functions/reverse.rb index 7f1018f67..0cd62f246 100644 --- a/lib/puppet/parser/functions/reverse.rb +++ b/lib/puppet/parser/functions/reverse.rb @@ -1,22 +1,24 @@ +# frozen_string_literal: true + # # reverse.rb # - module Puppet::Parser::Functions - newfunction(:reverse, :type => :rvalue, :doc => <<-EOS -Reverses the order of a string or array. - EOS - ) do |arguments| + newfunction(:reverse, type: :rvalue, doc: <<-DOC + @summary + Reverses the order of a string or array. - raise(Puppet::ParseError, "reverse(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 + @return + reversed string or array + + > *Note:* that the same can be done with the reverse_each() function in Puppet. + DOC + ) do |arguments| + raise(Puppet::ParseError, "reverse(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty? value = arguments[0] - unless value.is_a?(Array) || value.is_a?(String) - raise(Puppet::ParseError, 'reverse(): Requires either ' + - 'array or string to work with') - end + raise(Puppet::ParseError, 'reverse(): Requires either array or string to work with') unless value.is_a?(Array) || value.is_a?(String) result = value.reverse diff --git a/lib/puppet/parser/functions/rstrip.rb b/lib/puppet/parser/functions/rstrip.rb deleted file mode 100644 index 0cf8d222c..000000000 --- a/lib/puppet/parser/functions/rstrip.rb +++ /dev/null @@ -1,31 +0,0 @@ -# -# rstrip.rb -# - -module Puppet::Parser::Functions - newfunction(:rstrip, :type => :rvalue, :doc => <<-EOS -Strips leading spaces to the right of the string. - EOS - ) do |arguments| - - raise(Puppet::ParseError, "rstrip(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 - - value = arguments[0] - - unless value.is_a?(Array) || value.is_a?(String) - raise(Puppet::ParseError, 'rstrip(): Requires either ' + - 'array or string to work with') - end - - if value.is_a?(Array) - result = value.collect { |i| i.is_a?(String) ? i.rstrip : i } - else - result = value.rstrip - end - - return result - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/shell_join.rb b/lib/puppet/parser/functions/shell_join.rb new file mode 100644 index 000000000..93f026e1f --- /dev/null +++ b/lib/puppet/parser/functions/shell_join.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require 'shellwords' +# +# shell_join.rb +# +module Puppet::Parser::Functions + newfunction(:shell_join, type: :rvalue, doc: <<-DOC + @summary + Builds a command line string from the given array of strings. + Each array item is escaped for Bourne shell. All items are then joined together, with a single space in between. + This function behaves the same as ruby's Shellwords.shelljoin() function + + @return + a command line string + DOC + ) do |arguments| + raise(Puppet::ParseError, "shell_join(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.size != 1 + + array = arguments[0] + + raise Puppet::ParseError, "First argument is not an Array: #{array.inspect}" unless array.is_a?(Array) + + # explicit conversion to string is required for ruby 1.9 + array = array.map(&:to_s) + result = Shellwords.shelljoin(array) + + return result + end +end + +# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/shell_split.rb b/lib/puppet/parser/functions/shell_split.rb new file mode 100644 index 000000000..1fa3c8ed3 --- /dev/null +++ b/lib/puppet/parser/functions/shell_split.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require 'shellwords' +# +# shell_split.rb +# +module Puppet::Parser::Functions + newfunction(:shell_split, type: :rvalue, doc: <<-DOC + @summary + Splits a string into an array of tokens in the same way the Bourne shell does. + + @return + array of tokens + + This function behaves the same as ruby's Shellwords.shellsplit() function + DOC + ) do |arguments| + raise(Puppet::ParseError, "shell_split(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.size != 1 + + string = arguments[0].to_s + + result = Shellwords.shellsplit(string) + + return result + end +end + +# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/shuffle.rb b/lib/puppet/parser/functions/shuffle.rb index 30c663dbe..c2c420ebf 100644 --- a/lib/puppet/parser/functions/shuffle.rb +++ b/lib/puppet/parser/functions/shuffle.rb @@ -1,32 +1,32 @@ +# frozen_string_literal: true + # # shuffle.rb # - module Puppet::Parser::Functions - newfunction(:shuffle, :type => :rvalue, :doc => <<-EOS -Randomizes the order of a string or array elements. - EOS - ) do |arguments| + newfunction(:shuffle, type: :rvalue, doc: <<-DOC + @summary + Randomizes the order of a string or array elements. - raise(Puppet::ParseError, "shuffle(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 + @return + randomized string or array + DOC + ) do |arguments| + raise(Puppet::ParseError, "shuffle(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty? value = arguments[0] - unless value.is_a?(Array) || value.is_a?(String) - raise(Puppet::ParseError, 'shuffle(): Requires either ' + - 'array or string to work with') - end + raise(Puppet::ParseError, 'shuffle(): Requires either array or string to work with') unless value.is_a?(Array) || value.is_a?(String) result = value.clone - string = value.is_a?(String) ? true : false + string = value.is_a?(String) # Check whether it makes sense to shuffle ... return result if result.size <= 1 # We turn any string value into an array to be able to shuffle ... - result = string ? result.split('') : result + result = string ? result.chars : result elements = result.size diff --git a/lib/puppet/parser/functions/size.rb b/lib/puppet/parser/functions/size.rb deleted file mode 100644 index 0d6cc9613..000000000 --- a/lib/puppet/parser/functions/size.rb +++ /dev/null @@ -1,46 +0,0 @@ -# -# size.rb -# - -module Puppet::Parser::Functions - newfunction(:size, :type => :rvalue, :doc => <<-EOS -Returns the number of elements in a string, an array or a hash - EOS - ) do |arguments| - - raise(Puppet::ParseError, "size(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 - - item = arguments[0] - - if item.is_a?(String) - - begin - # - # Check whether your item is a numeric value or not ... - # This will take care about positive and/or negative numbers - # for both integer and floating-point values ... - # - # Please note that Puppet has no notion of hexadecimal - # nor octal numbers for its DSL at this point in time ... - # - Float(item) - - raise(Puppet::ParseError, 'size(): Requires either ' + - 'string, array or hash to work with') - - rescue ArgumentError - result = item.size - end - - elsif item.is_a?(Array) || item.is_a?(Hash) - result = item.size - else - raise(Puppet::ParseError, 'size(): Unknown type given') - end - - return result - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/sort.rb b/lib/puppet/parser/functions/sort.rb deleted file mode 100644 index cefbe5463..000000000 --- a/lib/puppet/parser/functions/sort.rb +++ /dev/null @@ -1,27 +0,0 @@ -# -# sort.rb -# - -module Puppet::Parser::Functions - newfunction(:sort, :type => :rvalue, :doc => <<-EOS -Sorts strings and arrays lexically. - EOS - ) do |arguments| - - if (arguments.size != 1) then - raise(Puppet::ParseError, "sort(): Wrong number of arguments "+ - "given #{arguments.size} for 1") - end - - value = arguments[0] - - if value.is_a?(Array) then - value.sort - elsif value.is_a?(String) then - value.split("").sort.join("") - end - - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/squeeze.rb b/lib/puppet/parser/functions/squeeze.rb index 81fadfdb2..ee527c4d2 100644 --- a/lib/puppet/parser/functions/squeeze.rb +++ b/lib/puppet/parser/functions/squeeze.rb @@ -1,35 +1,33 @@ +# frozen_string_literal: true + # # squeeze.rb # - module Puppet::Parser::Functions - newfunction(:squeeze, :type => :rvalue, :doc => <<-EOS -Returns a new string where runs of the same character that occur in this set are replaced by a single character. - EOS - ) do |arguments| + newfunction(:squeeze, type: :rvalue, doc: <<-DOC + @summary + Returns a new string where runs of the same character that occur in this set are replaced by a single character. - if ((arguments.size != 2) and (arguments.size != 1)) then - raise(Puppet::ParseError, "squeeze(): Wrong number of arguments "+ - "given #{arguments.size} for 2 or 1") - end + @return + a new string where runs of the same character that occur in this set are replaced by a single character. + DOC + ) do |arguments| + raise(Puppet::ParseError, "squeeze(): Wrong number of arguments given #{arguments.size} for 2 or 1") if (arguments.size != 2) && (arguments.size != 1) item = arguments[0] squeezeval = arguments[1] - if item.is_a?(Array) then - if squeezeval then - item.collect { |i| i.squeeze(squeezeval) } + if item.is_a?(Array) + if squeezeval + item.map { |i| i.squeeze(squeezeval) } else - item.collect { |i| i.squeeze } + item.map(&:squeeze) end + elsif squeezeval + item.squeeze(squeezeval) else - if squeezeval then - item.squeeze(squeezeval) - else - item.squeeze - end + item.squeeze end - end end diff --git a/lib/puppet/parser/functions/str2bool.rb b/lib/puppet/parser/functions/str2bool.rb index 8def131e3..f2cb42ba6 100644 --- a/lib/puppet/parser/functions/str2bool.rb +++ b/lib/puppet/parser/functions/str2bool.rb @@ -1,43 +1,43 @@ +# frozen_string_literal: true + # # str2bool.rb # - module Puppet::Parser::Functions - newfunction(:str2bool, :type => :rvalue, :doc => <<-EOS -This converts a string to a boolean. This attempt to convert strings that -contain things like: Y,y, 1, T,t, TRUE,true to 'true' and strings that contain things -like: 0, F,f, N,n, false, FALSE, no to 'false'. - EOS - ) do |arguments| + newfunction(:str2bool, type: :rvalue, doc: <<-DOC + @summary + This converts a string to a boolean. - raise(Puppet::ParseError, "str2bool(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 + @return + This attempt to convert to boolean strings that contain things like: Y,y, 1, T,t, TRUE,true to 'true' and strings that contain things + like: 0, F,f, N,n, false, FALSE, no to 'false'. + + > *Note:* that since Puppet 5.0.0 the Boolean data type can convert strings to a Boolean value. + See the function new() in Puppet for details what the Boolean data type supports. + DOC + ) do |arguments| + raise(Puppet::ParseError, "str2bool(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty? string = arguments[0] # If string is already Boolean, return it - if !!string == string - return string - end + return string if !!string == string # rubocop:disable Style/DoubleNegation : No viable alternative - unless string.is_a?(String) - raise(Puppet::ParseError, 'str2bool(): Requires either ' + - 'string to work with') - end + raise(Puppet::ParseError, 'str2bool(): Requires string to work with') unless string.is_a?(String) # We consider all the yes, no, y, n and so on too ... result = case string - # - # This is how undef looks like in Puppet ... - # We yield false in this case. - # - when /^$/, '' then false # Empty string will be false ... - when /^(1|t|y|true|yes)$/i then true - when /^(0|f|n|false|no)$/i then false - when /^(undef|undefined)$/ then false # This is not likely to happen ... - else - raise(Puppet::ParseError, 'str2bool(): Unknown type of boolean given') - end + # + # This is how undef looks like in Puppet ... + # We yield false in this case. + # + when %r{^$}, '' then false # Empty string will be false ... + when %r{^(1|t|y|true|yes)$}i then true + when %r{^(0|f|n|false|no)$}i then false + when %r{^(undef|undefined)$} then false # This is not likely to happen ... + else + raise(Puppet::ParseError, 'str2bool(): Unknown type of boolean given') + end return result end diff --git a/lib/puppet/parser/functions/str2saltedpbkdf2.rb b/lib/puppet/parser/functions/str2saltedpbkdf2.rb new file mode 100644 index 000000000..5640832dd --- /dev/null +++ b/lib/puppet/parser/functions/str2saltedpbkdf2.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true + +# str2saltedpbkdf2.rb +# Please note: This function is an implementation of a Ruby class and as such may not be entirely UTF8 compatible. To ensure compatibility please use this function with Ruby 2.4.0 or greater - https://bugs.ruby-lang.org/issues/10085. +# +module Puppet::Parser::Functions + newfunction(:str2saltedpbkdf2, type: :rvalue, doc: <<-DOC + @summary Convert a string into a salted SHA512 PBKDF2 password hash like requred for OS X / macOS 10.8+ + + Convert a string into a salted SHA512 PBKDF2 password hash like requred for OS X / macOS 10.8+. + Note, however, that Apple changes what's required periodically and this may not work for the latest + version of macOS. If that is the case you should get a helpful error message when Puppet tries to set + the pasword using the parameters you provide to the user resource. + + @example Plain text password and salt + $pw_info = str2saltedpbkdf2('Pa55w0rd', 'Use a s@lt h3r3 th@t is 32 byt3s', 50000) + user { 'jdoe': + ensure => present, + iterations => $pw_info['interations'], + password => $pw_info['password_hex'], + salt => $pw_info['salt_hex'], + } + + @example Sensitive password and salt + $pw = Sensitive.new('Pa55w0rd') + $salt = Sensitive.new('Use a s@lt h3r3 th@t is 32 byt3s') + $pw_info = Sensitive.new(str2saltedpbkdf2($pw, $salt, 50000)) + user { 'jdoe': + ensure => present, + iterations => unwrap($pw_info)['interations'], + password => unwrap($pw_info)['password_hex'], + salt => unwrap($pw_info)['salt_hex'], + } + + @return [Hash] + Provides a hash containing the hex version of the password, the hex version of the salt, and iterations. + DOC + ) do |args| + require 'openssl' + + raise ArgumentError, "str2saltedpbkdf2(): wrong number of arguments (#{args.size} for 3)" if args.size != 3 + + args.map! do |arg| + if (defined? Puppet::Pops::Types::PSensitiveType::Sensitive) && (arg.is_a? Puppet::Pops::Types::PSensitiveType::Sensitive) + arg.unwrap + else + arg + end + end + + raise ArgumentError, 'str2saltedpbkdf2(): first argument must be a string' unless args[0].is_a?(String) + raise ArgumentError, 'str2saltedpbkdf2(): second argument must be a string' unless args[1].is_a?(String) + raise ArgumentError, 'str2saltedpbkdf2(): second argument must be at least 8 bytes long' unless args[1].bytesize >= 8 + raise ArgumentError, 'str2saltedpbkdf2(): third argument must be an integer' unless args[2].is_a?(Integer) + raise ArgumentError, 'str2saltedpbkdf2(): third argument must be between 40,000 and 70,000' unless args[2] > 40_000 && args[2] < 70_000 + + password = args[0] + salt = args[1] + iterations = args[2] + keylen = 128 + digest = OpenSSL::Digest.new('SHA512') + hash = OpenSSL::PKCS5.pbkdf2_hmac(password, salt, iterations, keylen, digest) + + { + 'password_hex' => hash.unpack1('H*'), + 'salt_hex' => salt.unpack1('H*'), + 'iterations' => iterations + } + end +end diff --git a/lib/puppet/parser/functions/str2saltedsha512.rb b/lib/puppet/parser/functions/str2saltedsha512.rb index 7fe7b0128..4d4800e8a 100644 --- a/lib/puppet/parser/functions/str2saltedsha512.rb +++ b/lib/puppet/parser/functions/str2saltedsha512.rb @@ -1,31 +1,35 @@ +# frozen_string_literal: true + # -# str2saltedsha512.rb +# str2saltedsha512.rb +# Please note: This function is an implementation of a Ruby class and as such may not be entirely UTF8 compatible. To ensure compatibility please use this function with Ruby 2.4.0 or greater - https://bugs.ruby-lang.org/issues/10085. # - module Puppet::Parser::Functions - newfunction(:str2saltedsha512, :type => :rvalue, :doc => <<-EOS -This converts a string to a salted-SHA512 password hash (which is used for -OS X versions >= 10.7). Given any simple string, you will get a hex version -of a salted-SHA512 password hash that can be inserted into your Puppet -manifests as a valid password attribute. - EOS + newfunction(:str2saltedsha512, type: :rvalue, doc: <<-DOC + @summary + This converts a string to a salted-SHA512 password hash (which is used for + OS X versions >= 10.7). + + @return + converted string as a hex version of a salted-SHA512 password hash + + Given any simple string, you will get a hex version + of a salted-SHA512 password hash that can be inserted into your Puppet + manifests as a valid password attribute. + DOC ) do |arguments| require 'digest/sha2' - raise(Puppet::ParseError, "str2saltedsha512(): Wrong number of arguments " + - "passed (#{arguments.size} but we require 1)") if arguments.size != 1 + raise(Puppet::ParseError, "str2saltedsha512(): Wrong number of arguments passed (#{arguments.size} but we require 1)") if arguments.size != 1 password = arguments[0] - unless password.is_a?(String) - raise(Puppet::ParseError, 'str2saltedsha512(): Requires a ' + - "String argument, you passed: #{password.class}") - end + raise(Puppet::ParseError, "str2saltedsha512(): Requires a String argument, you passed: #{password.class}") unless password.is_a?(String) - seedint = rand(2**31 - 1) - seedstring = Array(seedint).pack("L") + seedint = rand((2**31) - 1) + seedstring = Array(seedint).pack('L') saltedpass = Digest::SHA512.digest(seedstring + password) - (seedstring + saltedpass).unpack('H*')[0] + (seedstring + saltedpass).unpack1('H*') end end diff --git a/lib/puppet/parser/functions/strftime.rb b/lib/puppet/parser/functions/strftime.rb deleted file mode 100644 index 0b52adecd..000000000 --- a/lib/puppet/parser/functions/strftime.rb +++ /dev/null @@ -1,107 +0,0 @@ -# -# strftime.rb -# - -module Puppet::Parser::Functions - newfunction(:strftime, :type => :rvalue, :doc => <<-EOS -This function returns formatted time. - -*Examples:* - -To return the time since epoch: - - strftime("%s") - -To return the date: - - strftime("%Y-%m-%d") - -*Format meaning:* - - %a - The abbreviated weekday name (``Sun'') - %A - The full weekday name (``Sunday'') - %b - The abbreviated month name (``Jan'') - %B - The full month name (``January'') - %c - The preferred local date and time representation - %C - Century (20 in 2009) - %d - Day of the month (01..31) - %D - Date (%m/%d/%y) - %e - Day of the month, blank-padded ( 1..31) - %F - Equivalent to %Y-%m-%d (the ISO 8601 date format) - %h - Equivalent to %b - %H - Hour of the day, 24-hour clock (00..23) - %I - Hour of the day, 12-hour clock (01..12) - %j - Day of the year (001..366) - %k - hour, 24-hour clock, blank-padded ( 0..23) - %l - hour, 12-hour clock, blank-padded ( 0..12) - %L - Millisecond of the second (000..999) - %m - Month of the year (01..12) - %M - Minute of the hour (00..59) - %n - Newline (\n) - %N - Fractional seconds digits, default is 9 digits (nanosecond) - %3N millisecond (3 digits) - %6N microsecond (6 digits) - %9N nanosecond (9 digits) - %p - Meridian indicator (``AM'' or ``PM'') - %P - Meridian indicator (``am'' or ``pm'') - %r - time, 12-hour (same as %I:%M:%S %p) - %R - time, 24-hour (%H:%M) - %s - Number of seconds since 1970-01-01 00:00:00 UTC. - %S - Second of the minute (00..60) - %t - Tab character (\t) - %T - time, 24-hour (%H:%M:%S) - %u - Day of the week as a decimal, Monday being 1. (1..7) - %U - Week number of the current year, - starting with the first Sunday as the first - day of the first week (00..53) - %v - VMS date (%e-%b-%Y) - %V - Week number of year according to ISO 8601 (01..53) - %W - Week number of the current year, - starting with the first Monday as the first - day of the first week (00..53) - %w - Day of the week (Sunday is 0, 0..6) - %x - Preferred representation for the date alone, no time - %X - Preferred representation for the time alone, no date - %y - Year without a century (00..99) - %Y - Year with century - %z - Time zone as hour offset from UTC (e.g. +0900) - %Z - Time zone name - %% - Literal ``%'' character - EOS - ) do |arguments| - - # Technically we support two arguments but only first is mandatory ... - raise(Puppet::ParseError, "strftime(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 - - format = arguments[0] - - raise(Puppet::ParseError, 'strftime(): You must provide ' + - 'format for evaluation') if format.empty? - - # The Time Zone argument is optional ... - time_zone = arguments[1] if arguments[1] - - time = Time.new - - # There is probably a better way to handle Time Zone ... - if time_zone and not time_zone.empty? - original_zone = ENV['TZ'] - - local_time = time.clone - local_time = local_time.utc - - ENV['TZ'] = time_zone - - time = local_time.localtime - - ENV['TZ'] = original_zone - end - - result = time.strftime(format) - - return result - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/strip.rb b/lib/puppet/parser/functions/strip.rb deleted file mode 100644 index 3fac47d53..000000000 --- a/lib/puppet/parser/functions/strip.rb +++ /dev/null @@ -1,38 +0,0 @@ -# -# strip.rb -# - -module Puppet::Parser::Functions - newfunction(:strip, :type => :rvalue, :doc => <<-EOS -This function removes leading and trailing whitespace from a string or from -every string inside an array. - -*Examples:* - - strip(" aaa ") - -Would result in: "aaa" - EOS - ) do |arguments| - - raise(Puppet::ParseError, "strip(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 - - value = arguments[0] - - unless value.is_a?(Array) || value.is_a?(String) - raise(Puppet::ParseError, 'strip(): Requires either ' + - 'array or string to work with') - end - - if value.is_a?(Array) - result = value.collect { |i| i.is_a?(String) ? i.strip : i } - else - result = value.strip - end - - return result - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/suffix.rb b/lib/puppet/parser/functions/suffix.rb index f7792d6f7..34db43833 100644 --- a/lib/puppet/parser/functions/suffix.rb +++ b/lib/puppet/parser/functions/suffix.rb @@ -1,42 +1,52 @@ +# frozen_string_literal: true + # # suffix.rb # - module Puppet::Parser::Functions - newfunction(:suffix, :type => :rvalue, :doc => <<-EOS -This function applies a suffix to all elements in an array. + newfunction(:suffix, type: :rvalue, doc: <<-DOC + @summary + This function applies a suffix to all elements in an array, or to the keys + in a hash. -*Examples:* + @return + Array or Hash with updated elements containing the passed suffix - suffix(['a','b','c'], 'p') + @example **Usage** -Will return: ['ap','bp','cp'] - EOS - ) do |arguments| + suffix(['a','b','c'], 'p') + Will return: ['ap','bp','cp'] + > *Note:* that since Puppet 4.0.0 the general way to modify values is in array is by using the map + function in Puppet. This example does the same as the example above: + + ```['a', 'b', 'c'].map |$x| { "${x}p" }``` + + DOC + ) do |arguments| # Technically we support two arguments but only first is mandatory ... - raise(Puppet::ParseError, "suffix(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 + raise(Puppet::ParseError, "suffix(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty? - array = arguments[0] + enumerable = arguments[0] - unless array.is_a?(Array) - raise Puppet::ParseError, "suffix(): expected first argument to be an Array, got #{array.inspect}" - end + raise Puppet::ParseError, "suffix(): expected first argument to be an Array or a Hash, got #{enumerable.inspect}" unless enumerable.is_a?(Array) || enumerable.is_a?(Hash) suffix = arguments[1] if arguments[1] - if suffix - unless suffix.is_a? String - raise Puppet::ParseError, "suffix(): expected second argument to be a String, got #{suffix.inspect}" - end - end - - # Turn everything into string same as join would do ... - result = array.collect do |i| - i = i.to_s - suffix ? i + suffix : i - end + raise Puppet::ParseError, "suffix(): expected second argument to be a String, got #{suffix.inspect}" if suffix && !(suffix.is_a? String) + + result = if enumerable.is_a?(Array) + # Turn everything into string same as join would do ... + enumerable.map do |i| + i = i.to_s + suffix ? i + suffix : i + end + else + enumerable.to_h do |k, v| + k = k.to_s + [suffix ? k + suffix : k, v] + end + end return result end diff --git a/lib/puppet/parser/functions/swapcase.rb b/lib/puppet/parser/functions/swapcase.rb index eb7fe137d..a640f0272 100644 --- a/lib/puppet/parser/functions/swapcase.rb +++ b/lib/puppet/parser/functions/swapcase.rb @@ -1,35 +1,35 @@ +# frozen_string_literal: true + # # swapcase.rb +# Please note: This function is an implementation of a Ruby class and as such may not be entirely UTF8 compatible. To ensure compatibility please use this function with Ruby 2.4.0 or greater - https://bugs.ruby-lang.org/issues/10085. # - module Puppet::Parser::Functions - newfunction(:swapcase, :type => :rvalue, :doc => <<-EOS -This function will swap the existing case of a string. + newfunction(:swapcase, type: :rvalue, doc: <<-DOC + @summary + This function will swap the existing case of a string. -*Examples:* + @return + string with uppercase alphabetic characters converted to lowercase and lowercase characters converted to uppercase - swapcase("aBcD") + @example **Usage** -Would result in: "AbCd" - EOS + swapcase("aBcD") + Would result in: "AbCd" + DOC ) do |arguments| - - raise(Puppet::ParseError, "swapcase(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 + raise(Puppet::ParseError, "swapcase(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty? value = arguments[0] - unless value.is_a?(Array) || value.is_a?(String) - raise(Puppet::ParseError, 'swapcase(): Requires either ' + - 'array or string to work with') - end - - if value.is_a?(Array) - # Numbers in Puppet are often string-encoded which is troublesome ... - result = value.collect { |i| i.is_a?(String) ? i.swapcase : i } - else - result = value.swapcase - end + raise(Puppet::ParseError, 'swapcase(): Requires either array or string to work with') unless value.is_a?(Array) || value.is_a?(String) + + result = if value.is_a?(Array) + # Numbers in Puppet are often string-encoded which is troublesome ... + value.map { |i| i.is_a?(String) ? i.swapcase : i } + else + value.swapcase + end return result end diff --git a/lib/puppet/parser/functions/time.rb b/lib/puppet/parser/functions/time.rb deleted file mode 100644 index c5747474f..000000000 --- a/lib/puppet/parser/functions/time.rb +++ /dev/null @@ -1,50 +0,0 @@ -# -# time.rb -# - -module Puppet::Parser::Functions - newfunction(:time, :type => :rvalue, :doc => <<-EOS -This function will return the current time since epoch as an integer. - -*Examples:* - - time() - -Will return something like: 1311972653 - EOS - ) do |arguments| - - # The Time Zone argument is optional ... - time_zone = arguments[0] if arguments[0] - - if (arguments.size != 0) and (arguments.size != 1) then - raise(Puppet::ParseError, "time(): Wrong number of arguments "+ - "given #{arguments.size} for 0 or 1") - end - - time = Time.new - - # There is probably a better way to handle Time Zone ... - if time_zone and not time_zone.empty? - original_zone = ENV['TZ'] - - local_time = time.clone - local_time = local_time.utc - - ENV['TZ'] = time_zone - - result = local_time.localtime.strftime('%s') - - ENV['TZ'] = original_zone - else - result = time.localtime.strftime('%s') - end - - # Calling Time#to_i on a receiver changes it. Trust me I am the Doctor. - result = result.to_i - - return result - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/to_bytes.rb b/lib/puppet/parser/functions/to_bytes.rb index df490ea8c..9b903db77 100644 --- a/lib/puppet/parser/functions/to_bytes.rb +++ b/lib/puppet/parser/functions/to_bytes.rb @@ -1,30 +1,38 @@ +# frozen_string_literal: true + +# +# to_bytes.rb +# module Puppet::Parser::Functions - newfunction(:to_bytes, :type => :rvalue, :doc => <<-EOS - Converts the argument into bytes, for example 4 kB becomes 4096. + newfunction(:to_bytes, type: :rvalue, doc: <<-DOC + @summary + Converts the argument into bytes, for example 4 kB becomes 4096. + + @return + converted value into bytes + Takes a single string value as an argument. These conversions reflect a layperson's understanding of 1 MB = 1024 KB, when in fact 1 MB = 1000 KB, and 1 MiB = 1024 KiB. - EOS + DOC ) do |arguments| - - raise(Puppet::ParseError, "to_bytes(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size != 1 + raise(Puppet::ParseError, "to_bytes(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.size != 1 arg = arguments[0] return arg if arg.is_a? Numeric - value,prefix = */([0-9.e+-]*)\s*([^bB]?)/.match(arg)[1,2] + value, prefix = *%r{([0-9.e+-]*)\s*([^bB]?)}.match(arg)[1, 2] value = value.to_f case prefix when '' then return value.to_i - when 'k' then return (value*(1<<10)).to_i - when 'M' then return (value*(1<<20)).to_i - when 'G' then return (value*(1<<30)).to_i - when 'T' then return (value*(1<<40)).to_i - when 'P' then return (value*(1<<50)).to_i - when 'E' then return (value*(1<<60)).to_i + when 'k' then return (value * (1 << 10)).to_i + when 'M' then return (value * (1 << 20)).to_i + when 'G' then return (value * (1 << 30)).to_i + when 'T' then return (value * (1 << 40)).to_i + when 'P' then return (value * (1 << 50)).to_i + when 'E' then return (value * (1 << 60)).to_i else raise Puppet::ParseError, "to_bytes(): Unknown prefix #{prefix}" end end diff --git a/lib/puppet/parser/functions/try_get_value.rb b/lib/puppet/parser/functions/try_get_value.rb deleted file mode 100644 index 0c19fd965..000000000 --- a/lib/puppet/parser/functions/try_get_value.rb +++ /dev/null @@ -1,77 +0,0 @@ -module Puppet::Parser::Functions - newfunction( - :try_get_value, - :type => :rvalue, - :arity => -2, - :doc => <<-eos -Looks up into a complex structure of arrays and hashes and returns a value -or the default value if nothing was found. - -Key can contain slashes to describe path components. The function will go down -the structure and try to extract the required value. - -$data = { - 'a' => { - 'b' => [ - 'b1', - 'b2', - 'b3', - ] - } -} - -$value = try_get_value($data, 'a/b/2', 'not_found', '/') -=> $value = 'b3' - -a -> first hash key -b -> second hash key -2 -> array index starting with 0 - -not_found -> (optional) will be returned if there is no value or the path did not match. Defaults to nil. -/ -> (optional) path delimiter. Defaults to '/'. - -In addition to the required "key" argument, "try_get_value" accepts default -argument. It will be returned if no value was found or a path component is -missing. And the fourth argument can set a variable path separator. - eos - ) do |args| - path_lookup = lambda do |data, path, default| - debug "Try_get_value: #{path.inspect} from: #{data.inspect}" - if data.nil? - debug "Try_get_value: no data, return default: #{default.inspect}" - break default - end - unless path.is_a? Array - debug "Try_get_value: wrong path, return default: #{default.inspect}" - break default - end - unless path.any? - debug "Try_get_value: value found, return data: #{data.inspect}" - break data - end - unless data.is_a? Hash or data.is_a? Array - debug "Try_get_value: incorrect data, return default: #{default.inspect}" - break default - end - - key = path.shift - if data.is_a? Array - begin - key = Integer key - rescue ArgumentError - debug "Try_get_value: non-numeric path for an array, return default: #{default.inspect}" - break default - end - end - path_lookup.call data[key], path, default - end - - data = args[0] - path = args[1] || '' - default = args[2] - separator = args[3] || '/' - - path = path.split separator - path_lookup.call data, path, default - end -end diff --git a/lib/puppet/parser/functions/type.rb b/lib/puppet/parser/functions/type.rb deleted file mode 100644 index 016529b03..000000000 --- a/lib/puppet/parser/functions/type.rb +++ /dev/null @@ -1,19 +0,0 @@ -# -# type.rb -# - -module Puppet::Parser::Functions - newfunction(:type, :type => :rvalue, :doc => <<-EOS - DEPRECATED: This function will cease to function on Puppet 4; please use type3x() before upgrading to puppet 4 for backwards-compatibility, or migrate to the new parser's typing system. - EOS - ) do |args| - - warning("type() DEPRECATED: This function will cease to function on Puppet 4; please use type3x() before upgrading to puppet 4 for backwards-compatibility, or migrate to the new parser's typing system.") - if ! Puppet::Parser::Functions.autoloader.loaded?(:type3x) - Puppet::Parser::Functions.autoloader.load(:type3x) - end - function_type3x(args + [false]) - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/type3x.rb b/lib/puppet/parser/functions/type3x.rb deleted file mode 100644 index 0800b4a3e..000000000 --- a/lib/puppet/parser/functions/type3x.rb +++ /dev/null @@ -1,51 +0,0 @@ -# -# type3x.rb -# - -module Puppet::Parser::Functions - newfunction(:type3x, :type => :rvalue, :doc => <<-EOS -DEPRECATED: This function will be removed when puppet 3 support is dropped; please migrate to the new parser's typing system. - -Returns the type when passed a value. Type can be one of: - -* string -* array -* hash -* float -* integer -* boolean - EOS - ) do |args| - raise(Puppet::ParseError, "type3x(): Wrong number of arguments " + - "given (#{args.size} for 1)") if args.size < 1 - - value = args[0] - - klass = value.class - - if not [TrueClass, FalseClass, Array, Bignum, Fixnum, Float, Hash, String].include?(klass) - raise(Puppet::ParseError, 'type3x(): Unknown type') - end - - klass = klass.to_s # Ugly ... - - # We note that Integer is the parent to Bignum and Fixnum ... - result = case klass - when /^(?:Big|Fix)num$/ then 'integer' - when /^(?:True|False)Class$/ then 'boolean' - else klass - end - - if result == "String" then - if value == value.to_i.to_s then - result = "Integer" - elsif value == value.to_f.to_s then - result = "Float" - end - end - - return result.downcase - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/union.rb b/lib/puppet/parser/functions/union.rb index 6c5bb8348..eb2c9f0ce 100644 --- a/lib/puppet/parser/functions/union.rb +++ b/lib/puppet/parser/functions/union.rb @@ -1,22 +1,23 @@ +# frozen_string_literal: true + # # union.rb # - module Puppet::Parser::Functions - newfunction(:union, :type => :rvalue, :doc => <<-EOS -This function returns a union of two or more arrays. + newfunction(:union, type: :rvalue, doc: <<-DOC + @summary + This function returns a union of two or more arrays. -*Examples:* + @return + a unionized array of two or more arrays + @example **Usage** - union(["a","b","c"],["b","c","d"]) - -Would return: ["a","b","c","d"] - EOS + union(["a","b","c"],["b","c","d"]) + Would return: ["a","b","c","d"] + DOC ) do |arguments| - # Check that 2 or more arguments have been given ... - raise(Puppet::ParseError, "union(): Wrong number of arguments " + - "given (#{arguments.size} for < 2)") if arguments.size < 2 + raise(Puppet::ParseError, "union(): Wrong number of arguments given (#{arguments.size} for < 2)") if arguments.size < 2 arguments.each do |argument| raise(Puppet::ParseError, 'union(): Every parameter must be an array') unless argument.is_a?(Array) diff --git a/lib/puppet/parser/functions/unique.rb b/lib/puppet/parser/functions/unique.rb deleted file mode 100644 index cf770f3b4..000000000 --- a/lib/puppet/parser/functions/unique.rb +++ /dev/null @@ -1,50 +0,0 @@ -# -# unique.rb -# - -module Puppet::Parser::Functions - newfunction(:unique, :type => :rvalue, :doc => <<-EOS -This function will remove duplicates from strings and arrays. - -*Examples:* - - unique("aabbcc") - -Will return: - - abc - -You can also use this with arrays: - - unique(["a","a","b","b","c","c"]) - -This returns: - - ["a","b","c"] - EOS - ) do |arguments| - - raise(Puppet::ParseError, "unique(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 - - value = arguments[0] - - unless value.is_a?(Array) || value.is_a?(String) - raise(Puppet::ParseError, 'unique(): Requires either ' + - 'array or string to work with') - end - - result = value.clone - - string = value.is_a?(String) ? true : false - - # We turn any string value into an array to be able to shuffle ... - result = string ? result.split('') : result - result = result.uniq # Remove duplicates ... - result = string ? result.join : result - - return result - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/unix2dos.rb b/lib/puppet/parser/functions/unix2dos.rb index 0bd9cd1f1..4dd4c5662 100644 --- a/lib/puppet/parser/functions/unix2dos.rb +++ b/lib/puppet/parser/functions/unix2dos.rb @@ -1,15 +1,19 @@ +# frozen_string_literal: true + # Custom Puppet function to convert unix to dos format module Puppet::Parser::Functions - newfunction(:unix2dos, :type => :rvalue, :arity => 1, :doc => <<-EOS - Returns the DOS version of the given string. + newfunction(:unix2dos, type: :rvalue, arity: 1, doc: <<-DOC + @summary + Returns the DOS version of the given string. + + @return + the DOS version of the given string. + Takes a single string argument. - EOS + DOC ) do |arguments| + raise(Puppet::ParseError, 'unix2dos(): Requires string as argument') unless arguments[0].is_a?(String) - unless arguments[0].is_a?(String) - raise(Puppet::ParseError, 'unix2dos(): Requires string as argument') - end - - arguments[0].gsub(/\r*\n/, "\r\n") + arguments[0].gsub(%r{\r*\n}, "\r\n") end end diff --git a/lib/puppet/parser/functions/upcase.rb b/lib/puppet/parser/functions/upcase.rb deleted file mode 100644 index 44b3bcd6f..000000000 --- a/lib/puppet/parser/functions/upcase.rb +++ /dev/null @@ -1,45 +0,0 @@ -# -# upcase.rb -# - -module Puppet::Parser::Functions - newfunction(:upcase, :type => :rvalue, :doc => <<-EOS -Converts a string or an array of strings to uppercase. - -*Examples:* - - upcase("abcd") - -Will return: - - ABCD - EOS - ) do |arguments| - - raise(Puppet::ParseError, "upcase(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size != 1 - - value = arguments[0] - - unless value.is_a?(Array) || value.is_a?(Hash) || value.respond_to?(:upcase) - raise(Puppet::ParseError, 'upcase(): Requires an ' + - 'array, hash or object that responds to upcase in order to work') - end - - if value.is_a?(Array) - # Numbers in Puppet are often string-encoded which is troublesome ... - result = value.collect { |i| function_upcase([i]) } - elsif value.is_a?(Hash) - result = {} - value.each_pair do |k, v| - result[function_upcase([k])] = function_upcase([v]) - end - else - result = value.upcase - end - - return result - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/uriescape.rb b/lib/puppet/parser/functions/uriescape.rb index 45bbed22c..128558163 100644 --- a/lib/puppet/parser/functions/uriescape.rb +++ b/lib/puppet/parser/functions/uriescape.rb @@ -1,31 +1,39 @@ +# frozen_string_literal: true + +require 'uri' # # uriescape.rb +# Please note: This function is an implementation of a Ruby class and as such may not be entirely UTF8 compatible. To ensure compatibility please use this function with Ruby 2.4.0 or greater - https://bugs.ruby-lang.org/issues/10085. +# URI.escape has been fully removed as of Ruby 3. Therefore, it will not work as it stand on Puppet 8. Consider deprecating or updating this function. # -require 'uri' - module Puppet::Parser::Functions - newfunction(:uriescape, :type => :rvalue, :doc => <<-EOS - Urlencodes a string or array of strings. - Requires either a single string or an array as an input. - EOS + newfunction(:uriescape, type: :rvalue, doc: <<-DOC + @summary + Urlencodes a string or array of strings. + Requires either a single string or an array as an input. + + @return [String] + a string that contains the converted value + + > **Note:** **Deprecated:** Starting Puppet 8, our Ruby version has upgraded to 3.2. + Therefore, its no longer possible to call URI.escape as it was deprecated by 2.7 and removed completely by 3+. + This function should be removed once Puppet 7 is no longer supported. + DOC ) do |arguments| + raise(Puppet::ParseError, 'Puppet: This function is not available in Puppet 8. URI.escape no longer exists as of Ruby 3+.') if Puppet::Util::Package.versioncmp(Puppet.version, '8').positive? - raise(Puppet::ParseError, "uriescape(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 + raise(Puppet::ParseError, "uriescape(): Wrong number of arguments given (#{arguments.size} for 1)") if arguments.empty? value = arguments[0] - unless value.is_a?(Array) || value.is_a?(String) - raise(Puppet::ParseError, 'uriescape(): Requires either ' + - 'array or string to work with') - end - - if value.is_a?(Array) - # Numbers in Puppet are often string-encoded which is troublesome ... - result = value.collect { |i| i.is_a?(String) ? URI.escape(i) : i } - else - result = URI.escape(value) - end + raise(Puppet::ParseError, 'uriescape(): Requires either array or string to work with') unless value.is_a?(Array) || value.is_a?(String) + + result = if value.is_a?(Array) + # Numbers in Puppet are often string-encoded which is troublesome ... + value.map { |i| i.is_a?(String) ? URI::DEFAULT_PARSER.escape(i) : i } + else + URI::DEFAULT_PARSER.escape(value) + end return result end diff --git a/lib/puppet/parser/functions/validate_absolute_path.rb b/lib/puppet/parser/functions/validate_absolute_path.rb deleted file mode 100644 index b69668096..000000000 --- a/lib/puppet/parser/functions/validate_absolute_path.rb +++ /dev/null @@ -1,69 +0,0 @@ -module Puppet::Parser::Functions - newfunction(:validate_absolute_path, :doc => <<-'ENDHEREDOC') do |args| - Validate the string represents an absolute path in the filesystem. This function works - for windows and unix style paths. - - The following values will pass: - - $my_path = 'C:/Program Files (x86)/Puppet Labs/Puppet' - validate_absolute_path($my_path) - $my_path2 = '/var/lib/puppet' - validate_absolute_path($my_path2) - $my_path3 = ['C:/Program Files (x86)/Puppet Labs/Puppet','C:/Program Files/Puppet Labs/Puppet'] - validate_absolute_path($my_path3) - $my_path4 = ['/var/lib/puppet','/usr/share/puppet'] - validate_absolute_path($my_path4) - - The following values will fail, causing compilation to abort: - - validate_absolute_path(true) - validate_absolute_path('../var/lib/puppet') - validate_absolute_path('var/lib/puppet') - validate_absolute_path([ 'var/lib/puppet', '/var/foo' ]) - validate_absolute_path([ '/var/lib/puppet', 'var/foo' ]) - $undefined = undef - validate_absolute_path($undefined) - - ENDHEREDOC - - require 'puppet/util' - - unless args.length > 0 then - raise Puppet::ParseError, ("validate_absolute_path(): wrong number of arguments (#{args.length}; must be > 0)") - end - - args.each do |arg| - # put arg to candidate var to be able to replace it - candidates = arg - # if arg is just a string with a path to test, convert it to an array - # to avoid test code duplication - unless arg.is_a?(Array) then - candidates = Array.new(1,arg) - end - # iterate over all pathes within the candidates array - candidates.each do |path| - # This logic was borrowed from - # [lib/puppet/file_serving/base.rb](https://github.com/puppetlabs/puppet/blob/master/lib/puppet/file_serving/base.rb) - # Puppet 2.7 and beyond will have Puppet::Util.absolute_path? Fall back to a back-ported implementation otherwise. - if Puppet::Util.respond_to?(:absolute_path?) then - unless Puppet::Util.absolute_path?(path, :posix) or Puppet::Util.absolute_path?(path, :windows) - raise Puppet::ParseError, ("#{path.inspect} is not an absolute path.") - end - else - # This code back-ported from 2.7.x's lib/puppet/util.rb Puppet::Util.absolute_path? - # Determine in a platform-specific way whether a path is absolute. This - # defaults to the local platform if none is specified. - # Escape once for the string literal, and once for the regex. - slash = '[\\\\/]' - name = '[^\\\\/]+' - regexes = { - :windows => %r!^(([A-Z]:#{slash})|(#{slash}#{slash}#{name}#{slash}#{name})|(#{slash}#{slash}\?#{slash}#{name}))!i, - :posix => %r!^/!, - } - rval = (!!(path =~ regexes[:posix])) || (!!(path =~ regexes[:windows])) - rval or raise Puppet::ParseError, ("#{path.inspect} is not an absolute path.") - end - end - end - end -end diff --git a/lib/puppet/parser/functions/validate_array.rb b/lib/puppet/parser/functions/validate_array.rb deleted file mode 100644 index 34b511825..000000000 --- a/lib/puppet/parser/functions/validate_array.rb +++ /dev/null @@ -1,33 +0,0 @@ -module Puppet::Parser::Functions - - newfunction(:validate_array, :doc => <<-'ENDHEREDOC') do |args| - Validate that all passed values are array data structures. Abort catalog - compilation if any value fails this check. - - The following values will pass: - - $my_array = [ 'one', 'two' ] - validate_array($my_array) - - The following values will fail, causing compilation to abort: - - validate_array(true) - validate_array('some_string') - $undefined = undef - validate_array($undefined) - - ENDHEREDOC - - unless args.length > 0 then - raise Puppet::ParseError, ("validate_array(): wrong number of arguments (#{args.length}; must be > 0)") - end - - args.each do |arg| - unless arg.is_a?(Array) - raise Puppet::ParseError, ("#{arg.inspect} is not an Array. It looks to be a #{arg.class}") - end - end - - end - -end diff --git a/lib/puppet/parser/functions/validate_augeas.rb b/lib/puppet/parser/functions/validate_augeas.rb index 2196c3e0e..31df4cd66 100644 --- a/lib/puppet/parser/functions/validate_augeas.rb +++ b/lib/puppet/parser/functions/validate_augeas.rb @@ -1,8 +1,15 @@ +# frozen_string_literal: true + require 'tempfile' +# +# validate_augaes.rb +# module Puppet::Parser::Functions - newfunction(:validate_augeas, :doc => <<-'ENDHEREDOC') do |args| - Perform validation of a string using an Augeas lens + newfunction(:validate_augeas, doc: <<-DOC + @summary + Perform validation of a string using an Augeas lens + The first argument of this function should be a string to test, and the second argument should be the name of the Augeas lens to use. If Augeas fails to parse the string with the lens, the compilation will @@ -12,41 +19,45 @@ module Puppet::Parser::Functions not be found in the file. The `$file` variable points to the location of the temporary file being tested in the Augeas tree. - For example, if you want to make sure your passwd content never contains - a user `foo`, you could write: + @return + validate string using an Augeas lens + + @example **Usage** + + If you want to make sure your passwd content never contains + a user `foo`, you could write: validate_augeas($passwdcontent, 'Passwd.lns', ['$file/foo']) - Or if you wanted to ensure that no users used the '/bin/barsh' shell, - you could use: + If you wanted to ensure that no users used the '/bin/barsh' shell, + you could use: validate_augeas($passwdcontent, 'Passwd.lns', ['$file/*[shell="/bin/barsh"]'] - If a fourth argument is specified, this will be the error message raised and - seen by the user. + If a fourth argument is specified, this will be the error message raised and + seen by the user. - A helpful error message can be returned like this: + A helpful error message can be returned like this: validate_augeas($sudoerscontent, 'Sudoers.lns', [], 'Failed to validate sudoers content with Augeas') - ENDHEREDOC + DOC + ) do |args| unless Puppet.features.augeas? - raise Puppet::ParseError, ("validate_augeas(): this function requires the augeas feature. See http://docs.puppetlabs.com/guides/augeas.html#pre-requisites for how to activate it.") + raise Puppet::ParseError, 'validate_augeas(): this function requires the augeas feature. See http://docs.puppetlabs.com/guides/augeas.html#pre-requisites for how to activate it.' end - if (args.length < 2) or (args.length > 4) then - raise Puppet::ParseError, ("validate_augeas(): wrong number of arguments (#{args.length}; must be 2, 3, or 4)") - end + raise Puppet::ParseError, "validate_augeas(): wrong number of arguments (#{args.length}; must be 2, 3, or 4)" if (args.length < 2) || (args.length > 4) msg = args[3] || "validate_augeas(): Failed to validate content against #{args[1].inspect}" require 'augeas' - aug = Augeas::open(nil, nil, Augeas::NO_MODL_AUTOLOAD) + aug = Augeas.open(nil, nil, Augeas::NO_MODL_AUTOLOAD) begin content = args[0] # Test content in a temporary file - tmpfile = Tempfile.new("validate_augeas") + tmpfile = Tempfile.new('validate_augeas') begin tmpfile.write(content) ensure @@ -56,16 +67,16 @@ module Puppet::Parser::Functions # Check for syntax lens = args[1] aug.transform( - :lens => lens, - :name => 'Validate_augeas', - :incl => tmpfile.path + lens:, + name: 'Validate_augeas', + incl: tmpfile.path, ) aug.load! unless aug.match("/augeas/files#{tmpfile.path}//error").empty? error = aug.get("/augeas/files#{tmpfile.path}//error/message") msg += " with error: #{error}" - raise Puppet::ParseError, (msg) + raise Puppet::ParseError, msg end # Launch unit tests @@ -73,7 +84,7 @@ module Puppet::Parser::Functions aug.defvar('file', "/files#{tmpfile.path}") tests.each do |t| msg += " testing path #{t}" - raise Puppet::ParseError, (msg) unless aug.match(t).empty? + raise Puppet::ParseError, msg unless aug.match(t).empty? end ensure aug.close diff --git a/lib/puppet/parser/functions/validate_bool.rb b/lib/puppet/parser/functions/validate_bool.rb deleted file mode 100644 index 59a08056b..000000000 --- a/lib/puppet/parser/functions/validate_bool.rb +++ /dev/null @@ -1,34 +0,0 @@ -module Puppet::Parser::Functions - - newfunction(:validate_bool, :doc => <<-'ENDHEREDOC') do |args| - Validate that all passed values are either true or false. Abort catalog - compilation if any value fails this check. - - The following values will pass: - - $iamtrue = true - validate_bool(true) - validate_bool(true, true, false, $iamtrue) - - The following values will fail, causing compilation to abort: - - $some_array = [ true ] - validate_bool("false") - validate_bool("true") - validate_bool($some_array) - - ENDHEREDOC - - unless args.length > 0 then - raise Puppet::ParseError, ("validate_bool(): wrong number of arguments (#{args.length}; must be > 0)") - end - - args.each do |arg| - unless function_is_bool([arg]) - raise Puppet::ParseError, ("#{arg.inspect} is not a boolean. It looks to be a #{arg.class}") - end - end - - end - -end diff --git a/lib/puppet/parser/functions/validate_cmd.rb b/lib/puppet/parser/functions/validate_cmd.rb index 5df3c6094..c82952a2b 100644 --- a/lib/puppet/parser/functions/validate_cmd.rb +++ b/lib/puppet/parser/functions/validate_cmd.rb @@ -1,32 +1,40 @@ +# frozen_string_literal: true + require 'puppet/util/execution' require 'tempfile' +# +# validate_cmd.rb +# module Puppet::Parser::Functions - newfunction(:validate_cmd, :doc => <<-'ENDHEREDOC') do |args| - Perform validation of a string with an external command. + newfunction(:validate_cmd, doc: <<-DOC + @summary + Perform validation of a string with an external command. + The first argument of this function should be a string to test, and the second argument should be a path to a test command taking a % as a placeholder for the file path (will default to the end). If the command, launched against a tempfile containing the passed string, returns a non-null value, compilation will abort with a parse error. - If a third argument is specified, this will be the error message raised and seen by the user. + @return + validate of a string with an external command + A helpful error message can be returned like this: - Example: + @example **Usage** - # Defaults to end of path + Defaults to end of path validate_cmd($sudoerscontent, '/usr/sbin/visudo -c -f', 'Visudo failed to validate sudoers content') - # % as file location + % as file location validate_cmd($haproxycontent, '/usr/sbin/haproxy -f % -c', 'Haproxy failed to validate config content') - ENDHEREDOC - if (args.length < 2) or (args.length > 3) then - raise Puppet::ParseError, ("validate_cmd(): wrong number of arguments (#{args.length}; must be 2 or 3)") - end + DOC + ) do |args| + raise Puppet::ParseError, "validate_cmd(): wrong number of arguments (#{args.length}; must be 2 or 3)" if (args.length < 2) || (args.length > 3) msg = args[2] || "validate_cmd(): failed to validate content with command #{args[1].inspect}" @@ -34,27 +42,27 @@ module Puppet::Parser::Functions checkscript = args[1] # Test content in a temporary file - tmpfile = Tempfile.new("validate_cmd") + tmpfile = Tempfile.new('validate_cmd') begin tmpfile.write(content) tmpfile.close - if checkscript =~ /\s%(\s|$)/ - check_with_correct_location = checkscript.gsub(/%/,tmpfile.path) - else - check_with_correct_location = "#{checkscript} #{tmpfile.path}" - end + check_with_correct_location = if %r{\s%(\s|$)}.match?(checkscript) + checkscript.gsub(%r{%}, tmpfile.path) + else + "#{checkscript} #{tmpfile.path}" + end - if Puppet::Util::Execution.respond_to?('execute') + if Puppet::Util::Execution.respond_to?(:execute) Puppet::Util::Execution.execute(check_with_correct_location) else Puppet::Util.execute(check_with_correct_location) end - rescue Puppet::ExecutionFailure => detail - msg += "\n#{detail}" + rescue Puppet::ExecutionFailure => e + msg += "\n#{e}" raise Puppet::ParseError, msg - rescue Exception => detail - msg += "\n#{detail.class.name} #{detail}" + rescue StandardError => e + msg += "\n#{e.class.name} #{e}" raise Puppet::ParseError, msg ensure tmpfile.unlink diff --git a/lib/puppet/parser/functions/validate_hash.rb b/lib/puppet/parser/functions/validate_hash.rb deleted file mode 100644 index 9bdd54328..000000000 --- a/lib/puppet/parser/functions/validate_hash.rb +++ /dev/null @@ -1,33 +0,0 @@ -module Puppet::Parser::Functions - - newfunction(:validate_hash, :doc => <<-'ENDHEREDOC') do |args| - Validate that all passed values are hash data structures. Abort catalog - compilation if any value fails this check. - - The following values will pass: - - $my_hash = { 'one' => 'two' } - validate_hash($my_hash) - - The following values will fail, causing compilation to abort: - - validate_hash(true) - validate_hash('some_string') - $undefined = undef - validate_hash($undefined) - - ENDHEREDOC - - unless args.length > 0 then - raise Puppet::ParseError, ("validate_hash(): wrong number of arguments (#{args.length}; must be > 0)") - end - - args.each do |arg| - unless arg.is_a?(Hash) - raise Puppet::ParseError, ("#{arg.inspect} is not a Hash. It looks to be a #{arg.class}") - end - end - - end - -end diff --git a/lib/puppet/parser/functions/validate_integer.rb b/lib/puppet/parser/functions/validate_integer.rb deleted file mode 100644 index a950916b1..000000000 --- a/lib/puppet/parser/functions/validate_integer.rb +++ /dev/null @@ -1,132 +0,0 @@ -module Puppet::Parser::Functions - - newfunction(:validate_integer, :doc => <<-'ENDHEREDOC') do |args| - Validate that the first argument is an integer (or an array of integers). Abort catalog compilation if any of the checks fail. - - The second argument is optional and passes a maximum. (All elements of) the first argument has to be less or equal to this max. - - The third argument is optional and passes a minimum. (All elements of) the first argument has to be greater or equal to this min. - If, and only if, a minimum is given, the second argument may be an empty string or undef, which will be handled to just check - if (all elements of) the first argument are greater or equal to the given minimum. - - It will fail if the first argument is not an integer or array of integers, and if arg 2 and arg 3 are not convertable to an integer. - - The following values will pass: - - validate_integer(1) - validate_integer(1, 2) - validate_integer(1, 1) - validate_integer(1, 2, 0) - validate_integer(2, 2, 2) - validate_integer(2, '', 0) - validate_integer(2, undef, 0) - $foo = undef - validate_integer(2, $foo, 0) - validate_integer([1,2,3,4,5], 6) - validate_integer([1,2,3,4,5], 6, 0) - - Plus all of the above, but any combination of values passed as strings ('1' or "1"). - Plus all of the above, but with (correct) combinations of negative integer values. - - The following values will not: - - validate_integer(true) - validate_integer(false) - validate_integer(7.0) - validate_integer({ 1 => 2 }) - $foo = undef - validate_integer($foo) - validate_integer($foobaridontexist) - - validate_integer(1, 0) - validate_integer(1, true) - validate_integer(1, '') - validate_integer(1, undef) - validate_integer(1, , 0) - validate_integer(1, 2, 3) - validate_integer(1, 3, 2) - validate_integer(1, 3, true) - - Plus all of the above, but any combination of values passed as strings ('false' or "false"). - Plus all of the above, but with incorrect combinations of negative integer values. - Plus all of the above, but with non-integer items in arrays or maximum / minimum argument. - - ENDHEREDOC - - # tell the user we need at least one, and optionally up to two other parameters - raise Puppet::ParseError, "validate_integer(): Wrong number of arguments; must be 1, 2 or 3, got #{args.length}" unless args.length > 0 and args.length < 4 - - input, max, min = *args - - # check maximum parameter - if args.length > 1 - max = max.to_s - # allow max to be empty (or undefined) if we have a minimum set - if args.length > 2 and max == '' - max = nil - else - begin - max = Integer(max) - rescue TypeError, ArgumentError - raise Puppet::ParseError, "validate_integer(): Expected second argument to be unset or an Integer, got #{max}:#{max.class}" - end - end - else - max = nil - end - - # check minimum parameter - if args.length > 2 - begin - min = Integer(min.to_s) - rescue TypeError, ArgumentError - raise Puppet::ParseError, "validate_integer(): Expected third argument to be unset or an Integer, got #{min}:#{min.class}" - end - else - min = nil - end - - # ensure that min < max - if min and max and min > max - raise Puppet::ParseError, "validate_integer(): Expected second argument to be larger than third argument, got #{max} < #{min}" - end - - # create lamba validator function - validator = lambda do |num| - # check input < max - if max and num > max - raise Puppet::ParseError, "validate_integer(): Expected #{input.inspect} to be smaller or equal to #{max}, got #{input.inspect}." - end - # check input > min (this will only be checked if no exception has been raised before) - if min and num < min - raise Puppet::ParseError, "validate_integer(): Expected #{input.inspect} to be greater or equal to #{min}, got #{input.inspect}." - end - end - - # if this is an array, handle it. - case input - when Array - # check every element of the array - input.each_with_index do |arg, pos| - begin - raise TypeError if arg.is_a?(Hash) - arg = Integer(arg.to_s) - validator.call(arg) - rescue TypeError, ArgumentError - raise Puppet::ParseError, "validate_integer(): Expected element at array position #{pos} to be an Integer, got #{arg.class}" - end - end - # for the sake of compatibility with ruby 1.8, we need extra handling of hashes - when Hash - raise Puppet::ParseError, "validate_integer(): Expected first argument to be an Integer or Array, got #{input.class}" - # check the input. this will also fail any stuff other than pure, shiny integers - else - begin - input = Integer(input.to_s) - validator.call(input) - rescue TypeError, ArgumentError - raise Puppet::ParseError, "validate_integer(): Expected first argument to be an Integer or Array, got #{input.class}" - end - end - end -end diff --git a/lib/puppet/parser/functions/validate_ip_address.rb b/lib/puppet/parser/functions/validate_ip_address.rb deleted file mode 100644 index c0baf82eb..000000000 --- a/lib/puppet/parser/functions/validate_ip_address.rb +++ /dev/null @@ -1,50 +0,0 @@ -module Puppet::Parser::Functions - - newfunction(:validate_ip_address, :doc => <<-ENDHEREDOC - Validate that all values passed are valid IP addresses, - regardless they are IPv4 or IPv6 - Fail compilation if any value fails this check. - The following values will pass: - $my_ip = "1.2.3.4" - validate_ip_address($my_ip) - validate_bool("8.8.8.8", "172.16.0.1", $my_ip) - - $my_ip = "3ffe:505:2" - validate_ip_address(1) - validate_ip_address($my_ip) - validate_bool("fe80::baf6:b1ff:fe19:7507", $my_ip) - - The following values will fail, causing compilation to abort: - $some_array = [ 1, true, false, "garbage string", "3ffe:505:2" ] - validate_ip_address($some_array) - ENDHEREDOC - ) do |args| - - require "ipaddr" - rescuable_exceptions = [ ArgumentError ] - - if defined?(IPAddr::InvalidAddressError) - rescuable_exceptions << IPAddr::InvalidAddressError - end - - unless args.length > 0 then - raise Puppet::ParseError, ("validate_ip_address(): wrong number of arguments (#{args.length}; must be > 0)") - end - - args.each do |arg| - unless arg.is_a?(String) - raise Puppet::ParseError, "#{arg.inspect} is not a string." - end - - begin - unless IPAddr.new(arg).ipv4? or IPAddr.new(arg).ipv6? - raise Puppet::ParseError, "#{arg.inspect} is not a valid IP address." - end - rescue *rescuable_exceptions - raise Puppet::ParseError, "#{arg.inspect} is not a valid IP address." - end - end - - end - -end diff --git a/lib/puppet/parser/functions/validate_ipv4_address.rb b/lib/puppet/parser/functions/validate_ipv4_address.rb deleted file mode 100644 index 97faa5729..000000000 --- a/lib/puppet/parser/functions/validate_ipv4_address.rb +++ /dev/null @@ -1,48 +0,0 @@ -module Puppet::Parser::Functions - - newfunction(:validate_ipv4_address, :doc => <<-ENDHEREDOC - Validate that all values passed are valid IPv4 addresses. - Fail compilation if any value fails this check. - - The following values will pass: - - $my_ip = "1.2.3.4" - validate_ipv4_address($my_ip) - validate_ipv4_address("8.8.8.8", "172.16.0.1", $my_ip) - - The following values will fail, causing compilation to abort: - - $some_array = [ 1, true, false, "garbage string", "3ffe:505:2" ] - validate_ipv4_address($some_array) - - ENDHEREDOC - ) do |args| - - require "ipaddr" - rescuable_exceptions = [ ArgumentError ] - - if defined?(IPAddr::InvalidAddressError) - rescuable_exceptions << IPAddr::InvalidAddressError - end - - unless args.length > 0 then - raise Puppet::ParseError, ("validate_ipv4_address(): wrong number of arguments (#{args.length}; must be > 0)") - end - - args.each do |arg| - unless arg.is_a?(String) - raise Puppet::ParseError, "#{arg.inspect} is not a string." - end - - begin - unless IPAddr.new(arg).ipv4? - raise Puppet::ParseError, "#{arg.inspect} is not a valid IPv4 address." - end - rescue *rescuable_exceptions - raise Puppet::ParseError, "#{arg.inspect} is not a valid IPv4 address." - end - end - - end - -end diff --git a/lib/puppet/parser/functions/validate_ipv6_address.rb b/lib/puppet/parser/functions/validate_ipv6_address.rb deleted file mode 100644 index b0f2558df..000000000 --- a/lib/puppet/parser/functions/validate_ipv6_address.rb +++ /dev/null @@ -1,49 +0,0 @@ -module Puppet::Parser::Functions - - newfunction(:validate_ipv6_address, :doc => <<-ENDHEREDOC - Validate that all values passed are valid IPv6 addresses. - Fail compilation if any value fails this check. - - The following values will pass: - - $my_ip = "3ffe:505:2" - validate_ipv6_address(1) - validate_ipv6_address($my_ip) - validate_bool("fe80::baf6:b1ff:fe19:7507", $my_ip) - - The following values will fail, causing compilation to abort: - - $some_array = [ true, false, "garbage string", "1.2.3.4" ] - validate_ipv6_address($some_array) - - ENDHEREDOC - ) do |args| - - require "ipaddr" - rescuable_exceptions = [ ArgumentError ] - - if defined?(IPAddr::InvalidAddressError) - rescuable_exceptions << IPAddr::InvalidAddressError - end - - unless args.length > 0 then - raise Puppet::ParseError, ("validate_ipv6_address(): wrong number of arguments (#{args.length}; must be > 0)") - end - - args.each do |arg| - unless arg.is_a?(String) - raise Puppet::ParseError, "#{arg.inspect} is not a string." - end - - begin - unless IPAddr.new(arg).ipv6? - raise Puppet::ParseError, "#{arg.inspect} is not a valid IPv6 address." - end - rescue *rescuable_exceptions - raise Puppet::ParseError, "#{arg.inspect} is not a valid IPv6 address." - end - end - - end - -end diff --git a/lib/puppet/parser/functions/validate_numeric.rb b/lib/puppet/parser/functions/validate_numeric.rb deleted file mode 100644 index 3a144434b..000000000 --- a/lib/puppet/parser/functions/validate_numeric.rb +++ /dev/null @@ -1,94 +0,0 @@ -module Puppet::Parser::Functions - - newfunction(:validate_numeric, :doc => <<-'ENDHEREDOC') do |args| - Validate that the first argument is a numeric value (or an array of numeric values). Abort catalog compilation if any of the checks fail. - - The second argument is optional and passes a maximum. (All elements of) the first argument has to be less or equal to this max. - - The third argument is optional and passes a minimum. (All elements of) the first argument has to be greater or equal to this min. - If, and only if, a minimum is given, the second argument may be an empty string or undef, which will be handled to just check - if (all elements of) the first argument are greater or equal to the given minimum. - - It will fail if the first argument is not a numeric (Integer or Float) or array of numerics, and if arg 2 and arg 3 are not convertable to a numeric. - - For passing and failing usage, see `validate_integer()`. It is all the same for validate_numeric, yet now floating point values are allowed, too. - - ENDHEREDOC - - # tell the user we need at least one, and optionally up to two other parameters - raise Puppet::ParseError, "validate_numeric(): Wrong number of arguments; must be 1, 2 or 3, got #{args.length}" unless args.length > 0 and args.length < 4 - - input, max, min = *args - - # check maximum parameter - if args.length > 1 - max = max.to_s - # allow max to be empty (or undefined) if we have a minimum set - if args.length > 2 and max == '' - max = nil - else - begin - max = Float(max) - rescue TypeError, ArgumentError - raise Puppet::ParseError, "validate_numeric(): Expected second argument to be unset or a Numeric, got #{max}:#{max.class}" - end - end - else - max = nil - end - - # check minimum parameter - if args.length > 2 - begin - min = Float(min.to_s) - rescue TypeError, ArgumentError - raise Puppet::ParseError, "validate_numeric(): Expected third argument to be unset or a Numeric, got #{min}:#{min.class}" - end - else - min = nil - end - - # ensure that min < max - if min and max and min > max - raise Puppet::ParseError, "validate_numeric(): Expected second argument to be larger than third argument, got #{max} < #{min}" - end - - # create lamba validator function - validator = lambda do |num| - # check input < max - if max and num > max - raise Puppet::ParseError, "validate_numeric(): Expected #{input.inspect} to be smaller or equal to #{max}, got #{input.inspect}." - end - # check input > min (this will only be checked if no exception has been raised before) - if min and num < min - raise Puppet::ParseError, "validate_numeric(): Expected #{input.inspect} to be greater or equal to #{min}, got #{input.inspect}." - end - end - - # if this is an array, handle it. - case input - when Array - # check every element of the array - input.each_with_index do |arg, pos| - begin - raise TypeError if arg.is_a?(Hash) - arg = Float(arg.to_s) - validator.call(arg) - rescue TypeError, ArgumentError - raise Puppet::ParseError, "validate_numeric(): Expected element at array position #{pos} to be a Numeric, got #{arg.class}" - end - end - # for the sake of compatibility with ruby 1.8, we need extra handling of hashes - when Hash - raise Puppet::ParseError, "validate_integer(): Expected first argument to be a Numeric or Array, got #{input.class}" - # check the input. this will also fail any stuff other than pure, shiny integers - else - begin - input = Float(input.to_s) - validator.call(input) - rescue TypeError, ArgumentError - raise Puppet::ParseError, "validate_numeric(): Expected first argument to be a Numeric or Array, got #{input.class}" - end - end - end -end diff --git a/lib/puppet/parser/functions/validate_re.rb b/lib/puppet/parser/functions/validate_re.rb deleted file mode 100644 index efee7f8cb..000000000 --- a/lib/puppet/parser/functions/validate_re.rb +++ /dev/null @@ -1,47 +0,0 @@ -module Puppet::Parser::Functions - newfunction(:validate_re, :doc => <<-'ENDHEREDOC') do |args| - Perform simple validation of a string against one or more regular - expressions. The first argument of this function should be a string to - test, and the second argument should be a stringified regular expression - (without the // delimiters) or an array of regular expressions. If none - of the regular expressions match the string passed in, compilation will - abort with a parse error. - - If a third argument is specified, this will be the error message raised and - seen by the user. - - The following strings will validate against the regular expressions: - - validate_re('one', '^one$') - validate_re('one', [ '^one', '^two' ]) - - The following strings will fail to validate, causing compilation to abort: - - validate_re('one', [ '^two', '^three' ]) - - A helpful error message can be returned like this: - - validate_re($::puppetversion, '^2.7', 'The $puppetversion fact value does not match 2.7') - - Note: Compilation will also abort, if the first argument is not a String. Always use - quotes to force stringification: - - validate_re("${::operatingsystemmajrelease}", '^[57]$') - - ENDHEREDOC - if (args.length < 2) or (args.length > 3) then - raise Puppet::ParseError, "validate_re(): wrong number of arguments (#{args.length}; must be 2 or 3)" - end - - raise Puppet::ParseError, "validate_re(): input needs to be a String, not a #{args[0].class}" unless args[0].is_a? String - - msg = args[2] || "validate_re(): #{args[0].inspect} does not match #{args[1].inspect}" - - # We're using a flattened array here because we can't call String#any? in - # Ruby 1.9 like we can in Ruby 1.8 - raise Puppet::ParseError, msg unless [args[1]].flatten.any? do |re_str| - args[0] =~ Regexp.compile(re_str) - end - - end -end diff --git a/lib/puppet/parser/functions/validate_slength.rb b/lib/puppet/parser/functions/validate_slength.rb deleted file mode 100644 index 47c7d4a6c..000000000 --- a/lib/puppet/parser/functions/validate_slength.rb +++ /dev/null @@ -1,69 +0,0 @@ -module Puppet::Parser::Functions - - newfunction(:validate_slength, :doc => <<-'ENDHEREDOC') do |args| - Validate that the first argument is a string (or an array of strings), and - less/equal to than the length of the second argument. An optional third - parameter can be given the minimum length. It fails if the first - argument is not a string or array of strings, and if arg 2 and arg 3 are - not convertable to a number. - - The following values will pass: - - validate_slength("discombobulate",17) - validate_slength(["discombobulate","moo"],17) - validate_slength(["discombobulate","moo"],17,3) - - The following valueis will not: - - validate_slength("discombobulate",1) - validate_slength(["discombobulate","thermometer"],5) - validate_slength(["discombobulate","moo"],17,10) - - ENDHEREDOC - - raise Puppet::ParseError, "validate_slength(): Wrong number of arguments (#{args.length}; must be 2 or 3)" unless args.length == 2 or args.length == 3 - - input, max_length, min_length = *args - - begin - max_length = Integer(max_length) - raise ArgumentError if max_length <= 0 - rescue ArgumentError, TypeError - raise Puppet::ParseError, "validate_slength(): Expected second argument to be a positive Numeric, got #{max_length}:#{max_length.class}" - end - - if min_length - begin - min_length = Integer(min_length) - raise ArgumentError if min_length < 0 - rescue ArgumentError, TypeError - raise Puppet::ParseError, "validate_slength(): Expected third argument to be unset or a positive Numeric, got #{min_length}:#{min_length.class}" - end - else - min_length = 0 - end - - raise Puppet::ParseError, "validate_slength(): Expected second argument to be equal to or larger than third argument" unless max_length >= min_length - - validator = lambda do |str| - unless str.length <= max_length and str.length >= min_length - raise Puppet::ParseError, "validate_slength(): Expected length of #{input.inspect} to be between #{min_length} and #{max_length}, was #{input.length}" - end - end - - case input - when String - validator.call(input) - when Array - input.each_with_index do |arg, pos| - if arg.is_a? String - validator.call(arg) - else - raise Puppet::ParseError, "validate_slength(): Expected element at array position #{pos} to be a String, got #{arg.class}" - end - end - else - raise Puppet::ParseError, "validate_slength(): Expected first argument to be a String or Array, got #{input.class}" - end - end -end diff --git a/lib/puppet/parser/functions/validate_string.rb b/lib/puppet/parser/functions/validate_string.rb deleted file mode 100644 index c841f6abb..000000000 --- a/lib/puppet/parser/functions/validate_string.rb +++ /dev/null @@ -1,38 +0,0 @@ -module Puppet::Parser::Functions - - newfunction(:validate_string, :doc => <<-'ENDHEREDOC') do |args| - Validate that all passed values are string data structures. Abort catalog - compilation if any value fails this check. - - The following values will pass: - - $my_string = "one two" - validate_string($my_string, 'three') - - The following values will fail, causing compilation to abort: - - validate_string(true) - validate_string([ 'some', 'array' ]) - - Note: validate_string(undef) will not fail in this version of the - functions API (incl. current and future parser). Instead, use: - - if $var == undef { - fail('...') - } - - ENDHEREDOC - - unless args.length > 0 then - raise Puppet::ParseError, ("validate_string(): wrong number of arguments (#{args.length}; must be > 0)") - end - - args.each do |arg| - unless arg.is_a?(String) - raise Puppet::ParseError, ("#{arg.inspect} is not a string. It looks to be a #{arg.class}") - end - end - - end - -end diff --git a/lib/puppet/parser/functions/validate_x509_rsa_key_pair.rb b/lib/puppet/parser/functions/validate_x509_rsa_key_pair.rb new file mode 100644 index 000000000..48fbfe30a --- /dev/null +++ b/lib/puppet/parser/functions/validate_x509_rsa_key_pair.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +# +# validate_x509_rsa_key_pair.rb +# +module Puppet::Parser::Functions + newfunction(:validate_x509_rsa_key_pair, doc: <<-DOC + @summary + Validates a PEM-formatted X.509 certificate and RSA private key using + OpenSSL. + + Verifies that the certficate's signature was created from the + supplied key. + + @return + Fail compilation if any value fails this check. + + ```validate_x509_rsa_key_pair($cert, $key)``` + + DOC + ) do |args| + require 'openssl' + + NUM_ARGS = 2 unless defined? NUM_ARGS + + unless args.length == NUM_ARGS + raise Puppet::ParseError, + "validate_x509_rsa_key_pair(): wrong number of arguments (#{args.length}; must be #{NUM_ARGS})" + end + + args.each do |arg| + raise Puppet::ParseError, "#{arg.inspect} is not a string." unless arg.is_a?(String) + end + + begin + cert = OpenSSL::X509::Certificate.new(args[0]) + rescue OpenSSL::X509::CertificateError => e + raise Puppet::ParseError, "Not a valid x509 certificate: #{e}" + end + + begin + key = OpenSSL::PKey::RSA.new(args[1]) + rescue OpenSSL::PKey::RSAError => e + raise Puppet::ParseError, "Not a valid RSA key: #{e}" + end + + raise Puppet::ParseError, 'Certificate signature does not match supplied key' unless cert.verify(key) + end +end diff --git a/lib/puppet/parser/functions/values.rb b/lib/puppet/parser/functions/values.rb deleted file mode 100644 index 16067561b..000000000 --- a/lib/puppet/parser/functions/values.rb +++ /dev/null @@ -1,39 +0,0 @@ -# -# values.rb -# - -module Puppet::Parser::Functions - newfunction(:values, :type => :rvalue, :doc => <<-EOS -When given a hash this function will return the values of that hash. - -*Examples:* - - $hash = { - 'a' => 1, - 'b' => 2, - 'c' => 3, - } - values($hash) - -This example would return: - - [1,2,3] - EOS - ) do |arguments| - - raise(Puppet::ParseError, "values(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 - - hash = arguments[0] - - unless hash.is_a?(Hash) - raise(Puppet::ParseError, 'values(): Requires hash to work with') - end - - result = hash.values - - return result - end -end - -# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/values_at.rb b/lib/puppet/parser/functions/values_at.rb index f350f5391..a3e69e065 100644 --- a/lib/puppet/parser/functions/values_at.rb +++ b/lib/puppet/parser/functions/values_at.rb @@ -1,96 +1,89 @@ +# frozen_string_literal: true + # # values_at.rb # - module Puppet::Parser::Functions - newfunction(:values_at, :type => :rvalue, :doc => <<-EOS -Finds value inside an array based on location. + newfunction(:values_at, type: :rvalue, doc: <<-DOC + @summary + Finds value inside an array based on location. -The first argument is the array you want to analyze, and the second element can -be a combination of: + The first argument is the array you want to analyze, and the second element can + be a combination of: -* A single numeric index -* A range in the form of 'start-stop' (eg. 4-9) -* An array combining the above + * A single numeric index + * A range in the form of 'start-stop' (eg. 4-9) + * An array combining the above -*Examples*: + @return + an array of values identified by location - values_at(['a','b','c'], 2) + @example **Usage** -Would return ['c']. + values_at(['a','b','c'], 2) + Would return ['c'] - values_at(['a','b','c'], ["0-1"]) + values_at(['a','b','c'], ["0-1"]) + Would return ['a','b'] -Would return ['a','b']. + values_at(['a','b','c','d','e'], [0, "2-3"]) + Would return ['a','c','d'] - values_at(['a','b','c','d','e'], [0, "2-3"]) + > *Note:* + Since Puppet 4.0.0 it is possible to slice an array with index and count directly in the language. + A negative value is taken to be "from the end" of the array: -Would return ['a','c','d']. - EOS - ) do |arguments| + `['a', 'b', 'c', 'd'][1, 2]` results in `['b', 'c']` + `['a', 'b', 'c', 'd'][2, -1]` results in `['c', 'd']` + `['a', 'b', 'c', 'd'][1, -2]` results in `['b', 'c']` - raise(Puppet::ParseError, "values_at(): Wrong number of " + - "arguments given (#{arguments.size} for 2)") if arguments.size < 2 + DOC + ) do |arguments| + raise(Puppet::ParseError, "values_at(): Wrong number of arguments given (#{arguments.size} for 2)") if arguments.size < 2 array = arguments.shift - unless array.is_a?(Array) - raise(Puppet::ParseError, 'values_at(): Requires array to work with') - end + raise(Puppet::ParseError, 'values_at(): Requires array to work with') unless array.is_a?(Array) - indices = [arguments.shift].flatten() # Get them all ... Pokemon ... + indices = [arguments.shift].flatten # Get them all ... Pokemon ... - if not indices or indices.empty? - raise(Puppet::ParseError, 'values_at(): You must provide ' + - 'at least one positive index to collect') - end + raise(Puppet::ParseError, 'values_at(): You must provide at least one positive index to collect') if !indices || indices.empty? - result = [] indices_list = [] indices.each do |i| i = i.to_s - if m = i.match(/^(\d+)(\.\.\.?|\-)(\d+)$/) + m = i.match(%r{^(\d+)(\.\.\.?|-)(\d+)$}) + if m start = m[1].to_i stop = m[3].to_i type = m[2] - if start > stop - raise(Puppet::ParseError, 'values_at(): Stop index in ' + - 'given indices range is smaller than the start index') - elsif stop > array.size - 1 # First element is at index 0 is it not? - raise(Puppet::ParseError, 'values_at(): Stop index in ' + - 'given indices range exceeds array size') - end + raise(Puppet::ParseError, 'values_at(): Stop index in given indices range is smaller than the start index') if start > stop + raise(Puppet::ParseError, 'values_at(): Stop index in given indices range exceeds array size') if stop > array.size - 1 # First element is at index 0 is it not? range = case type - when /^(\.\.|\-)$/ then (start .. stop) - when /^(\.\.\.)$/ then (start ... stop) # Exclusive of last element ... - end + when %r{^(\.\.|-)$} then (start..stop) + when %r{^(\.\.\.)$} then (start...stop) # Exclusive of last element ... + end - range.each { |i| indices_list << i.to_i } + range.each { |i| indices_list << i.to_i } # rubocop:disable Lint/ShadowingOuterLocalVariable : Value is meant to be shadowed else # Only positive numbers allowed in this case ... - if not i.match(/^\d+$/) - raise(Puppet::ParseError, 'values_at(): Unknown format ' + - 'of given index') - end + raise(Puppet::ParseError, 'values_at(): Unknown format of given index') unless %r{^\d+$}.match?(i) # In Puppet numbers are often string-encoded ... i = i.to_i - if i > array.size - 1 # Same story. First element is at index 0 ... - raise(Puppet::ParseError, 'values_at(): Given index ' + - 'exceeds array size') - end + raise(Puppet::ParseError, 'values_at(): Given index exceeds array size') if i > array.size - 1 # Same story. First element is at index 0 ... indices_list << i end end # We remove nil values as they make no sense in Puppet DSL ... - result = indices_list.collect { |i| array[i] }.compact + result = indices_list.map { |i| array[i] }.compact return result end diff --git a/lib/puppet/parser/functions/zip.rb b/lib/puppet/parser/functions/zip.rb index 3074f282b..40323b7de 100644 --- a/lib/puppet/parser/functions/zip.rb +++ b/lib/puppet/parser/functions/zip.rb @@ -1,31 +1,28 @@ +# frozen_string_literal: true + # # zip.rb # - module Puppet::Parser::Functions - newfunction(:zip, :type => :rvalue, :doc => <<-EOS -Takes one element from first array and merges corresponding elements from second array. This generates a sequence of n-element arrays, where n is one more than the count of arguments. - -*Example:* + newfunction(:zip, type: :rvalue, doc: <<-DOC + @summary + Takes one element from first array and merges corresponding elements from second array. - zip(['1','2','3'],['4','5','6']) + @return + This generates a sequence of n-element arrays, where n is one more than the count of arguments. -Would result in: - - ["1", "4"], ["2", "5"], ["3", "6"] - EOS + @example + zip(['1','2','3'],['4','5','6']) + Would result in: ["1", "4"], ["2", "5"], ["3", "6"] + DOC ) do |arguments| - # Technically we support three arguments but only first is mandatory ... - raise(Puppet::ParseError, "zip(): Wrong number of arguments " + - "given (#{arguments.size} for 2)") if arguments.size < 2 + raise(Puppet::ParseError, "zip(): Wrong number of arguments given (#{arguments.size} for 2)") if arguments.size < 2 a = arguments[0] b = arguments[1] - unless a.is_a?(Array) and b.is_a?(Array) - raise(Puppet::ParseError, 'zip(): Requires array to work with') - end + raise(Puppet::ParseError, 'zip(): Requires array to work with') unless a.is_a?(Array) && b.is_a?(Array) flatten = function_str2bool([arguments[2]]) if arguments[2] diff --git a/lib/puppet/provider/file_line/ruby.rb b/lib/puppet/provider/file_line/ruby.rb index aab6fe289..4269f16ec 100644 --- a/lib/puppet/provider/file_line/ruby.rb +++ b/lib/puppet/provider/file_line/ruby.rb @@ -1,28 +1,66 @@ +# frozen_string_literal: true + Puppet::Type.type(:file_line).provide(:ruby) do + desc <<-DOC + @summary + This type allows puppet to manage small config files. + + The implementation matches the full line, including whitespace at the + beginning and end. If the line is not contained in the given file, Puppet + will append the line to the end of the file to ensure the desired state. + Multiple resources may be declared to manage multiple lines in the same file. + DOC def exists? - if resource[:replace].to_s != 'true' and count_matches(match_regex) > 0 - true - else - lines.find do |line| - line.chomp == resource[:line].chomp - end + found = false + lines_count = 0 + lines.each do |line| + found = line.chomp == resource[:line] + lines_count += 1 if found end + return found = lines_count.positive? if resource[:match].nil? + + match_count = count_matches(new_match_regex) + found = if resource[:ensure] == :present + if match_count.zero? + if lines_count.zero? && resource[:append_on_no_match].to_s == 'false' + true # lies, but gets the job done + else + !(lines_count.zero? && resource[:append_on_no_match].to_s != 'false') + end + elsif resource[:replace_all_matches_not_matching_line].to_s == 'true' + false # maybe lies, but knows there's still work to do + elsif lines_count.zero? + resource[:replace].to_s == 'false' + else + true + end + elsif match_count.zero? + if lines_count.zero? + false + else + true + end + elsif lines_count.zero? + resource[:match_for_absence].to_s == 'true' + else + true + end end def create - unless resource[:replace].to_s != 'true' and count_matches(match_regex) > 0 - if resource[:match] - handle_create_with_match - elsif resource[:after] - handle_create_with_after - else - append_line - end + return if resource[:replace].to_s != 'true' && count_matches(new_match_regex).positive? + + if resource[:match] + handle_create_with_match + elsif resource[:after] + handle_create_with_after + else + handle_append_line end end def destroy - if resource[:match_for_absence].to_s == 'true' and resource[:match] + if resource[:match_for_absence].to_s == 'true' && resource[:match] handle_destroy_with_match else handle_destroy_line @@ -30,99 +68,103 @@ def destroy end private + def lines # If this type is ever used with very large files, we should # write this in a different way, using a temp # file; for now assuming that this type is only used on # small-ish config files that can fit into memory without # too much trouble. + + @lines ||= File.readlines(resource[:path], encoding: resource[:encoding]) + rescue TypeError => _e + # Ruby 1.8 doesn't support open_args @lines ||= File.readlines(resource[:path]) + rescue Errno::ENOENT + raise unless resource.noop? + + @lines ||= [] end - def match_regex - resource[:match] ? Regexp.new(resource[:match]) : nil + def new_after_regex + resource[:after] ? Regexp.new(resource[:after]) : nil end - def handle_create_with_match() - regex_after = resource[:after] ? Regexp.new(resource[:after]) : nil - match_count = count_matches(match_regex) + def new_match_regex + resource[:match] ? Regexp.new(resource[:match]) : nil + end - if match_count > 1 && resource[:multiple].to_s != 'true' - raise Puppet::Error, "More than one line in file '#{resource[:path]}' matches pattern '#{resource[:match]}'" + def count_matches(regex) + lines.count do |line| + if resource[:replace_all_matches_not_matching_line].to_s == 'true' + line.match(regex) unless line.chomp == resource[:line] + else + line.match(regex) + end end + end + + def handle_create_with_match + after_regex = new_after_regex + match_regex = new_match_regex + match_count = count_matches(new_match_regex) + + raise Puppet::Error, "More than one line in file '#{resource[:path]}' matches pattern '#{resource[:match]}'" if match_count > 1 && resource[:multiple].to_s != 'true' File.open(resource[:path], 'w') do |fh| - lines.each do |l| - fh.puts(match_regex.match(l) ? resource[:line] : l) - if (match_count == 0 and regex_after) - if regex_after.match(l) - fh.puts(resource[:line]) - match_count += 1 #Increment match_count to indicate that the new line has been inserted. - end + lines.each do |line| + fh.puts(match_regex.match(line) ? resource[:line] : line) + next unless match_count.zero? && after_regex + + if after_regex.match(line) + fh.puts(resource[:line]) + match_count += 1 # Increment match_count to indicate that the new line has been inserted. end end - if (match_count == 0) - fh.puts(resource[:line]) - end + fh.puts(resource[:line]) if match_count.zero? end end def handle_create_with_after - regex = Regexp.new(resource[:after]) - count = count_matches(regex) + after_regex = new_after_regex + after_count = count_matches(after_regex) - if count > 1 && resource[:multiple].to_s != 'true' - raise Puppet::Error, "#{count} lines match pattern '#{resource[:after]}' in file '#{resource[:path]}'. One or no line must match the pattern." + if after_count > 1 && resource[:multiple].to_s != 'true' + raise Puppet::Error, "#{after_count} lines match pattern '#{resource[:after]}' in file '#{resource[:path]}'. One or no line must match the pattern." end File.open(resource[:path], 'w') do |fh| - lines.each do |l| - fh.puts(l) - if regex.match(l) then - fh.puts(resource[:line]) - end + lines.each do |line| + fh.puts(line) + fh.puts(resource[:line]) if after_regex.match(line) end - end - if (count == 0) # append the line to the end of the file - append_line + fh.puts(resource[:line]) if after_count.zero? end end - def count_matches(regex) - lines.select{|l| l.match(regex)}.size - end - def handle_destroy_with_match + match_regex = new_match_regex match_count = count_matches(match_regex) - if match_count > 1 && resource[:multiple].to_s != 'true' - raise Puppet::Error, "More than one line in file '#{resource[:path]}' matches pattern '#{resource[:match]}'" - end + raise Puppet::Error, "More than one line in file '#{resource[:path]}' matches pattern '#{resource[:match]}'" if match_count > 1 && resource[:multiple].to_s != 'true' local_lines = lines - File.open(resource[:path],'w') do |fh| - fh.write(local_lines.reject{|l| match_regex.match(l) }.join('')) - end + File.write(resource[:path], local_lines.reject { |line| match_regex.match(line) }.join) end def handle_destroy_line local_lines = lines - File.open(resource[:path],'w') do |fh| - fh.write(local_lines.reject{|l| l.chomp == resource[:line] }.join('')) - end + File.write(resource[:path], local_lines.reject { |line| line.chomp == resource[:line] }.join) end - ## - # append the line to the file. - # - # @api private - def append_line + def handle_append_line + local_lines = lines File.open(resource[:path], 'w') do |fh| - lines.each do |l| - fh.puts(l) + local_lines.each do |line| + fh.puts(line) end - fh.puts resource[:line] + fh.puts(resource[:line]) end end end diff --git a/lib/puppet/type/anchor.rb b/lib/puppet/type/anchor.rb index fe1e5aa19..64a111e49 100644 --- a/lib/puppet/type/anchor.rb +++ b/lib/puppet/type/anchor.rb @@ -1,6 +1,11 @@ +# frozen_string_literal: true + Puppet::Type.newtype(:anchor) do - desc <<-'ENDOFDESC' - A simple resource type intended to be used as an anchor in a composite class. + desc <<-DOC + @summary + A simple resource type intended to be used as an anchor in a composite class. + + > Note: this has been replaced by core puppet `contain()` method. Please see https://puppet.com/docs/puppet/latest/lang_containment.html for more information. In Puppet 2.6, when a class declares another class, the resources in the interior class are not contained by the exterior class. This interacts badly @@ -12,32 +17,35 @@ classes between two no-op resources that _are_ contained by the exterior class, you can ensure that all resources in the module are contained. - class ntp { - # These classes will have the correct order relationship with each - # other. However, without anchors, they won't have any order - # relationship to Class['ntp']. - class { 'ntp::package': } - -> class { 'ntp::config': } - -> class { 'ntp::service': } - - # These two resources "anchor" the composed classes within the ntp - # class. - anchor { 'ntp::begin': } -> Class['ntp::package'] - Class['ntp::service'] -> anchor { 'ntp::end': } - } + ``` + class ntp { + # These classes will have the correct order relationship with each + # other. However, without anchors, they won't have any order + # relationship to Class['ntp']. + class { 'ntp::package': } + -> class { 'ntp::config': } + -> class { 'ntp::service': } + + # These two resources "anchor" the composed classes within the ntp + # class. + anchor { 'ntp::begin': } -> Class['ntp::package'] + Class['ntp::service'] -> anchor { 'ntp::end': } + } + ``` This allows the end user of the ntp module to establish require and before relationships with Class['ntp']: - class { 'ntp': } -> class { 'mcollective': } - class { 'mcollective': } -> class { 'ntp': } + ``` + class { 'ntp': } -> class { 'mcollective': } + class { 'mcollective': } -> class { 'ntp': } + ``` - ENDOFDESC + DOC newparam :name do - desc "The name of the anchor resource." + desc 'The name of the anchor resource.' end - def refresh # We don't do anything with them, but we need this to # show that we are "refresh aware" and not break the diff --git a/lib/puppet/type/file_line.rb b/lib/puppet/type/file_line.rb index 77d3be261..bcb74f3fa 100644 --- a/lib/puppet/type/file_line.rb +++ b/lib/puppet/type/file_line.rb @@ -1,101 +1,158 @@ -Puppet::Type.newtype(:file_line) do - - desc <<-EOT - Ensures that a given line is contained within a file. The implementation - matches the full line, including whitespace at the beginning and end. If - the line is not contained in the given file, Puppet will append the line to - the end of the file to ensure the desired state. Multiple resources may - be declared to manage multiple lines in the same file. - - Example: - - file_line { 'sudo_rule': - path => '/etc/sudoers', - line => '%sudo ALL=(ALL) ALL', - } - - file_line { 'sudo_rule_nopw': - path => '/etc/sudoers', - line => '%sudonopw ALL=(ALL) NOPASSWD: ALL', - } +# frozen_string_literal: true +Puppet::Type.newtype(:file_line) do + desc <<-DOC + @summary + Ensures that a given line is contained within a file. + + The implementation matches the full line, including whitespace at the + beginning and end. If the line is not contained in the given file, Puppet + will append the line to the end of the file to ensure the desired state. + Multiple resources may be declared to manage multiple lines in the same file. + + * Ensure Example + ``` + file_line { 'sudo_rule': + path => '/etc/sudoers', + line => '%sudo ALL=(ALL) ALL', + } + + file_line { 'sudo_rule_nopw': + path => '/etc/sudoers', + line => '%sudonopw ALL=(ALL) NOPASSWD: ALL', + } + ``` In this example, Puppet will ensure both of the specified lines are contained in the file /etc/sudoers. - Match Example: + * Match Example - file_line { 'bashrc_proxy': - ensure => present, - path => '/etc/bashrc', - line => 'export HTTP_PROXY=http://squid.puppetlabs.vm:3128', - match => '^export\ HTTP_PROXY\=', - } + ``` + file_line { 'bashrc_proxy': + ensure => present, + path => '/etc/bashrc', + line => 'export HTTP_PROXY=http://squid.puppetlabs.vm:3128', + match => '^export HTTP_PROXY=', + } + ``` In this code example match will look for a line beginning with export followed by HTTP_PROXY and replace it with the value in line. - Match Example With `ensure => absent`: + * Examples With `ensure => absent`: + + This type has two behaviors when `ensure => absent` is set. - file_line { 'bashrc_proxy': - ensure => absent, - path => '/etc/bashrc', - line => 'export HTTP_PROXY=http://squid.puppetlabs.vm:3128', - match => '^export\ HTTP_PROXY\=', - match_for_absence => true, - } + One possibility is to set `match => ...` and `match_for_absence => true`, + as in the following example: + + ``` + file_line { 'bashrc_proxy': + ensure => absent, + path => '/etc/bashrc', + match => '^export HTTP_PROXY=', + match_for_absence => true, + } + ``` In this code example match will look for a line beginning with export followed by HTTP_PROXY and delete it. If multiple lines match, an error will be raised unless the `multiple => true` parameter is set. + Note that the `line => ...` parameter would be accepted BUT IGNORED in + the above example. + + The second way of using `ensure => absent` is to specify a `line => ...`, + and no match: + + ``` + file_line { 'bashrc_proxy': + ensure => absent, + path => '/etc/bashrc', + line => 'export HTTP_PROXY=http://squid.puppetlabs.vm:3128', + } + ``` + + > *Note:* + When ensuring lines are absent this way, the default behavior + this time is to always remove all lines matching, and this behavior + can't be disabled. + + * Encoding example: + + ``` + file_line { "XScreenSaver": + ensure => present, + path => '/root/XScreenSaver', + line => "*lock: 10:00:00", + match => '^*lock:', + encoding => "iso-8859-1", + } + ``` + + Files with special characters that are not valid UTF-8 will give the + error message "invalid byte sequence in UTF-8". In this case, determine + the correct file encoding and specify the correct encoding using the + encoding attribute, the value of which needs to be a valid Ruby character + encoding. + **Autorequires:** If Puppet is managing the file that will contain the line being managed, the file_line resource will autorequire that file. - EOT + DOC ensurable do + desc 'Manage the state of this type.' defaultvalues defaultto :present end - newparam(:name, :namevar => true) do + newparam(:name, namevar: true) do desc 'An arbitrary name used as the identity of the resource.' end newparam(:match) do - desc 'An optional ruby regular expression to run against existing lines in the file.' + - ' If a match is found, we replace that line rather than adding a new line.' + - ' A regex comparison is performed against the line value and if it does not' + - ' match an exception will be raised.' + desc 'An optional ruby regular expression to run against existing lines in the file. + If a match is found, we replace that line rather than adding a new line. + A regex comparison is performed against the line value and if it does not + match an exception will be raised.' end newparam(:match_for_absence) do - desc 'An optional value to determine if match should be applied when ensure => absent.' + - ' If set to true and match is set, the line that matches match will be deleted.' + - ' If set to false (the default), match is ignored when ensure => absent.' + desc 'An optional value to determine if match should be applied when ensure => absent. + If set to true and match is set, the line that matches match will be deleted. + If set to false (the default), match is ignored when ensure => absent. + When `ensure => present`, match_for_absence is ignored.' newvalues(true, false) defaultto false end newparam(:multiple) do - desc 'An optional value to determine if match can change multiple lines.' + - ' If set to false, an exception will be raised if more than one line matches' + desc 'An optional value to determine if match can change multiple lines. + If set to false, an exception will be raised if more than one line matches' newvalues(true, false) end newparam(:after) do - desc 'An optional value used to specify the line after which we will add any new lines. (Existing lines are added in place)' + desc 'An optional value used to specify the line after which we will add any new lines. (Existing lines are added in place) + This is also takes a regex.' end - newparam(:line) do + # The line property never changes; the type only ever performs a create() or + # destroy(). line is a property in order to allow it to correctly handle + # Sensitive type values. Because it is a property which will never change, + # it should never be considered out of sync. + newproperty(:line) do desc 'The line to be appended to the file or used to replace matches found by the match attribute.' + + def retrieve + @resource[:line] + end end newparam(:path) do desc 'The file Puppet will ensure contains the line specified by the line parameter.' validate do |value| - unless (Puppet.features.posix? and value =~ /^\//) or (Puppet.features.microsoft_windows? and (value =~ /^.:\// or value =~ /^\/\/[^\/]+\/[^\/]+/)) - raise(Puppet::Error, "File paths must be fully qualified, not '#{value}'") - end + raise Puppet::Error, "File paths must be fully qualified, not '#{value}'" unless Puppet::Util.absolute_path?(value) end end @@ -105,14 +162,33 @@ defaultto true end + newparam(:replace_all_matches_not_matching_line) do + desc 'Configures the behavior of replacing all lines in a file which match the `match` parameter regular expression, regardless of whether the specified line is already present in the file.' + + newvalues(true, false) + defaultto false + end + + newparam(:encoding) do + desc 'For files that are not UTF-8 encoded, specify encoding such as iso-8859-1' + defaultto 'UTF-8' + end + + newparam(:append_on_no_match) do + desc 'If true, append line if match is not found. If false, do not append line if a match is not found' + newvalues(true, false) + defaultto true + end + # Autorequire the file resource if it's being managed autorequire(:file) do self[:path] end - validate do - unless self[:line] and self[:path] - raise(Puppet::Error, "Both line and path are required attributes") - end + raise(Puppet::Error, 'multiple must be true when replace_all_matches_not_matching_line is true') if self[:replace_all_matches_not_matching_line].to_s == 'true' && self[:multiple].to_s == 'false' + raise(Puppet::Error, 'replace must be true when replace_all_matches_not_matching_line is true') if self[:replace_all_matches_not_matching_line].to_s == 'true' && self[:replace].to_s == 'false' + + raise(Puppet::Error, 'line is a required attribute') if !self[:line] && !((self[:ensure].to_s == 'absent') && (self[:match_for_absence].to_s == 'true') && self[:match]) + raise(Puppet::Error, 'path is a required attribute') unless self[:path] end end diff --git a/lib/puppet_x/stdlib.rb b/lib/puppet_x/stdlib.rb new file mode 100644 index 000000000..dbbe7cbc1 --- /dev/null +++ b/lib/puppet_x/stdlib.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +require 'puppet_x' + +# common PuppetX::Stdlib module definition +module PuppetX::Stdlib; end diff --git a/lib/puppet_x/stdlib/toml_dumper.rb b/lib/puppet_x/stdlib/toml_dumper.rb new file mode 100644 index 000000000..e287bc1cc --- /dev/null +++ b/lib/puppet_x/stdlib/toml_dumper.rb @@ -0,0 +1,135 @@ +# The MIT License (MIT) +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +require_relative '../../puppet_x/stdlib' +require 'date' + +# The Dumper class was blindly copied from https://github.com/emancu/toml-rb/blob/v2.0.1/lib/toml-rb/dumper.rb +# This allows us to use the `to_toml` function as a `Deferred` function because the `toml-rb` gem is usually +# installed on the agent and the `Deferred` function gets evaluated before the catalog gets applied. This +# makes it in most scenarios impossible to install the gem before it is used. +class PuppetX::Stdlib::TomlDumper + attr_reader :toml_str + + def initialize(hash) + @toml_str = '' + + visit(hash, []) + end + + private + + def visit(hash, prefix, extra_brackets = false) + simple_pairs, nested_pairs, table_array_pairs = sort_pairs hash + + print_prefix prefix, extra_brackets if prefix.any? && (simple_pairs.any? || hash.empty?) + + dump_pairs simple_pairs, nested_pairs, table_array_pairs, prefix + end + + def sort_pairs(hash) + nested_pairs = [] + simple_pairs = [] + table_array_pairs = [] + + hash.keys.sort.each do |key| + val = hash[key] + element = [key, val] + + if val.is_a? Hash + nested_pairs << element + elsif val.is_a?(Array) && val.first.is_a?(Hash) + table_array_pairs << element + else + simple_pairs << element + end + end + + [simple_pairs, nested_pairs, table_array_pairs] + end + + def dump_pairs(simple, nested, table_array, prefix = []) + # First add simple pairs, under the prefix + dump_simple_pairs simple + dump_nested_pairs nested, prefix + dump_table_array_pairs table_array, prefix + end + + def dump_simple_pairs(simple_pairs) + simple_pairs.each do |key, val| + key = quote_key(key) unless bare_key? key + @toml_str << "#{key} = #{to_toml(val)}\n" + end + end + + def dump_nested_pairs(nested_pairs, prefix) + nested_pairs.each do |key, val| + key = quote_key(key) unless bare_key? key + + visit val, prefix + [key], false + end + end + + def dump_table_array_pairs(table_array_pairs, prefix) + table_array_pairs.each do |key, val| + key = quote_key(key) unless bare_key? key + aux_prefix = prefix + [key] + + val.each do |child| + print_prefix aux_prefix, true + args = sort_pairs(child) << aux_prefix + + dump_pairs(*args) + end + end + end + + def print_prefix(prefix, extra_brackets = false) + new_prefix = prefix.join('.') + new_prefix = "[#{new_prefix}]" if extra_brackets + + @toml_str += "[#{new_prefix}]\n" + end + + def to_toml(obj) + case obj + when Time, DateTime + obj.strftime('%Y-%m-%dT%H:%M:%SZ') + when Date + obj.strftime('%Y-%m-%d') + when Regexp + obj.inspect.inspect + when String + obj.inspect.gsub(/\\(#[$@{])/, '\1') # rubocop:disable Style/RegexpLiteral + else + obj.inspect + end + end + + def bare_key?(key) + # rubocop:disable Style/RegexpLiteral + !!key.to_s.match(/^[a-zA-Z0-9_-]*$/) + # rubocop:enable Style/RegexpLiteral + end + + def quote_key(key) + "\"#{key.gsub('"', '\\"')}\"" + end +end diff --git a/manifests/init.pp b/manifests/init.pp index 9ea22a737..987c6d8e3 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -1,18 +1,13 @@ -# Class: stdlib -# -# This module manages stdlib. Most of stdlib's features are automatically -# loaded by Puppet, but this class should be declared in order to use the -# standardized run stages. -# -# Parameters: none -# -# Actions: -# -# Declares all other classes in the stdlib module. Currently, this consists -# of stdlib::stages. -# -# Requires: nothing +# @summary +# This module manages stdlib. +# +# Most of stdlib's features are automatically loaded by Puppet, but this class should be +# declared in order to use the standardized run stages. +# +# Declares all other classes in the stdlib module. Currently, this consists +# of stdlib::stages and stdlib::manage. # class stdlib { - include ::stdlib::stages + include stdlib::manage + include stdlib::stages } diff --git a/manifests/manage.pp b/manifests/manage.pp new file mode 100644 index 000000000..82c39bc8d --- /dev/null +++ b/manifests/manage.pp @@ -0,0 +1,118 @@ +# @summary A simple place to define trivial resources +# +# Sometimes your systems require a single simple resource. +# It can feel unnecessary to create a module for a single +# resource. There are a number of possible patterns to +# generate trivial resource definitions. This is an attempt +# to create a single clear method for uncomplicated resources. +# There is __limited__ support for `before`, `require`, `notify`, +# and `subscribe`. +# +# @param create_resources +# A hash of resources to create +# NOTE: functions, such as `template` or `epp`, are not directly evaluated +# but processed as Puppet code based on epp and erb hash keys. +# +# @example +# class { 'stdlib::manage': +# 'create_resources' => { +# 'file' => { +# '/etc/motd.d/hello' => { +# 'content' => 'I say Hi', +# 'notify' => 'Service[sshd]', +# }, +# '/etc/motd' => { +# 'ensure' => 'file', +# 'epp' => { +# 'template' => 'profile/motd.epp', +# } +# }, +# '/etc/information' => { +# 'ensure' => 'file', +# 'erb' => { +# 'template' => 'profile/informaiton.erb', +# } +# } +# }, +# 'package' => { +# 'example' => { +# 'ensure' => 'installed', +# 'subscribe' => ['Service[sshd]', 'Exec[something]'], +# } +# } +# } +# } +# +# @example +# stdlib::manage::create_resources: +# file: +# '/etc/motd.d/hello': +# content: I say Hi +# notify: 'Service[sshd]' +# '/etc/motd': +# ensure: 'file' +# epp: +# template: 'profile/motd.epp' +# context: {} +# '/etc/information': +# ensure: 'file' +# erb: +# template: 'profile/information.erb' +# package: +# example: +# ensure: installed +# subscribe: +# - 'Service[sshd]' +# - 'Exec[something]' +class stdlib::manage ( + Hash[String, Hash] $create_resources = {} +) { + $create_resources.each |$type, $resources| { + $resources.each |$title, $attributes| { + case $type { + 'file': { + # sanity checks + # epp, erb and content are exclusive + if 'epp' in $attributes and 'content' in $attributes { + fail("You can not set 'epp' and 'content' for file ${title}") + } + if 'erb' in $attributes and 'content' in $attributes { + fail("You can not set 'erb' and 'content' for file ${title}") + } + if 'erb' in $attributes and 'epp' in $attributes { + fail("You can not set 'erb' and 'epp' for file ${title}") + } + + if 'epp' in $attributes { + if 'template' in $attributes['epp'] { + if 'context' in $attributes['epp'] { + $content = epp($attributes['epp']['template'], $attributes['epp']['context']) + } else { + $content = epp($attributes['epp']['template']) + } + } else { + fail("No template configured for epp for file ${title}") + } + } elsif 'erb' in $attributes { + if 'template' in $attributes['erb'] { + $content = template($attributes['erb']['template']) + } else { + fail("No template configured for erb for file ${title}") + } + } elsif 'content' in $attributes { + $content = $attributes['content'] + } else { + $content = undef + } + file { $title: + * => $attributes - 'erb' - 'epp' - 'content', + content => $content, + } + } + default: { + create_resources($type, { $title => $attributes }) + } + } + } + } +} diff --git a/manifests/stages.pp b/manifests/stages.pp index 7de254c71..0ebf596be 100644 --- a/manifests/stages.pp +++ b/manifests/stages.pp @@ -1,10 +1,11 @@ -# Class: stdlib::stages -# -# This class manages a standard set of run stages for Puppet. It is managed by -# the stdlib class, and should not be declared independently. +# @summary +# This class manages a standard set of run stages for Puppet. It is managed by +# the stdlib class, and should not be declared independently. # +# Declares various run-stages for deploying infrastructure, +# language runtimes, and application layers. +# # The high level stages are (in order): -# # * setup # * main # * runtime @@ -14,24 +15,13 @@ # * deploy_app # * deploy # -# Parameters: none -# -# Actions: -# -# Declares various run-stages for deploying infrastructure, -# language runtimes, and application layers. -# -# Requires: nothing -# -# Sample Usage: -# -# node default { -# include ::stdlib -# class { java: stage => 'runtime' } -# } +# @example +# node default { +# include ::stdlib +# class { java: stage => 'runtime' } +# } # class stdlib::stages { - stage { 'setup': before => Stage['main'] } stage { 'runtime': require => Stage['main'] } -> stage { 'setup_infra': } @@ -39,5 +29,4 @@ -> stage { 'setup_app': } -> stage { 'deploy_app': } -> stage { 'deploy': } - } diff --git a/metadata.json b/metadata.json index dab84e568..c997c0457 100644 --- a/metadata.json +++ b/metadata.json @@ -1,114 +1,119 @@ { "name": "puppetlabs-stdlib", - "version": "4.8.0", + "version": "9.7.0", "author": "puppetlabs", "summary": "Standard library of resources for Puppet modules.", "license": "Apache-2.0", "source": "https://github.com/puppetlabs/puppetlabs-stdlib", "project_page": "https://github.com/puppetlabs/puppetlabs-stdlib", - "issues_url": "https://tickets.puppetlabs.com/browse/MODULES", + "issues_url": "https://github.com/puppetlabs/puppetlabs-stdlib/issues", + "dependencies": [ + + ], "operatingsystem_support": [ { "operatingsystem": "RedHat", "operatingsystemrelease": [ - "4", - "5", - "6", - "7" + "7", + "8", + "9" ] }, { "operatingsystem": "CentOS", "operatingsystemrelease": [ - "4", - "5", - "6", - "7" + "7", + "8" ] }, { "operatingsystem": "OracleLinux", "operatingsystemrelease": [ - "4", - "5", - "6", "7" ] }, { "operatingsystem": "Scientific", "operatingsystemrelease": [ - "4", - "5", - "6", "7" ] }, { "operatingsystem": "SLES", "operatingsystemrelease": [ - "10 SP4", - "11 SP1", - "12" + "12", + "15" ] }, { "operatingsystem": "Debian", "operatingsystemrelease": [ - "6", - "7" + "10", + "11", + "12" ] }, { "operatingsystem": "Ubuntu", "operatingsystemrelease": [ - "10.04", - "12.04", - "14.04" + "18.04", + "20.04", + "22.04", + "24.04" ] }, { "operatingsystem": "Solaris", "operatingsystemrelease": [ - "10", - "11", - "12" + "11" ] }, { "operatingsystem": "Windows", "operatingsystemrelease": [ - "Server 2003", - "Server 2003 R2", - "Server 2008", - "Server 2008 R2", - "Server 2012", - "Server 2012 R2", - "7", - "8" + "10", + "2012", + "2012 R2", + "2016", + "2019", + "2022" ] }, { "operatingsystem": "AIX", "operatingsystemrelease": [ - "5.3", - "6.1", - "7.1" + "7.1", + "7.2" + ] + }, + { + "operatingsystem": "Rocky", + "operatingsystemrelease": [ + "8" + ] + }, + { + "operatingsystem": "AlmaLinux", + "operatingsystemrelease": [ + "8" + ] + }, + { + "operatingsystem": "AmazonLinux", + "operatingsystemrelease": [ + "2", + "2023" ] } ], "requirements": [ - { - "name": "pe", - "version_requirement": "3.x" - }, { "name": "puppet", - "version_requirement": ">=2.7.20 <5.0.0" + "version_requirement": ">= 8.0.0 < 9.0.0" } ], "description": "Standard Library for Puppet Modules", - "dependencies": [ - - ] + "pdk-version": "3.5.0", + "template-url": "https://github.com/puppetlabs/pdk-templates#main", + "template-ref": "heads/main-0-g11c0f3d" } diff --git a/pdk.yaml b/pdk.yaml new file mode 100644 index 000000000..4bef4bd0f --- /dev/null +++ b/pdk.yaml @@ -0,0 +1,2 @@ +--- +ignore: [] diff --git a/provision.yaml b/provision.yaml new file mode 100644 index 000000000..4df54fcee --- /dev/null +++ b/provision.yaml @@ -0,0 +1,84 @@ +--- +default: + provisioner: docker + images: + - litmusimage/centos:7 +vagrant: + provisioner: vagrant + images: + - centos/7 + - generic/ubuntu1804 + - gusztavvargadr/windows-server +docker_deb: + provisioner: docker + images: + - litmusimage/debian:8 + - litmusimage/debian:9 + - litmusimage/debian:10 +docker_ub_6: + provisioner: docker + images: + - litmusimage/ubuntu:14.04 + - litmusimage/ubuntu:16.04 + - litmusimage/ubuntu:18.04 + - litmusimage/ubuntu:20.04 +docker_el7: + provisioner: docker + images: + - litmusimage/centos:7 + - litmusimage/oraclelinux:7 + - litmusimage/scientificlinux:7 +docker_el8: + provisioner: docker + images: + - litmusimage/centos:8 +release_checks_6: + provisioner: abs + images: + - redhat-6-x86_64 + - redhat-7-x86_64 + - redhat-8-x86_64 + - centos-6-x86_64 + - centos-7-x86_64 + - centos-8-x86_64 + - oracle-5-x86_64 + - oracle-6-x86_64 + - oracle-7-x86_64 + - scientific-6-x86_64 + - scientific-7-x86_64 + - debian-8-x86_64 + - debian-9-x86_64 + - debian-10-x86_64 + - sles-12-x86_64 + - ubuntu-1404-x86_64 + - ubuntu-1604-x86_64 + - ubuntu-1804-x86_64 + - ubuntu-2004-x86_64 + - win-2008-x86_64 + - win-2008r2-x86_64 + - win-2012-x86_64 + - win-2012r2-x86_64 + - win-2016-x86_64 + - win-2019-x86_64 + - win-7-x86_64 + - win-81-x86_64 + - win-10-pro-x86_64 +release_checks_7: + provisioner: abs + images: + - redhat-7-x86_64 + - redhat-8-x86_64 + - centos-7-x86_64 + - centos-8-x86_64 + - oracle-7-x86_64 + - scientific-7-x86_64 + - sles-12-x86_64 + - sles-15-x86_64 + - debian-9-x86_64 + - debian-10-x86_64 + - ubuntu-1804-x86_64 + - ubuntu-2004-x86_64 + - win-2012r2-x86_64 + - win-2016-x86_64 + - win-2019-x86_64 + - win-10-pro-x86_64 diff --git a/readmes/README_ja_JP.md b/readmes/README_ja_JP.md new file mode 100644 index 000000000..d1d514001 --- /dev/null +++ b/readmes/README_ja_JP.md @@ -0,0 +1,3135 @@ +# stdlib + +#### 目欔 + +1. [čŖ¬ę˜Ž - ćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ć®ę©Ÿčƒ½ćØćć®ęœ‰ē›Šę€§](#module-description) +1. [ć‚»ćƒƒćƒˆć‚¢ćƒƒćƒ— - stdlibå°Žå…„ć®åŸŗęœ¬](#setup) +1. [使用方法 - čØ­å®šć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ćØčæ½åŠ ę©Ÿčƒ½](#usage) +1. [å‚č€ƒ - ćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ć®ę©Ÿčƒ½ćØå‹•ä½œć«ć¤ć„ć¦](#reference) + 1. [ć‚Æćƒ©ć‚¹](#classes) + 1. [å®šē¾©ć§ćć‚‹ć‚æć‚¤ćƒ—](#defined-types) + 1. [ćƒ‡ćƒ¼ć‚æć‚æć‚¤ćƒ—](#data-types) + 1. [Facts](#facts) + 1. [関数](#functions) +1. [åˆ¶ē“„äŗ‹é … - OSć®äŗ’ę›ę€§ćŖć©](#limitations) +1. [開発 - ćƒ¢ć‚øćƒ„ćƒ¼ćƒ«č²¢ēŒ®ć«ć¤ć„ć¦ć®ć‚¬ć‚¤ćƒ‰](#development) +1. [ć‚³ćƒ³ćƒˆćƒŖćƒ“ćƒ„ćƒ¼ć‚æ](#contributors) + + +## ćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ć®ę¦‚č¦ + +ć“ć®ćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ć§ćÆć€Puppetćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ćƒŖć‚½ćƒ¼ć‚¹ć®ęØ™ęŗ–ćƒ©ć‚¤ćƒ–ćƒ©ćƒŖć‚’ęä¾›ć—ć¦ć„ć¾ć™ć€‚Puppetćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ć§ćÆć€ć“ć®ęØ™ęŗ–ćƒ©ć‚¤ćƒ–ćƒ©ćƒŖć‚’åŗƒćä½æē”Øć—ć¦ć„ć¾ć™ć€‚stdlibćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ćÆć€ä»„äø‹ć®ćƒŖć‚½ćƒ¼ć‚¹ć‚’Puppetć«čæ½åŠ ć—ć¾ć™ć€‚ + + * ć‚¹ćƒ†ćƒ¼ć‚ø + * Facts + * 関数 + * å®šē¾©ć•ć‚ŒćŸåž‹ + * ćƒ‡ćƒ¼ć‚æć‚æć‚¤ćƒ— + * 惗惭惐悤惀 + +> *注:* ćƒćƒ¼ć‚øćƒ§ćƒ³3.7恮Puppet Enterpriseには、stdlibćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ćŒå«ć¾ć‚Œć¦ć„ć¾ć›ć‚“ć€‚Puppet Enterpriseć‚’ä½æē”Øć—ć¦ć„ć‚‹å “åˆćÆć€PuppetćØäŗ’ę›ę€§ć®ć‚ć‚‹stdlibć®ęœ€ę–°ćƒŖćƒŖćƒ¼ć‚¹ć‚’ć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ«ć™ć‚‹åæ…č¦ćŒć‚ć‚Šć¾ć™ć€‚ + +## ć‚»ćƒƒćƒˆć‚¢ćƒƒćƒ— + +stdlibćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ć‚’[ć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ«](https://puppet.com/docs/puppet/latest/modules_installing.html)ć—ć€ć“ć®ęØ™ęŗ–ćƒ©ć‚¤ćƒ–ćƒ©ćƒŖć®é–¢ę•°ć€Factsć€ćƒŖć‚½ćƒ¼ć‚¹ć‚’Puppetć«čæ½åŠ ć—ć¾ć™ć€‚ + +stdlibć«ä¾å­˜ć™ć‚‹ćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ć‚’čØ˜čæ°ć™ć‚‹å “åˆćÆć€åæ…ćšmetadata.json恧[ä¾å­˜é–¢äæ‚ć‚’ē‰¹å®š](https://puppet.com/docs/puppet/latest/modules_metadata.html#specifying-dependencies-in-modules)ć—ć¦ćć ć•ć„ć€‚ + +## 使用方法 + +stdlibć®ć»ćØć‚“ć©ć®ę©Ÿčƒ½ćÆć€Puppetć«č‡Ŗå‹•ēš„ć«ćƒ­ćƒ¼ćƒ‰ć•ć‚Œć¾ć™ć€‚Puppetć§ęØ™ęŗ–åŒ–ć•ć‚ŒćŸćƒ©ćƒ³ć‚¹ćƒ†ćƒ¼ć‚øć‚’ä½æē”Øć™ć‚‹ć«ćÆć€`include stdlib`ć‚’ē”Øć„ć¦ćƒžćƒ‹ćƒ•ć‚§ć‚¹ćƒˆå†…ć§ć“ć®ć‚Æćƒ©ć‚¹ć‚’å®£čØ€ć—ć¦ćć ć•ć„ć€‚ + +宣言すると、stdlibćŒćƒ¢ć‚øćƒ„ćƒ¼ćƒ«å†…ć®ä»–ć®ć™ć¹ć¦ć®ć‚Æćƒ©ć‚¹ć‚’å®£čØ€ć—ć¾ć™ć€‚ē¾åœØćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ć«å«ć¾ć‚Œć¦ć„ć‚‹ä»–ć®ć‚Æćƒ©ć‚¹ćÆć€`stdlib::stages`のみです。 + +`stdlib::stages`ć‚Æćƒ©ć‚¹ćÆć€ć‚¤ćƒ³ćƒ•ćƒ©ć‚¹ćƒˆćƒ©ć‚Æćƒćƒ£ć€čØ€čŖžćƒ©ćƒ³ć‚æć‚¤ćƒ ć€ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ćƒ¬ć‚¤ćƒ¤ć®é…å‚™ć«é–¢ć™ć‚‹å„ēØ®ć®ćƒ©ćƒ³ć‚¹ćƒ†ćƒ¼ć‚øć‚’å®£čØ€ć—ć¾ć™ć€‚ćƒć‚¤ćƒ¬ćƒ™ćƒ«ć‚¹ćƒ†ćƒ¼ć‚øćÆć€ä»„äø‹ć®ćØćŠć‚Šć§ć™(é †ē•Ŗć©ćŠć‚Š)怂 + + * ć‚»ćƒƒćƒˆć‚¢ćƒƒćƒ— + * main + * runtime + * setup_infra + * deploy_infra + * setup_app + * deploy_app + * deploy + +使用例: + +```puppet +node default { + include stdlib + class { java: stage => 'runtime' } +} +``` + +## ćƒŖćƒ•ć‚”ćƒ¬ćƒ³ć‚¹ + +* [ćƒ‘ćƒ–ćƒŖćƒƒć‚Æć‚Æćƒ©ć‚¹](#public-classes) +* [ćƒ—ćƒ©ć‚¤ćƒ™ćƒ¼ćƒˆć‚Æćƒ©ć‚¹](#private-classes) +* [å®šē¾©ć•ć‚ŒćŸåž‹](#defined-types) +* [ćƒ‡ćƒ¼ć‚æć‚æć‚¤ćƒ—](#data-types) +* [Facts](#facts) +* [関数](#functions) + +### ć‚Æćƒ©ć‚¹ + +#### ćƒ‘ćƒ–ćƒŖćƒƒć‚Æć‚Æćƒ©ć‚¹ + +`stdlib`ć‚Æćƒ©ć‚¹ć«ćÆćƒ‘ćƒ©ćƒ”ćƒ¼ć‚æćÆć‚ć‚Šć¾ć›ć‚“ć€‚ + +#### ćƒ—ćƒ©ć‚¤ćƒ™ćƒ¼ćƒˆć‚Æćƒ©ć‚¹ + +* `stdlib::stages`: Puppetć®ćƒ©ćƒ³ć‚¹ćƒ†ćƒ¼ć‚øć®ęØ™ęŗ–ć‚»ćƒƒćƒˆć‚’ē®”ē†ć—ć¾ć™ć€‚ + +### å®šē¾©ć•ć‚ŒćŸåž‹ + +#### `file_line` + +ä»»ę„ć®č”ŒćŒćƒ•ć‚”ć‚¤ćƒ«å†…ć«ē¢ŗå®Ÿć«å«ć¾ć‚Œć‚‹ć‚ˆć†ć«ć—ć¾ć™ć€‚ęœ€åˆćØęœ€å¾Œć®ē©ŗē™½ć‚’å«ć‚ć€č”Œå…Øä½“ć‚’ćƒžćƒƒćƒć•ć›ć¾ć™ć€‚ćć®č”ŒćŒäøŽćˆć‚‰ć‚ŒćŸćƒ•ć‚”ć‚¤ćƒ«ć«å«ć¾ć‚ŒćŖć„å “åˆćÆć€PuppetćŒćƒ•ć‚”ć‚¤ćƒ«ć®ęœ€å¾Œć«ćć®č”Œć‚’čæ½åŠ ć—ć€ęœ›ć¾ć—ć„ēŠ¶ę…‹ć‚’ē¢ŗäæć—ć¾ć™ć€‚1ć¤ć®ćƒ•ć‚”ć‚¤ćƒ«å†…ć§č¤‡ę•°ć®ćƒŖć‚½ćƒ¼ć‚¹ć‚’å®£čØ€ć—ć€č¤‡ę•°ć®č”Œć‚’ē®”ē†ć™ć‚‹ć“ćØćŒåÆčƒ½ć§ć™ć€‚ + +例: + +```puppet +file_line { 'sudo_rule': + path => '/etc/sudoers', + line => '%sudo ALL=(ALL) ALL', +} + +file_line { 'sudo_rule_nopw': + path => '/etc/sudoers', + line => '%sudonopw ALL=(ALL) NOPASSWD: ALL', +} +``` + +äøŠć®ä¾‹ć§ćÆć€ęŒ‡å®šć•ć‚ŒćŸäø”ę–¹ć®č”ŒćŒć€ćƒ•ć‚”ć‚¤ćƒ« `/etc/sudoers`ć«ē¢ŗå®Ÿć«å«ć¾ć‚Œć¾ć™ć€‚ + +ćƒžćƒƒćƒä¾‹: + +```puppet +file_line { 'bashrc_proxy': + ensure => present, + path => '/etc/bashrc', + line => 'export HTTP_PROXY=http://squid.puppetlabs.vm:3128', + match => '^export\ HTTP_PROXY\=', +} +``` + +äøŠć®ä¾‹ć§ćÆć€`match`ć«ć‚ˆć‚Šć€'export'ć§å§‹ć¾ć‚Š'HTTP_PROXY'ćØē¶šćč”ŒćŒęŽ¢ć•ć‚Œć€ćć®č”ŒćŒč”Œå†…ć®å€¤ć«ē½®ćę›ćˆć‚‰ć‚Œć¾ć™ć€‚ + +ćƒžćƒƒćƒä¾‹: + +```puppet +file_line { 'bashrc_proxy': + ensure => present, + path => '/etc/bashrc', + line => 'export HTTP_PROXY=http://squid.puppetlabs.vm:3128', + match => '^export\ HTTP_PROXY\=', + append_on_no_match => false, +} +``` + +ć“ć®ć‚³ćƒ¼ćƒ‰ć®ä¾‹ć§ćÆć€`match`ć«ć‚ˆć£ć¦exportć§å§‹ć¾ć‚Š'HTTP_PROXY'ćŒē¶šćč”ŒćŒę¤œē“¢ć•ć‚Œć€ćć®č”ŒćŒč”Œå†…ć®å€¤ć«ē½®ćę›ćˆć‚‰ć‚Œć¾ć™ć€‚ćƒžćƒƒćƒć™ć‚‹ć‚‚ć®ćŒč¦‹ć¤ć‹ć‚‰ćŖć„å “åˆć€ćƒ•ć‚”ć‚¤ćƒ«ćÆå¤‰ę›“ć•ć‚Œć¾ć›ć‚“ć€‚ + + `ensure => absent`の例: + +`ensure => absent`ć‚’čØ­å®šć™ć‚‹å “åˆć«ć€ć“ć®ć‚æć‚¤ćƒ—ć®å‹•ä½œć«ćÆ2é€šć‚ŠćŒć‚ć‚Šć¾ć™ć€‚ + +1つは`match => ...`と`match_for_absence => true`ć®čØ­å®šć§ć™ć€‚`match`ć«ć‚ˆć‚Šć€'export'ć§å§‹ć¾ć‚Š'HTTP_PROXY'ćØē¶šćč”ŒćŒęŽ¢ć•ć‚Œć€ćć®č”ŒćŒå‰Šé™¤ć•ć‚Œć¾ć™ć€‚č¤‡ę•°ć®č”ŒćŒćƒžćƒƒćƒć—ć€`multiple => true`ćƒ‘ćƒ©ćƒ”ćƒ¼ć‚æćŒčØ­å®šć•ć‚Œć¦ć„ćŖć„å “åˆćÆć€ć‚Øćƒ©ćƒ¼ćŒē”Ÿć˜ć¾ć™ć€‚ + +この例で`line => ...`ćƒ‘ćƒ©ćƒ”ćƒ¼ć‚æćÆę‰æčŖć•ć‚Œć¾ć™ćŒē„”č¦–ć•ć‚Œć¾ć™ć€‚ + +例:怀 + +```puppet +file_line { 'bashrc_proxy': + ensure => absent, + path => '/etc/bashrc', + match => '^export\ HTTP_PROXY\=', + match_for_absence => true, +} +``` + +`ensure => absent`ć‚’čØ­å®šć™ć‚‹å “åˆć®ć‚‚ć†1ć¤ć®å‹•ä½œćÆć€`line => ...`ć®ęŒ‡å®šćØäø€č‡“ćŖć—ć§ć™ć€‚č”ŒćŒå­˜åœØć—ćŖć„ć“ćØć‚’ē¢ŗčŖć—ćŸå “åˆć®ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆć®å‹•ä½œć§ćÆć€ćƒžćƒƒćƒć™ć‚‹ć™ć¹ć¦ć®č”Œć‚’å‰Šé™¤ć—ć¾ć™ć€‚ć“ć®å‹•ä½œć‚’ē„”åŠ¹ć«ć™ć‚‹ć“ćØćÆć§ćć¾ć›ć‚“ć€‚ + +例:怀 + +```puppet +file_line { 'bashrc_proxy': + ensure => absent, + path => '/etc/bashrc', + line => 'export HTTP_PROXY=http://squid.puppetlabs.vm:3128', +} +``` + + +ć‚Øćƒ³ć‚³ćƒ¼ćƒ‰ä¾‹: + +```puppet +file_line { "XScreenSaver": + ensure => present, + path => '/root/XScreenSaver' + line => "*lock: 10:00:00", + match => '^*lock:', + encoding => "iso-8859-1", +} +``` + +ćƒ•ć‚”ć‚¤ćƒ«ć«UTF-8ć«åÆ¾åæœć—ćŖć„ē‰¹ę®Šę–‡å­—ćŒē”Øć„ć‚‰ć‚Œć¦ć„ć‚‹ćØć€ć€ŒInvalid byte sequence in UTF-8怍(UTF-8ć§ē„”åŠ¹ćŖćƒć‚¤ćƒˆåˆ—)ćØć„ć†ć‚Øćƒ©ćƒ¼ćƒ”ćƒƒć‚»ćƒ¼ć‚øćŒč”Øē¤ŗć•ć‚Œć¾ć™ć€‚ć“ć®å “åˆćÆć€ćƒ•ć‚”ć‚¤ćƒ«ć‚Øćƒ³ć‚³ćƒ¼ćƒ‡ć‚£ćƒ³ć‚°ć‚’ę±ŗå®šć—ć€`encoding`å±žę€§ć§ęŒ‡å®šć—ć¦ćć ć•ć„ć€‚ + +**Autorequire:** PuppetćŒē®”ē†ć—ć¦ć„ć‚‹ćƒ•ć‚”ć‚¤ćƒ«ć«ć€ē®”ē†åÆ¾č±”ćØćŖć‚‹č”ŒćŒå«ć¾ć‚Œć¦ć„ć‚‹å “åˆćÆć€`file_line`ćƒŖć‚½ćƒ¼ć‚¹ćØå½“č©²ćƒ•ć‚”ć‚¤ćƒ«ć®ęš—é»™ēš„ćŖä¾å­˜é–¢äæ‚ćŒčØ­å®šć•ć‚Œć¾ć™ć€‚ + +**ćƒ‘ćƒ©ćƒ”ćƒ¼ć‚æ**怀 + +ćƒ‘ćƒ©ćƒ”ćƒ¼ć‚æćÆć€åˆ„é€”čŖ¬ę˜ŽćŒćŖć„é™ć‚Šć€ć™ć¹ć¦ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć§ć™ć€‚ + +##### `after` + +ć“ć®ćƒ‘ćƒ©ćƒ”ćƒ¼ć‚æć§ęŒ‡å®šć•ć‚ŒćŸč”Œć®å¾Œć«ć€PuppetćŒę­£č¦č”Øē¾ć‚’ē”Øć„ć¦ę–°č¦ć®č”Œć‚’čæ½åŠ ć—ć¾ć™(ę—¢å­˜ć®č”ŒćŒč¦å®šć®ä½ē½®ć«čæ½åŠ ć•ć‚Œć¾ć™)怂 + +値: ę­£č¦č”Øē¾ć‚’å«ć‚€ę–‡å­—åˆ— + +ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆå€¤: `undef`怂 + +##### `encoding` + +é©ę­£ćŖćƒ•ć‚”ć‚¤ćƒ«ć‚Øćƒ³ć‚³ćƒ¼ćƒ‰ć‚’ęŒ‡å®šć—ć¾ć™ć€‚ + +値: ęœ‰åŠ¹ćŖRubyę–‡å­—ć‚Øćƒ³ć‚³ćƒ¼ćƒ‰ć‚’ęŒ‡å®šć™ć‚‹ę–‡å­—åˆ— + +ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆ: 'UTF-8' + +##### `ensure`: ćƒŖć‚½ćƒ¼ć‚¹ćŒå­˜åœØć™ć‚‹ć‹ć©ć†ć‹ć‚’ęŒ‡å®šć—ć¾ć™ć€‚ + +値: 'present'态'absent' + +ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆå€¤: 'present'怂 + +##### `line` + +**åæ…é ˆ** + +`path`ćƒ‘ćƒ©ćƒ”ćƒ¼ć‚æć«ć‚ˆć‚Šä½ē½®ć‚’ē¤ŗć•ć‚ŒćŸćƒ•ć‚”ć‚¤ćƒ«ć«čæ½åŠ ć™ć‚‹č”Œć‚’čØ­å®šć—ć¾ć™ć€‚ + +値: ę–‡å­—åˆ— + +##### `match` + +ćƒ•ć‚”ć‚¤ćƒ«å†…ć®ę—¢å­˜ć®č”ŒćØęÆ”č¼ƒć™ć‚‹ę­£č¦č”Øē¾ć‚’ęŒ‡å®šć—ć¾ć™ć€‚ćƒžćƒƒćƒćŒč¦‹ć¤ć‹ć£ćŸå “åˆć€ę–°č¦ć®č”Œć‚’čæ½åŠ ć™ć‚‹ä»£ć‚ć‚Šć«ć€ē½®ćę›ćˆć‚‰ć‚Œć¾ć™ć€‚ + +値: ę­£č¦č”Øē¾ć‚’å«ć‚€ę–‡å­—åˆ— + +ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆå€¤: `undef`怂 + + +##### `match_for_absence` + +`ensure => absent`ć®å “åˆć«ćƒžćƒƒćƒć‚’é©ē”Øć™ć‚‹ć‹ć©ć†ć‹ć‚’ęŒ‡å®šć—ć¾ć™ć€‚`true`ć«čØ­å®šć—ć¦ćƒžćƒƒćƒć‚’čØ­å®šć™ć‚‹ćØć€ćƒžćƒƒćƒć™ć‚‹č”ŒćŒå‰Šé™¤ć•ć‚Œć¾ć™ć€‚`false`ć«čØ­å®šć™ć‚‹ćØ(ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆ)态`ensure => absent`ć®å “åˆć«ćƒžćƒƒćƒćŒē„”č¦–ć•ć‚Œć€ä»£ć‚ć‚Šć«`line`ć®å€¤ćŒä½æē”Øć•ć‚Œć¾ć™ć€‚`ensure => present`ć«ćŖć£ć¦ć„ć‚‹å “åˆćÆć€ć“ć®ćƒ‘ćƒ©ćƒ”ćƒ¼ć‚æćÆē„”č¦–ć•ć‚Œć¾ć™ć€‚ + +ćƒ–ćƒ¼ćƒŖć‚¢ćƒ³ć€‚ + +ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆå€¤: `false`怂 + +##### `multiple` + +`match`ćŠć‚ˆć³`after`ć«ć‚ˆć‚Šč¤‡ę•°ć®č”Œć‚’å¤‰ę›“ć§ćć‚‹ć‹ć©ć†ć‹ć‚’ęŒ‡å®šć—ć¾ć™ć€‚`false`ć«čØ­å®šć™ć‚‹ćØć€file_lineは1ć¤ć®č”Œć®ćæē½®ćę›ćˆć‚‹ć“ćØćŒć§ćć¾ć™ćŒć€č¤‡ę•°ć®č”Œć‚’ē½®ćę›ćˆć‚ˆć†ćØć™ć‚‹ćØć‚Øćƒ©ćƒ¼ćŒē™ŗē”Ÿć—ć¾ć™ć€‚`true`ć«čØ­å®šć™ć‚‹ćØć€file_lineは1ć¤ć¾ćŸćÆč¤‡ę•°ć®č”Œć‚’ē½®ćę›ćˆć‚‹ć“ćØćŒć§ćć¾ć™ć€‚ + +値: `true`态`false`怂 + +ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆå€¤: `false`怂 + + +##### `name` + +ćƒŖć‚½ćƒ¼ć‚¹ć®åē§°ćØć—ć¦ä½æē”Øć™ć‚‹åå‰ć‚’ęŒ‡å®šć—ć¾ć™ć€‚ćƒŖć‚½ćƒ¼ć‚¹ć®namevarć‚’ćƒŖć‚½ćƒ¼ć‚¹ć®č¦å®šć®`title`ćØē•°ćŖć‚‹ć‚‚ć®ć«ć—ćŸć„å “åˆćÆć€`name`ć§åå‰ć‚’ęŒ‡å®šć—ć¾ć™ć€‚ + +値: ę–‡å­—åˆ— + +ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆå€¤: ć‚æć‚¤ćƒˆćƒ«ć®å€¤ + +##### `path` + +**åæ…é ˆ** + +`line`ć§ęŒ‡å®šć•ć‚ŒćŸč”Œć‚’ē¢ŗäæć™ć‚‹ćƒ•ć‚”ć‚¤ćƒ«ć‚’ęŒ‡å®šć—ć¾ć™ć€‚ + +値: å½“č©²ćƒ•ć‚”ć‚¤ćƒ«ć®ēµ¶åÆ¾ćƒ‘ć‚¹ć‚’ęŒ‡å®šć™ć‚‹ę–‡å­—åˆ— + +##### `replace` + +`match`ćƒ‘ćƒ©ćƒ”ćƒ¼ć‚æćØćƒžćƒƒćƒć™ć‚‹ę—¢å­˜ć®č”Œć‚’ćƒŖć‚½ćƒ¼ć‚¹ć§äøŠę›øćć™ć‚‹ć‹ć©ć†ć‹ć‚’ęŒ‡å®šć—ć¾ć™ć€‚`false`ć«čØ­å®šć™ć‚‹ćØć€`match`ćƒ‘ćƒ©ćƒ”ćƒ¼ć‚æć«ćƒžćƒƒćƒć™ć‚‹č”ŒćŒč¦‹ć¤ć‹ć£ćŸå “åˆć€ćć®č”ŒćÆćƒ•ć‚”ć‚¤ćƒ«ć«é…ē½®ć•ć‚Œć¾ć›ć‚“ć€‚ + +`false`ć«čØ­å®šć™ć‚‹ćØć€`match`ćƒ‘ćƒ©ćƒ”ćƒ¼ć‚æć«ćƒžćƒƒćƒć™ć‚‹č”ŒćŒč¦‹ć¤ć‹ć£ćŸå “åˆć€ćć®č”ŒćÆćƒ•ć‚”ć‚¤ćƒ«ć«é…ē½®ć•ć‚Œć¾ć›ć‚“ć€‚ + +ćƒ–ćƒ¼ćƒŖć‚¢ćƒ³ć€‚ + +ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆå€¤: `true`怂 + +##### `replace_all_matches_not_matching_line` + +`line`ćŒćƒ•ć‚”ć‚¤ćƒ«ć«ć™ć§ć«å­˜åœØć™ć‚‹å “åˆć§ć‚‚ć€`match`ćƒ‘ćƒ©ćƒ”ćƒ¼ć‚æć«äø€č‡“ć™ć‚‹ć™ć¹ć¦ć®č”ŒćŒē½®ćę›ćˆć‚‰ć‚Œć¾ć™ć€‚ + +ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆå€¤: `false`怂 + +### ćƒ‡ćƒ¼ć‚æć‚æć‚¤ćƒ— + +#### `Stdlib::Absolutepath` + +åŽ³åÆ†ćŖēµ¶åÆ¾ćƒ‘ć‚¹ć‚æć‚¤ćƒ—ć€‚Unixpathć‚æć‚¤ćƒ—ćŠć‚ˆć³Windowspathć‚æć‚¤ćƒ—ć®ē•°å½¢ć‚’ä½æē”Øć—ć¾ć™ć€‚ + +ä½æē”ØåÆčƒ½ćŖć‚¤ćƒ³ćƒ—ćƒƒćƒˆä¾‹: + +```shell +/var/log +``` + +```shell +/usr2/username/bin:/usr/local/bin:/usr/bin:. +``` + +```shell +C:\\WINDOWS\\System32 +``` + +ä½æē”ØäøåÆčƒ½ćŖć‚¤ćƒ³ćƒ—ćƒƒćƒˆä¾‹: + +```shell +../relative_path +``` + +#### `Stdlib::Ensure::Service` + +ć‚µćƒ¼ćƒ“ć‚¹ćƒŖć‚½ćƒ¼ć‚¹ć®ä½æē”ØåÆčƒ½ćŖensure値と一臓します。 + +ä½æē”ØåÆčƒ½ćŖć‚¤ćƒ³ćƒ—ćƒƒćƒˆä¾‹: + +```shell +stopped +running +``` + +ä½æē”ØäøåÆčƒ½ćŖć‚¤ćƒ³ćƒ—ćƒƒćƒˆä¾‹: + +```shell +true +false +``` + +#### `Stdlib::Httpsurl` + +HTTPS URLć«äø€č‡“ć—ć¾ć™ć€‚ć“ć®äø€č‡“ć§ćÆć€å¤§ę–‡å­—ćØå°ę–‡å­—ćÆåŒŗåˆ„ć•ć‚Œć¾ć›ć‚“ć€‚ + +ä½æē”ØåÆčƒ½ćŖć‚¤ćƒ³ćƒ—ćƒƒćƒˆä¾‹: + +```shell +https://hello.com + +HTTPS://HELLO.COM +``` + +ä½æē”ØäøåÆčƒ½ćŖć‚¤ćƒ³ćƒ—ćƒƒćƒˆä¾‹: + +```shell +httds://notquiteright.org` +``` + +#### `Stdlib::Httpurl` + +HTTPSとHTTPの且方のURLć«äø€č‡“ć—ć¾ć™ć€‚ć“ć®äø€č‡“ć§ćÆć€å¤§ę–‡å­—ćØå°ę–‡å­—ćÆåŒŗåˆ„ć•ć‚Œć¾ć›ć‚“ć€‚ + +ä½æē”ØåÆčƒ½ćŖć‚¤ćƒ³ćƒ—ćƒƒćƒˆä¾‹: + +```shell +https://hello.com + +http://hello.com + +HTTP://HELLO.COM +``` + +ä½æē”ØäøåÆčƒ½ćŖć‚¤ćƒ³ćƒ—ćƒƒćƒˆä¾‹: + +```shell +httds://notquiteright.org +``` + +#### `Stdlib::MAC` + +[RFC5342](https://tools.ietf.org/html/rfc5342)ć§å®šē¾©ć•ć‚Œć‚‹MACć‚¢ćƒ‰ćƒ¬ć‚¹ć«äø€č‡“ć—ć¾ć™ć€‚ + +#### `Stdlib::Unixpath` + +Unixć‚Ŗćƒšćƒ¬ćƒ¼ćƒ†ć‚£ćƒ³ć‚°ć‚·ć‚¹ćƒ†ćƒ ć®ēµ¶åÆ¾ćƒ‘ć‚¹ć«äø€č‡“ć—ć¾ć™ć€‚ + +ä½æē”ØåÆčƒ½ćŖć‚¤ćƒ³ćƒ—ćƒƒćƒˆä¾‹: + +```shell +/usr2/username/bin:/usr/local/bin:/usr/bin: + +/var/tmp +``` + +ä½æē”ØäøåÆčƒ½ćŖć‚¤ćƒ³ćƒ—ćƒƒćƒˆä¾‹: + +```shell +C:/whatever + +some/path + +../some/other/path +``` + +#### `Stdlib::Filemode` + +1恋悉4ć¾ć§ć®ę•°å­—ćØć‚·ćƒ³ćƒœćƒŖćƒƒć‚Æćƒ•ć‚”ć‚¤ćƒ«ćƒ¢ćƒ¼ćƒ‰ć‹ć‚‰ćŖć‚‹8é€²ćƒ•ć‚”ć‚¤ćƒ«ćƒ¢ćƒ¼ćƒ‰ć«äø€č‡“ć—ć¾ć™ć€‚ + +ä½æē”ØåÆčƒ½ćŖć‚¤ćƒ³ćƒ—ćƒƒćƒˆä¾‹: + +```shell +0644 +``` + +```shell +1777 +``` + +```shell +a=Xr,g=w +``` + +ä½æē”ØäøåÆčƒ½ćŖć‚¤ćƒ³ćƒ—ćƒƒćƒˆä¾‹: + +```shell +x=r,a=wx +``` + +```shell +0999 +``` + +#### `Stdlib::Windowspath` + +Windowsć‚Ŗćƒšćƒ¬ćƒ¼ćƒ†ć‚£ćƒ³ć‚°ć‚·ć‚¹ćƒ†ćƒ ć®ćƒ‘ć‚¹ć«äø€č‡“ć—ć¾ć™ć€‚ + +ä½æē”ØåÆčƒ½ćŖć‚¤ćƒ³ćƒ—ćƒƒćƒˆä¾‹: + +```shell +C:\\WINDOWS\\System32 + +C:\\ + +\\\\host\\windows +``` + +ęœ‰åŠ¹ćŖå€¤: Windowsć®ćƒ•ć‚”ć‚¤ćƒ«ćƒ‘ć‚¹ć«äø€č‡“ć—ć¾ć™ć€‚ + +#### `Stdlib::Filesource` + +Puppetćƒ•ć‚”ć‚¤ćƒ«ć‚æć‚¤ćƒ—ć®ć‚½ćƒ¼ć‚¹ćƒ‘ćƒ©ćƒ”ćƒ¼ć‚æć®ęœ‰åŠ¹ćŖå€¤ć®ćƒ‘ć‚¹ć«äø€č‡“ć—ć¾ć™ć€‚ + +ä½æē”ØåÆčƒ½ćŖć‚¤ćƒ³ćƒ—ćƒƒćƒˆä¾‹: + +```shell +http://example.com + +https://example.com + +file:///hello/bla +``` + +ęœ‰åŠ¹ćŖå€¤: ćƒ•ć‚”ć‚¤ćƒ«ćƒ‘ć‚¹ć€‚ + +#### `Stdlib::Fqdn` + +å®Œå…Øäæ®é£¾ćƒ‰ćƒ”ć‚¤ćƒ³å(FQDN)ć®ćƒ‘ć‚¹ć«äø€č‡“ć—ć¾ć™ć€‚ + +ä½æē”ØåÆčƒ½ćŖć‚¤ćƒ³ćƒ—ćƒƒćƒˆä¾‹: + +```shell +localhost + +example.com + +www.example.com +``` +ęœ‰åŠ¹ćŖå€¤: ć‚µćƒ¼ćƒćƒ¼ć®ćƒ‰ćƒ”ć‚¤ćƒ³åć€‚ + +#### `Stdlib::Host` + +ęœ‰åŠ¹ćŖćƒ›ć‚¹ćƒˆć«äø€č‡“ć—ć¾ć™ć€‚ć“ć‚Œć«ćÆć€ęœ‰åŠ¹ćŖipv4态ipv6ć€ć¾ćŸćÆfqdnを含みます。 + +ä½æē”ØåÆčƒ½ćŖć‚¤ćƒ³ćƒ—ćƒƒćƒˆä¾‹: + +```shell +localhost + +www.example.com + +192.0.2.1 +``` + +ęœ‰åŠ¹ćŖå€¤: IPć‚¢ćƒ‰ćƒ¬ć‚¹ć¾ćŸćÆćƒ‰ćƒ”ć‚¤ćƒ³åć€‚ + +#### `Stdlib::Port` + +ęœ‰åŠ¹ćŖTCP/UDPćƒćƒ¼ćƒˆē•Ŗå·ć«äø€č‡“ć—ć¾ć™ć€‚ + +ä½æē”ØåÆčƒ½ćŖć‚¤ćƒ³ćƒ—ćƒƒćƒˆä¾‹: + +```shell +80 + +443 + +65000 +``` + +ęœ‰åŠ¹ćŖå€¤: ꕓꕰ怂 + +#### `Stdlib::Port::Privileged` + +ęœ‰åŠ¹ćŖTCP/UDPē‰¹ęØ©ćƒćƒ¼ćƒˆ(1024ęœŖęŗ€)に一臓します。 + +ä½æē”ØåÆčƒ½ćŖć‚¤ćƒ³ćƒ—ćƒƒćƒˆä¾‹: + +```shell +80 + +443 + +1023 +``` + +ęœ‰åŠ¹ćŖå€¤: 1024ęœŖęŗ€ć®ę•°ć€‚ + +#### `Stdlib::Port::Unprivileged` + +ęœ‰åŠ¹ćŖTCP/UDPē‰¹ęØ©ćƒćƒ¼ćƒˆ(1024仄上)に一臓します。 + +ä½æē”ØåÆčƒ½ćŖć‚¤ćƒ³ćƒ—ćƒƒćƒˆä¾‹: + +```shell +1024 + +1337 + +65000 + +``` + +ęœ‰åŠ¹ćŖå€¤: 1024ä»„äøŠć®ę•°ć€‚ + +#### `Stdlib::Base32` + +ęœ‰åŠ¹ćŖbase32ę–‡å­—åˆ—ć®ćƒ‘ć‚¹ć«äø€č‡“ć—ć¾ć™ć€‚ + +ä½æē”ØåÆčƒ½ćŖć‚¤ćƒ³ćƒ—ćƒƒćƒˆä¾‹: + +```shell +ASDASDDASD3453453 + +asdasddasd3453453= + +ASDASDDASD3453453== +``` + +ęœ‰åŠ¹ćŖå€¤: base32ę–‡å­—åˆ—ć€‚ + +#### `Stdlib::Base64` + +ęœ‰åŠ¹ćŖbase64ę–‡å­—åˆ—ć®ćƒ‘ć‚¹ć«äø€č‡“ć—ć¾ć™ć€‚ + +ä½æē”ØåÆčƒ½ćŖć‚¤ćƒ³ćƒ—ćƒƒćƒˆä¾‹: + +```shell +asdasdASDSADA342386832/746+= + +asdasdASDSADA34238683274/6+ + +asdasdASDSADA3423868327/46+== +``` + +ęœ‰åŠ¹ćŖå€¤: base64ę–‡å­—åˆ—ć€‚ + +#### `Stdlib::Ipv4` + +ęœ‰åŠ¹ćŖIPv4ć‚¢ćƒ‰ćƒ¬ć‚¹ć«äø€č‡“ć—ć¾ć™ć€‚ + +ä½æē”ØåÆčƒ½ćŖć‚¤ćƒ³ćƒ—ćƒƒćƒˆä¾‹: + +```shell +0.0.0.0 + +192.0.2.1 + +127.0.0.1 +``` + +ęœ‰åŠ¹ćŖå€¤: IPv4ć‚¢ćƒ‰ćƒ¬ć‚¹ć€‚ + +#### `Stdlib::Ipv6` + +ęœ‰åŠ¹ćŖIPv6ć‚¢ćƒ‰ćƒ¬ć‚¹ć«äø€č‡“ć—ć¾ć™ć€‚ + +ä½æē”ØåÆčƒ½ćŖć‚¤ćƒ³ćƒ—ćƒƒćƒˆä¾‹: + +```shell +2001:0db8:85a3:0000:0000:8a2e:0370:7334 + +2001:db8:: + +2001:db8::80 +``` + +ęœ‰åŠ¹ćŖå€¤: IPv6ć‚¢ćƒ‰ćƒ¬ć‚¹ć€‚ + +#### `Stdlib::Ip_address` + +ęœ‰åŠ¹ćŖIPv4またはIPv6ć‚¢ćƒ‰ćƒ¬ć‚¹ć«äø€č‡“ć—ć¾ć™ć€‚ + +ä½æē”ØåÆčƒ½ćŖć‚¤ćƒ³ćƒ—ćƒƒćƒˆä¾‹: + +```shell +0.0.0.0 + +127.0.0.1 + +fe80:0000:0000:0000:0204:61ff:fe9d:f156 +``` + +ęœ‰åŠ¹ćŖå€¤: IPć‚¢ćƒ‰ćƒ¬ć‚¹ć€‚ + +#### `Stdlib::IP::Address` + +IPv4とIPv6äø”ę–¹ć®ć‚¢ćƒ‰ćƒ¬ć‚¹ć‚’å«ć‚€ć€ä»»ę„ć®IPć‚¢ćƒ‰ćƒ¬ć‚¹ć«äø€č‡“ć—ć¾ć™ć€‚CIDRćƒ•ć‚©ćƒ¼ćƒžćƒƒćƒˆć®IPv4ć‚¢ćƒ‰ćƒ¬ć‚¹ć§ä½æē”Øć•ć‚Œć‚‹ć‚¢ćƒ‰ćƒ¬ć‚¹ćƒ—ćƒ¬ćƒ•ć‚£ćƒƒć‚Æć‚¹ć®ęœ‰ē„”ć«é–¢ć‚ć‚‰ćšäø€č‡“ć—ć¾ć™ć€‚ + +例: + +``` +'127.0.0.1' =~ Stdlib::IP::Address # true +'10.1.240.4/24' =~ Stdlib::IP::Address # true +'52.10.10.141' =~ Stdlib::IP::Address # true +'192.168.1' =~ Stdlib::IP::Address # false +'FEDC:BA98:7654:3210:FEDC:BA98:7654:3210' =~ Stdlib::IP::Address # true +'FF01:0:0:0:0:0:0:101' =~ Stdlib::IP::Address # true +``` + +#### `Stdlib::IP::Address::V4` + +CIDRćƒ—ćƒ¬ćƒ•ć‚£ćƒƒć‚Æć‚¹ć®ęœ‰ē„”ć«é–¢ć‚ć‚‰ćšć€ćƒ‰ćƒƒćƒˆåŒŗåˆ‡ć‚Šć®4恤恮10é€²ę•°ć§č”Øē¾ć•ć‚ŒćŸIPv4ć‚¢ćƒ‰ćƒ¬ć‚¹ć§ę§‹ęˆć•ć‚Œć‚‹ä»»ę„ć®ę–‡å­—åˆ—ć«äø€č‡“ć—ć¾ć™ć€‚ēœē•„å½¢(192.168.1など)ć«ćÆäø€č‡“ć—ć¾ć›ć‚“ć€‚ēœē•„å½¢ćÆćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ćŒäøååˆ†ć§ć€ć‚µćƒćƒ¼ćƒˆć«ć°ć‚‰ć¤ććŒć‚ć‚‹ćŸć‚ć§ć™ć€‚ + +例: + +``` +'127.0.0.1' =~ Stdlib::IP::Address::V4 # true +'10.1.240.4/24' =~ Stdlib::IP::Address::V4 # true +'192.168.1' =~ Stdlib::IP::Address::V4 # false +'FEDC:BA98:7654:3210:FEDC:BA98:7654:3210' =~ Stdlib::IP::Address::V4 # false +'12AB::CD30:192.168.0.1' =~ Stdlib::IP::Address::V4 # false +``` + +ęœ‰åŠ¹ćŖå€¤: IPv4ć‚¢ćƒ‰ćƒ¬ć‚¹ć€‚ + +#### `Stdlib::IP::Address::V6` + +ć‚¢ćƒ‰ćƒ¬ć‚¹ćƒ—ćƒ¬ćƒ•ć‚£ćƒƒć‚Æć‚¹ć®ęœ‰ē„”ć«é–¢ć‚ć‚‰ćšć€RFC 2373ć«č¦å®šć•ć‚ŒćŸä»»ę„ć®ćƒ•ć‚©ćƒ¼ćƒžćƒƒćƒˆć§čØ˜čæ°ć•ć‚ŒćŸIPv6ć‚¢ćƒ‰ćƒ¬ć‚¹ć‚’ę§‹ęˆć™ć‚‹ä»»ę„ć®ę–‡å­—åˆ—ć«äø€č‡“ć—ć¾ć™ć€‚ + +例: + +``` +'127.0.0.1' =~ Stdlib::IP::Address::V6 # false +'10.1.240.4/24' =~ Stdlib::IP::Address::V6 # false +'FEDC:BA98:7654:3210:FEDC:BA98:7654:3210' =~ Stdlib::IP::Address::V6 # true +'FF01:0:0:0:0:0:0:101' =~ Stdlib::IP::Address::V6 # true +'FF01::101' =~ Stdlib::IP::Address::V6 # true +``` + +ęœ‰åŠ¹ćŖå€¤: IPv6ć‚¢ćƒ‰ćƒ¬ć‚¹ć€‚ + +#### `Stdlib::IP::Address::Nosubnet` + +`Stdlib::IP::Address`ć‚Øć‚¤ćƒŖć‚¢ć‚¹ćØåŒć˜ć‚‚ć®ć«äø€č‡“ć—ć¾ć™ćŒć€ć‚¢ćƒ‰ćƒ¬ć‚¹ćƒ—ćƒ¬ćƒ•ć‚£ćƒƒć‚Æć‚¹ć‚’å«ć‚€ć‚¢ćƒ‰ćƒ¬ć‚¹ć«ćÆäø€č‡“ć—ć¾ć›ć‚“(ćŸćØćˆć°ć€'192.168.0.6'ć«ćÆäø€č‡“ć—ć¾ć™ćŒć€'192.168.0.6/24'には一臓しません)怂 + +ęœ‰åŠ¹ćŖå€¤: ć‚µćƒ–ćƒćƒƒćƒˆć‚’ęŒćŸćŖć„IPć‚¢ćƒ‰ćƒ¬ć‚¹ć€‚ + +#### `Stdlib::IP::Address::V4::CIDR` + +CIDRå½¢å¼ć®IPv4ć‚¢ćƒ‰ćƒ¬ć‚¹ć«äø€č‡“ć—ć¾ć™ć€‚ć‚¢ćƒ‰ćƒ¬ć‚¹ć«ć‚¢ćƒ‰ćƒ¬ć‚¹ćƒ—ćƒ¬ćƒ•ć‚£ćƒƒć‚Æć‚¹ćŒå«ć¾ć‚Œć¦ć„ć‚‹å “åˆć«ć®ćæäø€č‡“ć—ć¾ć™(ä¾‹ćˆć°ć€'192.168.0.6/24'ć«ćÆäø€č‡“ć—ć¾ć™ćŒć€'192.168.0.6'には一臓しません)怂 + +ęœ‰åŠ¹ćŖå€¤: CIDRćŒęä¾›ć•ć‚ŒćŸIPv4ć‚¢ćƒ‰ćƒ¬ć‚¹ć€ćŸćØćˆć°'192.186.8.101/105'ćŖć©ć€‚ć“ć‚ŒćÆć€'192.186.8.101'ļ½ž'192.168.8.105'を含むすべてに一臓します。 + +#### `Stdlib::IP::Address::V4::Nosubnet` + +ć‚¢ćƒ‰ćƒ¬ć‚¹ćƒ—ćƒ¬ćƒ•ć‚£ćƒƒć‚Æć‚¹ć‚’å«ć¾ćŖć„IPv4ć‚¢ćƒ‰ćƒ¬ć‚¹ć«äø€č‡“ć—ć¾ć™(ćŸćØćˆć°ć€'192.168.0.6'ć«ćÆäø€č‡“ć—ć¾ć™ćŒć€'192.168.0.6/24'には一臓しません)怂 + +ęœ‰åŠ¹ćŖå€¤: ć‚µćƒ–ćƒćƒƒćƒˆć‚’ęŒćŸćŖć„IPv4ć‚¢ćƒ‰ćƒ¬ć‚¹ć€‚ + +#### `Stdlib::IP::Address::V6::Full` + +[RFC 2373](https://www.ietf.org/rfc/rfc2373.txt)恮2.2ć«č¦å®šć•ć‚ŒćŸć€Œå„½ć¾ć—ć„å½¢å¼ć€ć®IPv6ć‚¢ćƒ‰ćƒ¬ć‚¹ć«äø€č‡“ć—ć¾ć™ć€‚[RFC 2373](https://www.ietf.org/rfc/rfc2373.txt)恮2.3ć«č¦å®šć•ć‚ŒćŸć‚¢ćƒ‰ćƒ¬ć‚¹ćƒ—ćƒ¬ćƒ•ć‚£ćƒƒć‚Æć‚¹ć®ęœ‰ē„”ć«é–¢ć‚ć‚‰ćšäø€č‡“ć—ć¾ć™ć€‚ + +#### `Stdlib::IP::Address::V6::Alternate` + +[RFC 2373](https://www.ietf.org/rfc/rfc2373.txt)恮2.2ć«č¦å®šć•ć‚ŒćŸć€Œä»£ę›æå½¢å¼ć€(ęœ€å¾Œć®2恤恮16ćƒ“ćƒƒćƒˆę–­ē‰‡ć‚’ćƒ‰ćƒƒćƒˆåŒŗåˆ‡ć‚Šć®4恤恮10é€²ę•°ć§č”Øē¾ć§ćć‚‹)恮IPv6ć‚¢ćƒ‰ćƒ¬ć‚¹ć«äø€č‡“ć—ć¾ć™ć€‚[RFC 2373](https://www.ietf.org/rfc/rfc2373.txt)恮2.3ć«č¦å®šć•ć‚ŒćŸć‚¢ćƒ‰ćƒ¬ć‚¹ćƒ—ćƒ¬ćƒ•ć‚£ćƒƒć‚Æć‚¹ć®ęœ‰ē„”ć«é–¢ć‚ć‚‰ćšäø€č‡“ć—ć¾ć™ć€‚ + +#### `Stdlib::IP::Address::V6::Compressed` + +[RFC 2373](https://www.ietf.org/rfc/rfc2373.txt)恮2.2ć«č¦å®šć•ć‚ŒćŸ0ć‚’åœ§ēø®ć™ć‚‹čØ˜ę³•ć§ć‚ć‚‹`::`ć‚’å«ć‚€åÆčƒ½ę€§ć®ć‚ć‚‹IPv6ć‚¢ćƒ‰ćƒ¬ć‚¹ć«äø€č‡“ć—ć¾ć™ć€‚[RFC 2373](https://www.ietf.org/rfc/rfc2373.txt)恮2.3ć«č¦å®šć•ć‚ŒćŸć‚¢ćƒ‰ćƒ¬ć‚¹ćƒ—ćƒ¬ćƒ•ć‚£ćƒƒć‚Æć‚¹ć®ęœ‰ē„”ć«é–¢ć‚ć‚‰ćšäø€č‡“ć—ć¾ć™ć€‚ + +#### `Stdlib::IP::Address::V6::Nosubnet` + +`Stdlib::IP::Address::V6::Nosubnet::Full`态`Stdlib::IP::Address::V6::Nosubnet::Alternate`ć€ćŠć‚ˆć³`Stdlib::IP::Address::V6::Nosubnet::Compressed`ć‚’čØ±åÆć™ć‚‹ć‚Øć‚¤ćƒŖć‚¢ć‚¹ć€‚ + +#### `Stdlib::IP::Address::V6::Nosubnet::Full` + +[RFC 2373](https://www.ietf.org/rfc/rfc2373.txt)恮2.2.1ć«č¦å®šć•ć‚ŒćŸć€Œå„½ć¾ć—ć„å½¢å¼ć€ć®IPv6ć‚¢ćƒ‰ćƒ¬ć‚¹ć«äø€č‡“ć—ć¾ć™ć€‚[RFC 2373](https://www.ietf.org/rfc/rfc2373.txt)恮2.3ć«č¦å®šć•ć‚ŒćŸć‚¢ćƒ‰ćƒ¬ć‚¹ćƒ—ćƒ¬ćƒ•ć‚£ćƒƒć‚Æć‚¹ć‚’ęŒć¤ć‚¢ćƒ‰ćƒ¬ć‚¹ć«ćÆäø€č‡“ć—ć¾ć›ć‚“ć€‚ + +#### `Stdlib::IP::Address::V6::Nosubnet::Alternate` + +[RFC 2373](https://www.ietf.org/rfc/rfc2373.txt)恮2.2.1ć«č¦å®šć•ć‚ŒćŸć€Œä»£ę›æå½¢å¼ć€(ęœ€å¾Œć®2恤恮16ćƒ“ćƒƒćƒˆę–­ē‰‡ć‚’ćƒ‰ćƒƒćƒˆåŒŗåˆ‡ć‚Šć®4恤恮10é€²ę•°ć§č”Øē¾ć§ćć‚‹)恮IPv6ć‚¢ćƒ‰ćƒ¬ć‚¹ć«äø€č‡“ć—ć¾ć™ć€‚[RFC 2373](https://www.ietf.org/rfc/rfc2373.txt)恮2.3ć«č¦å®šć•ć‚ŒćŸć‚¢ćƒ‰ćƒ¬ć‚¹ćƒ—ćƒ¬ćƒ•ć‚£ćƒƒć‚Æć‚¹ć‚’ęŒćŸćŖć„ć‚¢ćƒ‰ćƒ¬ć‚¹ć«ć®ćæäø€č‡“ć—ć¾ć™ć€‚ + +#### `Stdlib::IP::Address::V6::Nosubnet::Compressed` + +[RFC 2373](https://www.ietf.org/rfc/rfc2373.txt)恮2.2.2ć«č¦å®šć•ć‚ŒćŸ0ć‚’åœ§ēø®ć™ć‚‹čØ˜ę³•ć§ć‚ć‚‹`::`ć‚’å«ć‚€åÆčƒ½ę€§ć®ć‚ć‚‹IPv6ć‚¢ćƒ‰ćƒ¬ć‚¹ć«äø€č‡“ć—ć¾ć™ć€‚[RFC 2373](https://www.ietf.org/rfc/rfc2373.txt)恮2.3ć«č¦å®šć•ć‚ŒćŸć‚¢ćƒ‰ćƒ¬ć‚¹ćƒ—ćƒ¬ćƒ•ć‚£ćƒƒć‚Æć‚¹ć‚’ęŒćŸćŖć„ć‚¢ćƒ‰ćƒ¬ć‚¹ć«ć®ćæäø€č‡“ć—ć¾ć™ć€‚ + +### Facts + +#### `package_provider` + +PuppetćŒć“ć®ć‚·ć‚¹ćƒ†ćƒ ć®ćƒ‘ćƒƒć‚±ćƒ¼ć‚øē®”ē†ć«ä½æē”Øć™ć‚‹ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆć®ćƒ—ćƒ­ćƒć‚¤ćƒ€ć‚’čæ”ć—ć¾ć™ć€‚ + +#### `is_pe` + +Puppet EnterprisećŒć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ«ć•ć‚Œć¦ć„ć‚‹ć‹ć©ć†ć‹ć‚’čæ”ć—ć¾ć™ć€‚PE 3.xä»„é™ć®ćƒ—ćƒ©ćƒƒćƒˆćƒ•ć‚©ćƒ¼ćƒ ć§ćÆä½•ć‚‚å ±å‘Šć•ć‚Œć¾ć›ć‚“ć€‚ + +#### `pe_version` + +ć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ«ć•ć‚Œć¦ć„ć‚‹Puppet Enterpriseć®ćƒćƒ¼ć‚øćƒ§ćƒ³ć‚’čæ”ć—ć¾ć™ć€‚PE 3.xä»„é™ć®ćƒ—ćƒ©ćƒƒćƒˆćƒ•ć‚©ćƒ¼ćƒ ć§ćÆä½•ć‚‚å ±å‘Šć•ć‚Œć¾ć›ć‚“ć€‚ + +#### `pe_major_version` + +ć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ«ć•ć‚Œć¦ć„ć‚‹Puppet Enterpriseć®ćƒ”ć‚øćƒ£ćƒ¼ćƒćƒ¼ć‚øćƒ§ćƒ³ć‚’čæ”ć—ć¾ć™ć€‚PE 3.xä»„é™ć®ćƒ—ćƒ©ćƒƒćƒˆćƒ•ć‚©ćƒ¼ćƒ ć§ćÆä½•ć‚‚å ±å‘Šć•ć‚Œć¾ć›ć‚“ć€‚ + +#### `pe_minor_version` + +ć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ«ć•ć‚Œć¦ć„ć‚‹Puppet Enterpriseć®ćƒžć‚¤ćƒŠćƒ¼ćƒćƒ¼ć‚øćƒ§ćƒ³ć‚’čæ”ć—ć¾ć™ć€‚PE 3.xä»„é™ć®ćƒ—ćƒ©ćƒƒćƒˆćƒ•ć‚©ćƒ¼ćƒ ć§ćÆä½•ć‚‚å ±å‘Šć•ć‚Œć¾ć›ć‚“ć€‚ + +#### `pe_patch_version` + +ć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ«ć•ć‚Œć¦ć„ć‚‹Puppet Enterpriseć®ćƒ‘ćƒƒćƒćƒćƒ¼ć‚øćƒ§ćƒ³ć‚’čæ”ć—ć¾ć™ć€‚ + +#### `puppet_vardir` + +PuppetまたはPuppet agentćŒēØ¼åƒć—ć¦ć„ć‚‹ćƒŽćƒ¼ćƒ‰ć«ć¤ć„ć¦čØ­å®šć•ć‚ŒćŸPuppet vardirの値を返します。 + +#### `puppet_environmentpath` + +PuppetまたはPuppet agentćŒēØ¼åƒć—ć¦ć„ć‚‹ćƒŽćƒ¼ćƒ‰ć«ć¤ć„ć¦čØ­å®šć•ć‚ŒćŸPuppetē’°å¢ƒć®å€¤ć‚’čæ”ć—ć¾ć™ć€‚ + +#### `puppet_server` + +Puppet agent恮`server`値を返します。この値は、agentćŒé€šäæ”ć™ć‚‹Puppet serverć®ćƒ›ć‚¹ćƒˆćƒćƒ¼ćƒ ć§ć™ć€‚ + +#### `root_home` + +ćƒ«ćƒ¼ćƒˆć®ćƒ›ćƒ¼ćƒ ćƒ‡ć‚£ćƒ¬ć‚ÆćƒˆćƒŖć‚’ę±ŗå®šć—ć¾ć™ć€‚ + +ćƒ«ćƒ¼ćƒˆć®ćƒ›ćƒ¼ćƒ ćƒ‡ć‚£ćƒ¬ć‚ÆćƒˆćƒŖć‚’ę±ŗå®šć—ć¾ć™ć€‚ć“ć‚ŒćÆć€ć‚Ŗćƒšćƒ¬ćƒ¼ćƒ†ć‚£ćƒ³ć‚°ć‚·ć‚¹ćƒ†ćƒ ć«ć‚ˆć£ć¦ē•°ćŖć‚Šć¾ć™ć€‚é€šåøøćÆ'/root'恧恙怂 + +#### `service_provider` + +PuppetćŒć“ć®ć‚·ć‚¹ćƒ†ćƒ ć®ć‚µćƒ¼ćƒ“ć‚¹ē®”ē†ć«ä½æē”Øć™ć‚‹ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆć®ćƒ—ćƒ­ćƒć‚¤ćƒ€ć‚’čæ”ć—ć¾ć™ć€‚ + +### 関数 + +#### `abs` + +**éžęŽØå„Ø:** この関数は、Puppet 6.0.0で、内蔵の[`abs`](https://puppet.com/docs/puppet/latest/function.html#abs)é–¢ę•°ć«ē½®ćę›ćˆć‚‰ć‚Œć¾ć—ćŸć€‚ + +ę•°å­—ć®ēµ¶åÆ¾å€¤ć‚’čæ”ć—ć¾ć™ć€‚ćŸćØćˆć°ć€'-34.56'は'34.56'ć«ćŖć‚Šć¾ć™ć€‚ + +引数: ę•“ę•°å€¤ć¾ćŸćÆęµ®å‹•å°ę•°ē‚¹å€¤ć®ć„ćšć‚Œć‹ć®å˜äø€ć®å¼•ę•°ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `any2array` + +ä»»ę„ć®ć‚Ŗćƒ–ć‚øć‚§ć‚Æćƒˆć‚’ć€ćć®ć‚Ŗćƒ–ć‚øć‚§ć‚Æćƒˆć‚’å«ć‚€é…åˆ—ć«å¤‰ę›ć—ć¾ć™ć€‚ē©ŗć®å¼•ę•°ćƒŖć‚¹ćƒˆćÆē©ŗć®é…åˆ—ć«å¤‰ę›ć•ć‚Œć¾ć™ć€‚ćƒćƒƒć‚·ćƒ„ćÆć€ć‚­ćƒ¼ćØå€¤ćŒäŗ¤äŗ’ć«ćŖć£ćŸé…åˆ—ć«å¤‰ę›ć•ć‚Œć¾ć™ć€‚é…åˆ—ćÆå¤‰ę›ć•ć‚Œć¾ć›ć‚“ć€‚ + +Puppet 5.0.0ä»„é™ć§ćÆć€ć‚æć‚¤ćƒ—ć‚·ć‚¹ćƒ†ćƒ ć‚’ä½æē”Øć—ć¦ć»ćØć‚“ć©ć™ć¹ć¦ć®ćƒ‡ćƒ¼ć‚æć‚æć‚¤ćƒ—ć®ę–°ć—ć„å€¤ć‚’ä½œęˆć§ćć¾ć™ć€‚å†…č”µć®[`Array.new`](https://puppet.com/docs/puppet/latest/function.html#conversion-to-array-and-tuple)é–¢ę•°ć‚’ä½æē”Øć—ć¦ę–°ć—ć„é…åˆ—ć‚’ä½œęˆć§ćć¾ć™ć€‚ + + $hsh = {'key' => 42, 'another-key' => 100} + notice(Array($hsh)) + +`[['key', 42], ['another-key', 100]]`ć‚’é€šēŸ„ć—ć¾ć™ + +é…åˆ—ć®ćƒ‡ćƒ¼ć‚æć‚æć‚¤ćƒ—ć«ćÆć€"ć¾ć é…åˆ—ć§ćŖć„å “åˆćÆé…åˆ—ć‚’ä½œęˆć™ć‚‹"ćØć„ć†ē‰¹åˆ„ćŖćƒ¢ćƒ¼ćƒ‰ć‚‚ć‚ć‚Šć¾ć™ć€‚ + + notice(Array({'key' => 42, 'another-key' => 100}, true)) + +`true`ćƒ•ćƒ©ć‚°ćÆćƒćƒƒć‚·ćƒ„ćŒé…åˆ—ć«å¤‰ę›ć•ć‚ŒćŖć„ć‚ˆć†ć«ć™ć‚‹ćŸć‚ć€`[{'key' => 42, 'another-key' => 100}]`ć‚’é€šēŸ„ć—ć¾ć™ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `any2bool` + +ä»»ę„ć®ć‚Ŗćƒ–ć‚øć‚§ć‚Æćƒˆć‚’ćƒ–ćƒ¼ćƒŖć‚¢ćƒ³ć«å¤‰ę›ć—ć¾ć™ć€‚ + +* 'Y'态'y'态'1'态'T'态't'态'TRUE'态'yes'态'true'ćØć„ć£ćŸę–‡å­—åˆ—ćÆ`true`を返します。 +* '0'态'F'态'f'态'N'态'n'态'FALSE'态'no'态'false'ćØć„ć£ćŸę–‡å­—åˆ—ćÆ`false`を返します。 +* ćƒ–ćƒ¼ćƒŖć‚¢ćƒ³ćÆå…ƒć®å€¤ć‚’čæ”ć—ć¾ć™ć€‚ +* 0ć‚ˆć‚Šć‚‚å¤§ćć„ę•°å­—(ć¾ćŸćÆę•°å­—ć®ę–‡å­—åˆ—č”Øē¾)は`true`ć‚’čæ”ć—ć¾ć™ć€‚ćć‚Œä»„å¤–ćÆ`false`を返します。 +* undef値は`false`を返します。 +* ćć‚Œä»„å¤–ćÆć™ć¹ć¦`true`を返します。 + +詳瓰については、内蔵の[`Boolean.new`](https://puppet.com/docs/puppet/latest/function.html#conversion-to-boolean)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `assert_private` + +ē¾åœØć®ć‚Æćƒ©ć‚¹ć¾ćŸćÆå®šē¾©ć‚’ćƒ—ćƒ©ć‚¤ćƒ™ćƒ¼ćƒˆćØć—ć¦čØ­å®šć—ć¾ć™ć€‚ē¾åœØć®ćƒ¢ć‚øćƒ„ćƒ¼ćƒ«å¤–ć®ć‚Æćƒ©ć‚¹ć¾ćŸćÆå®šē¾©ć‚æć‚¤ćƒ—ć‚’å‘¼ć³å‡ŗć™ć“ćØćÆć§ćć¾ć›ć‚“ć€‚ + +ćŸćØćˆć°ć€ć‚Æćƒ©ć‚¹`foo::bar`恧`assert_private()`ćŒć‚³ćƒ¼ćƒ«ć•ć‚Œć‚‹ćØć€ć‚Æćƒ©ć‚¹ćŒćƒ¢ć‚øćƒ„ćƒ¼ćƒ«`foo`ć®å¤–ć‹ć‚‰å‘¼ć³å‡ŗć•ć‚ŒćŸå “åˆć€ę¬”ć®ćƒ”ćƒƒć‚»ćƒ¼ć‚øćŒć‚¢ć‚¦ćƒˆćƒ—ćƒƒćƒˆć•ć‚Œć¾ć™ļ¼š`Class foo::bar is private`怂 + +ä½æē”Øć—ćŸć„ć‚Øćƒ©ćƒ¼ćƒ”ćƒƒć‚»ćƒ¼ć‚øć‚’ęŒ‡å®šć™ć‚‹ę–¹ę³•: + +```puppet +assert_private("You're not supposed to do that!") +``` + +*ć‚æć‚¤ćƒ—*: ć‚¹ćƒ†ćƒ¼ćƒˆćƒ”ćƒ³ćƒˆ + +#### `base64` + +ę–‡å­—åˆ—ćØbase64ć‚Øćƒ³ć‚³ćƒ¼ćƒ‰ć‚’ē›øäŗ’ć«å¤‰ę›ć—ć¾ć™ć€‚`action` ('encode'态'decode')ćØćƒ—ćƒ¬ćƒ¼ćƒ³ć¾ćŸćÆ base64ć§ć‚Øćƒ³ć‚³ćƒ¼ćƒ‰ć—ćŸ`string`ć€ćŠć‚ˆć³ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć§`method` ('default'态'strict'态'urlsafe')ćŒåæ…č¦ć§ć™ć€‚ + +äø‹ä½äŗ’ę›ę€§ć‚’å¾—ć‚‹ć«ćÆć€`method`悒`default`ć«čØ­å®šć—ć¾ć™(ęŒ‡å®šć•ć‚Œć¦ć„ćŖć„å “åˆ)怂 + +> **注:** この関数はRubyć‚Æćƒ©ć‚¹ć®å®Ÿč£…ć«ć‚ćŸć‚Šć€UTF8ćØć®äŗ’ę›ę€§ćŒćŖć„åÆčƒ½ę€§ćŒć‚ć‚Šć¾ć™ć€‚äŗ’ę›ę€§ć‚’ē¢ŗäæć™ć‚‹ć«ćÆć€Ruby 2.4.0ä»„é™ć§ć“ć®é–¢ę•°ć‚’ä½æē”Øć—ć¦ćć ć•ć„ć€‚ + +Puppet 4.8.0ä»„é™ć§ćÆć€ćƒ™ćƒ¼ć‚¹64 ć§ć‚Øćƒ³ć‚³ćƒ¼ćƒ‰ć•ć‚ŒćŸę–‡å­—åˆ—ć®ē”Ÿęˆć«ć€`ćƒć‚¤ćƒŠćƒŖ`ćƒ‡ćƒ¼ć‚æć‚æć‚¤ćƒ—ć‚’ä½æē”Øć§ćć¾ć™ć€‚ + +詳瓰については、内蔵の[`String.new`](https://puppet.com/docs/puppet/latest/function.html#binary-value-to-string)関数と[`Binary.new`](https://puppet.com/docs/puppet/latest/function.html#creating-a-binary)é–¢ę•°ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +ćƒć‚¤ćƒŠćƒŖ(非UTF-8)ć‚³ćƒ³ćƒ†ćƒ³ćƒ„ć‚’å«ć‚€ćƒ•ć‚”ć‚¤ćƒ«ć®čŖ­ćæå–ć‚Šć«ć¤ć„ć¦ćÆć€å†…č”µć®[`binary_file`](https://puppet.com/docs/puppet/latest/function.html#binary_file)é–¢ę•°ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + + # encode a string as if it was binary + $encodestring = String(Binary('thestring', '%s')) + # decode a Binary assuming it is an UTF-8 String + $decodestring = String(Binary("dGhlc3RyaW5n"), "%s") + +**例:** + +```puppet +base64('encode', 'hello') +base64('encode', 'hello', 'default') +# return: "aGVsbG8=\n" + +base64('encode', 'hello', 'strict') +# return: "aGVsbG8=" + +base64('decode', 'aGVsbG8=') +base64('decode', 'aGVsbG8=\n') +base64('decode', 'aGVsbG8=', 'default') +base64('decode', 'aGVsbG8=\n', 'default') +base64('decode', 'aGVsbG8=', 'strict') +# return: "hello" + +base64('encode', 'https://puppetlabs.com', 'urlsafe') +# return: "aHR0cHM6Ly9wdXBwZXRsYWJzLmNvbQ==" + +base64('decode', 'aHR0cHM6Ly9wdXBwZXRsYWJzLmNvbQ==', 'urlsafe') +# return: "https://puppetlabs.com" +``` + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `basename` + +ćƒ‘ć‚¹ć®`basename`ć‚’čæ”ć—ć¾ć™ć€‚ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć®å¼•ę•°ć§ę‹”å¼µå­ćŒå¤–ć‚Œć¾ć™ć€‚ä¾‹: + +```puppet +basename('/path/to/a/file.ext') => 'file.ext' +basename('relative/path/file.ext') => 'file.ext' +basename('/path/to/a/file.ext', '.ext') => 'file' +``` + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `bool2num` + +ćƒ–ćƒ¼ćƒŖć‚¢ćƒ³ć‚’ę•°å­—ć«å¤‰ę›ć—ć¾ć™ć€‚ä»„äø‹ć®å€¤ć‚’å¤‰ę›ć—ć¾ć™ć€‚ + +* `false`态'f'态'0'态'n'态'no'悒0ć«å¤‰ę›ć—ć¾ć™ć€‚ +* `true`态't'态'1'态'y'态'yes'悒1ć«å¤‰ę›ć—ć¾ć™ć€‚ + +引数: ć‚¤ćƒ³ćƒ—ćƒƒćƒˆćØć—ć¦ć€å˜äø€ć®ćƒ–ćƒ¼ćƒŖć‚¢ćƒ³ć¾ćŸćÆę–‡å­—åˆ—ć€‚ + +Puppet 5.0.0ä»„é™ć§ćÆć€ ć‚æć‚¤ćƒ—ć‚·ć‚¹ćƒ†ćƒ ć‚’ä½æē”Øć—ć¦ć„ć‚‹ć»ćØć‚“ć©ć™ć¹ć¦ć®ćƒ‡ćƒ¼ć‚æć‚æć‚¤ćƒ—ć«é–¢ć—ć¦å€¤ć‚’ä½œęˆć§ćć¾ć™ć€‚å†…č”µć®[`Numeric.new`](https://puppet.com/docs/puppet/latest/function.html#conversion-to-numeric)态 [`Integer.new`](https://puppet.com/docs/puppet/latest/function.html#conversion-to-integer)ć€ćŠć‚ˆć³[`Float.new`](https://puppet.com/docs/puppet/latest/function.html#conversion-to-float) +ć®å„é–¢ę•°ć‚’ä½æē”Øć—ć¦ę•°å€¤ć«å¤‰ę›ć§ćć¾ć™ć€‚ + + notice(Integer(false)) # Notices 0 + notice(Float(true)) # Notices 1.0 + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `bool2str` + +ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć§ęä¾›ć•ć‚Œć‚‹å¼•ę•°ć‚’ē”Øć„ć¦ć€ćƒ–ćƒ¼ćƒŖć‚¢ćƒ³ć‚’ę–‡å­—åˆ—ć«å¤‰ę›ć—ć¾ć™ć€‚ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć®ē¬¬2ćŠć‚ˆć³ē¬¬3の引数は、truećŠć‚ˆć³falsećŒćć‚Œćžć‚Œä½•ć«å¤‰ę›ć•ć‚Œć‚‹ć‹ć‚’č”Øć—ć¦ć„ć¾ć™ć€‚äøŽćˆć‚‰ć‚ŒćŸå¼•ę•°ćŒ1ć¤ć ć‘ć®å “åˆćÆć€ćƒ–ćƒ¼ćƒŖć‚¢ćƒ³ć‹ć‚‰`true`または`false`ć‚’å«ć‚€ę–‡å­—åˆ—ć«å¤‰ę›ć•ć‚Œć¾ć™ć€‚ + +*例:* + +```puppet +bool2str(true) => `true` +bool2str(true, 'yes', 'no') => 'yes' +bool2str(false, 't', 'f') => 'f' +``` + +引数: ćƒ–ćƒ¼ćƒŖć‚¢ćƒ³ć€‚ + +Since Puppet 5.0.0, you can create new values for almost any +data type using the type system - you can use the built-in +[`String.new`](https://puppet.com/docs/puppet/latest/function.html#boolean-to-string) +function to convert to String, with many different format options: + + notice(String(false)) # Notices 'false' + notice(String(true)) # Notices 'true' + notice(String(false, '%y')) # Notices 'yes' + notice(String(true, '%y')) # Notices 'no' + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `camelcase` + +**éžęŽØå„Ø:**この関数は、Puppet 6.0.0で、内蔵の[`camelcase`](https://puppet.com/docs/puppet/latest/function.html#camelcase)é–¢ę•°ć«ē½®ćę›ćˆć‚‰ć‚Œć¾ć—ćŸć€‚ + +é…åˆ—å†…ć®1ć¤ć®ę–‡å­—åˆ—ć¾ćŸćÆć™ć¹ć¦ć®ę–‡å­—åˆ—ć®å¤§ę–‡å­—ćØå°ę–‡å­—ć®åˆ„ć‚’CamelCase(å¤§å°ę–‡å­—ę··åœØ)ć«å¤‰ę›ć—ć¾ć™ć€‚ + +引数: é…åˆ—ć¾ćŸćÆę–‡å­—åˆ—ć®ć„ćšć‚Œć‹ć€‚å—ć‘å–ć£ćŸć‚‚ć®ćØåŒć˜ć‚æć‚¤ćƒ—ć®å¼•ę•°ć‚’čæ”ć—ć¾ć™ćŒć€CamelCaseć®å½¢å¼ć§čæ”ć—ć¾ć™ć€‚ + +*注:* この関数はRubyć‚Æćƒ©ć‚¹ć®å®Ÿč£…ć«ć‚ćŸć‚Šć€UTF8ćØć®äŗ’ę›ę€§ćŒćŖć„åÆčƒ½ę€§ćŒć‚ć‚Šć¾ć™ć€‚äŗ’ę›ę€§ć‚’ē¢ŗäæć™ć‚‹ć«ćÆć€Ruby 2.4.0ä»„é™ć§ć“ć®é–¢ę•°ć‚’ä½æē”Øć—ć¦ćć ć•ć„ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `capitalize` + +**éžęŽØå„Ø:**この関数は、Puppet 6.0.0で、内蔵の[`capitalize`](https://puppet.com/docs/puppet/latest/function.html#capitalize)é–¢ę•°ć«ē½®ćę›ćˆć‚‰ć‚Œć¾ć—ćŸć€‚ + +ę–‡å­—åˆ—ć¾ćŸćÆč¤‡ę•°ę–‡å­—åˆ—ć®é…åˆ—ć®ęœ€åˆć®ę–‡å­—ć‚’å¤§ę–‡å­—ć«ć—ć€å„ę–‡å­—åˆ—ć®ę®‹ć‚Šć®ę–‡å­—ć‚’å°ę–‡å­—ć«ć—ć¾ć™ć€‚ + +引数: ć‚¤ćƒ³ćƒ—ćƒƒćƒˆćØć—ć¦ć€å˜äø€ę–‡å­—åˆ—ć¾ćŸćÆé…åˆ—ć€‚*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +*注:* この関数はRubyć‚Æćƒ©ć‚¹ć®å®Ÿč£…ć«ć‚ćŸć‚Šć€UTF8ćØć®äŗ’ę›ę€§ćŒćŖć„åÆčƒ½ę€§ćŒć‚ć‚Šć¾ć™ć€‚äŗ’ę›ę€§ć‚’ē¢ŗäæć™ć‚‹ć«ćÆć€Ruby 2.4.0ä»„é™ć§ć“ć®é–¢ę•°ć‚’ä½æē”Øć—ć¦ćć ć•ć„ć€‚ + +#### `ceiling` + +**éžęŽØå„Ø:**この関数は、Puppet 6.0.0で、内蔵の[`ceiling`](https://puppet.com/docs/puppet/latest/function.html#ceiling)é–¢ę•°ć«ē½®ćę›ćˆć‚‰ć‚Œć¾ć—ćŸć€‚ + +å¼•ę•°ä»„äøŠć®ęœ€å°ę•“ę•°ć‚’čæ”ć—ć¾ć™ć€‚ + +引数: å˜äø€ć®ę•°å€¤ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `chomp` + +**éžęŽØå„Ø:**この関数は、Puppet 6.0.0で、内蔵の[`chomp`](https://puppet.com/docs/puppet/latest/function.html#chomp)é–¢ę•°ć«ē½®ćę›ćˆć‚‰ć‚Œć¾ć—ćŸć€‚ + +ę–‡å­—åˆ—ć¾ćŸćÆč¤‡ę•°ę–‡å­—åˆ—ć®é…åˆ—ć®ęœ€å¾Œć‹ć‚‰ć€ćƒ¬ć‚³ćƒ¼ćƒ‰åˆ†é›¢ę–‡å­—ć‚’å‰Šé™¤ć—ć¾ć™ć€‚ćŸćØćˆć°ć€'hello\n'は'hello'ć«ćŖć‚Šć¾ć™ć€‚ + +引数: å˜äø€ć®ę–‡å­—ć¾ćŸćÆé…åˆ—ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `chop` + +**éžęŽØå„Ø:**この関数は、Puppet 6.0.0で、内蔵の[`chop`](https://puppet.com/docs/puppet/latest/function.html#chop)é–¢ę•°ć«ē½®ćę›ćˆć‚‰ć‚Œć¾ć—ćŸć€‚ + +ęœ€å¾Œć®ę–‡å­—ć‚’å‰Šé™¤ć—ćŸę–°ć—ć„ę–‡å­—åˆ—ć‚’čæ”ć—ć¾ć™ć€‚ę–‡å­—åˆ—ćŒ'\r\n'ć§ēµ‚ć‚ć‚‹å “åˆćÆć€äø”ę–¹ć®ę–‡å­—ćŒå‰Šé™¤ć•ć‚Œć¾ć™ć€‚`chop`ć‚’ē©ŗę–‡å­—åˆ—ć«é©ē”Øć™ć‚‹ćØć€ē©ŗę–‡å­—åˆ—ćŒčæ”ć•ć‚Œć¾ć™ć€‚ćƒ¬ć‚³ćƒ¼ćƒ‰åˆ†é›¢ę–‡å­—ć®ćæć‚’å‰Šé™¤ć™ć‚‹å “åˆćÆć€`chomp`é–¢ę•°ć‚’ä½æē”Øć—ć¦ćć ć•ć„ć€‚ + +引数: ć‚¤ćƒ³ćƒ—ćƒƒćƒˆćØć—ć¦ć€ę–‡å­—åˆ—ć¾ćŸćÆč¤‡ę•°ę–‡å­—åˆ—ć®é…åˆ—ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `clamp` + +ę•“ę•°å€¤ć«åŸŗć„ćåˆ†é”žć«ć‚ˆć‚Šć€å½“č©²é ˜åŸŸ[Min态X态Max]å†…ć§å€¤ć‚’ē¶­ęŒć—ć¾ć™(ćƒ‘ćƒ©ćƒ”ćƒ¼ć‚æć®é †åŗćÆé–¢äæ‚ć‚ć‚Šć¾ć›ć‚“)ć€‚ę–‡å­—åˆ—ćŒå¤‰ę›ć•ć‚Œć€ę•°å­—ćØć—ć¦ęÆ”č¼ƒć•ć‚Œć¾ć™ć€‚å€¤ć®é…åˆ—ćÆć€ć•ć‚‰ćŖć‚‹å‡¦ē†ćŒåÆčƒ½ćŖćƒŖć‚¹ćƒˆć«å¹³å¦åŒ–ć•ć‚Œć¾ć™ć€‚ä¾‹: + + * `clamp('24', [575, 187])`は187を返します。 + * `clamp(16, 88, 661)`は88を返します。 + * `clamp([4, 3, '99'])`は4を返します。 + +引数: ę–‡å­—åˆ—ć€é…åˆ—ć€ę•°å­—ć€‚ + +Puppet 6.0.0ä»„é™ć§ćÆć€å†…č”µć®é–¢ę•°ć‚’ä½æē”Øć—ć¦åŒć˜ēµęžœć‚’å¾—ć‚‹ć“ćØćŒć§ćć¾ć™ć€‚ + + [$minval, $maxval, $value_to_clamp].sort[1] + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `concat` + +č¤‡ę•°é…åˆ—ć®ć‚³ćƒ³ćƒ†ćƒ³ćƒ„ć‚’ć€äøŽćˆć‚‰ć‚ŒćŸęœ€åˆć®é…åˆ—ć«čæ½åŠ ć—ć¾ć™ć€‚ä¾‹: + + * `concat(['1','2','3'],'4')`は['1','2','3','4']を返します。 + * `concat(['1','2','3'],'4',['5','6','7'])`は['1','2','3','4','5','6','7']を返します。 + +Puppet 4.0ä»„é™ć§ćÆć€é…åˆ—ć®é€£ēµćØćƒćƒƒć‚·ćƒ„ć®ćƒžćƒ¼ć‚øć®ćŸć‚ć«`+`演算子を使い、`<<`ę¼”ē®—å­ć‚’ä½æć£ć¦čæ½åŠ ć™ć‚‹ć“ćØćŒć§ćć¾ć™ć€‚ + + ['1','2','3'] + ['4','5','6'] + ['7','8','9'] # returns ['1','2','3','4','5','6','7','8','9'] + [1, 2, 3] << 4 # returns [1, 2, 3, 4] + [1, 2, 3] << [4, 5] # returns [1, 2, 3, [4, 5]] + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `convert_base` + +äøŽćˆć‚‰ć‚ŒćŸę•“ę•°ć¾ćŸćÆę•“ę•°ć‚’č”Øć™10é€²ę•°ę–‡å­—åˆ—ć‚’ć€ęŒ‡å®šć—ćŸåŸŗę•°ć®ę–‡å­—åˆ—ć«å¤‰ę›ć—ć¾ć™ć€‚ä¾‹: + + * `convert_base(5, 2)`は'101'ć«ćŖć‚Šć¾ć™ć€‚ + * `convert_base('254', '16')`は'fe'ć«ćŖć‚Šć¾ć™ć€‚ + +Puppet 4.5.0ä»„é™ć§ćÆć€å†…č”µć®[`String.new`](https://puppet.com/docs/puppet/latest/function.html#integer-to-string)é–¢ę•°ć‚’ä½æć£ć¦ć€ć•ć¾ć–ć¾ćŖå½¢å¼ć®ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć§ć“ć‚Œć‚’č”Œć†ć“ćØćŒć§ćć¾ć™ć€‚ + + $binary_repr = String(5, '%b') # results in "101" + $hex_repr = String(254, '%x') # results in "fe" + $hex_repr = String(254, '%#x') # results in "0xfe" + +#### `count` + +é…åˆ—ć‚’ęœ€åˆć®å¼•ę•°ćØć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć®2ē•Ŗē›®ć®å¼•ę•°ćØč§£é‡ˆć—ć¾ć™ć€‚ +2ē•Ŗē›®ć®å¼•ę•°ć«ē­‰ć—ć„é…åˆ—å†…ć®č¦ē“ ć®ę•°ć‚’ć‚«ć‚¦ćƒ³ćƒˆć—ć¾ć™ć€‚ +é…åˆ—ć®ćæć§å‘¼ć³å‡ŗć•ć‚ŒćŸå “åˆćÆć€nil/undef/empty-stringä»„å¤–ć®č¦ē“ ć®ę•°ć‚’ć‚«ć‚¦ćƒ³ćƒˆć—ć¾ć™ć€‚ + +> **ę³Øę„**: 等値はRubyćƒ”ć‚½ćƒƒćƒ‰ć§ćƒ†ć‚¹ćƒˆć•ć‚Œć¾ć™ć€‚ć“ć‚ŒćÆRubyが +ē­‰å€¤ćØćæćŖć™åÆ¾č±”ć«ćŖć‚Šć¾ć™ć€‚ę–‡å­—åˆ—ć®å “åˆć€ē­‰å€¤ćÆå¤§ę–‡å­—ćØå°ę–‡å­—ć‚’åŒŗåˆ„ć—ć¾ć™ć€‚ + +Puppetコアでは、 内蔵の +[`filter`](https://puppet.com/docs/puppet/latest/function.html#filter) (Puppet 4.0.0仄降)ćŠć‚ˆć³ +[`length`](https://puppet.com/docs/puppet/latest/function.html#length) (Puppet 5.5.0ä»„é™ć€ćć‚Œä»„å‰ć§ćÆstdlib)ć®å„é–¢ę•°ć®ēµ„ćæåˆć‚ć›ć‚’ä½æē”Øć—ć¦ć‚«ć‚¦ćƒ³ćƒˆćŒč”Œć‚ć‚Œć¾ć™ć€‚ + +この例では、`undef`ć§ćŖć„å€¤ć®ć‚«ć‚¦ćƒ³ćƒˆć‚’č”Œć†ę–¹ę³•ć‚’ē¤ŗć—ć¦ć„ć¾ć™ć€‚ + + notice([42, "hello", undef].filter |$x| { $x =~ NotUndef }.length) + +2ć‚’é€šēŸ„ć—ć¾ć™ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `deep_merge` + +2ć¤ä»„äøŠć®ćƒćƒƒć‚·ćƒ„ć‚’å†åø°ēš„ć«ēµ±åˆć—ć€ćć®ēµęžœå¾—ć‚‰ć‚ŒćŸćƒćƒƒć‚·ćƒ„ć‚’čæ”ć—ć¾ć™ć€‚ + +```puppet +$hash1 = {'one' => 1, 'two' => 2, 'three' => { 'four' => 4 } } +$hash2 = {'two' => 'dos', 'three' => { 'five' => 5 } } +$merged_hash = deep_merge($hash1, $hash2) +``` + +å¾—ć‚‰ć‚Œć‚‹ćƒćƒƒć‚·ćƒ„ćÆć€ä»„äø‹ć«ē›øå½“ć—ć¾ć™ć€‚ + +```puppet +$merged_hash = { 'one' => 1, 'two' => 'dos', 'three' => { 'four' => 4, 'five' => 5 } } +``` + +ćƒćƒƒć‚·ćƒ„ć§ć‚ć‚‹é‡č¤‡ć‚­ćƒ¼ćŒå­˜åœØć™ć‚‹å “åˆćÆć€ćć†ć—ćŸé‡č¤‡ć‚­ćƒ¼ćŒå†åø°ēš„ć«ēµ±åˆć•ć‚Œć¾ć™ć€‚ćƒćƒƒć‚·ćƒ„ć§ćÆćŖć„é‡č¤‡ć‚­ćƒ¼ćŒå­˜åœØć™ć‚‹å “åˆćÆć€ęœ€å³ć®ćƒćƒƒć‚·ćƒ„ć®ć‚­ćƒ¼ćŒäøŠä½ć«ćŖć‚Šć¾ć™ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `defined_with_params` + +å±žę€§ć®ćƒŖć‚½ćƒ¼ć‚¹ćƒŖćƒ•ć‚”ćƒ¬ćƒ³ć‚¹ćØć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć§ćƒćƒƒć‚·ćƒ„ć‚’å–å¾—ć—ć¾ć™ć€‚ē‰¹å®šć®å±žę€§ć‚’ęŒć¤ćƒŖć‚½ćƒ¼ć‚¹ćŒć™ć§ć«ć‚«ć‚æćƒ­ć‚°ć«čæ½åŠ ć•ć‚Œć¦ć„ć‚‹å “åˆćÆ`true`ć‚’čæ”ć—ć¾ć™ć€‚ćć†ć§ćŖć„å “åˆćÆ`false`を返します。 + +```puppet +user { 'dan': + ensure => present, +} + +if ! defined_with_params(User[dan], {'ensure' => 'present' }) { + user { 'dan': ensure => present, } +} +``` + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `delete` + +é…åˆ—ć‹ć‚‰ä»»ę„ć®č¦ē“ ć®ć‚¤ćƒ³ć‚¹ć‚æćƒ³ć‚¹ć‚’ć€ę–‡å­—åˆ—ć‹ć‚‰ć‚µćƒ–ć‚¹ćƒˆćƒŖćƒ³ć‚°ć‚’ć€ć¾ćŸćÆćƒćƒƒć‚·ćƒ„ć‹ć‚‰ć‚­ćƒ¼ć‚’ć™ć¹ć¦å‰Šé™¤ć—ć¾ć™ć€‚ + +例:怀 + +* `delete(['a','b','c','b'], 'b')`は['a','c']を返します。 +* `delete('abracadabra', 'bra')`は'acada'を返します。 +* `delete({'a' => 1,'b' => 2,'c' => 3},['b','c'])`は{'a'=> 1}を返します。 +* `delete(['ab', 'b'], 'b')`は['ab']を返します。 + +Puppet 4.0.0ä»„é™ć§ćÆć€ćƒžć‚¤ćƒŠć‚¹(`-`)ę¼”ē®—å­ć«ć‚ˆć£ć¦ć€é…åˆ—ć‹ć‚‰å€¤ć‚’å‰Šé™¤ć—ć€ćƒćƒƒć‚·ćƒ„ć‹ć‚‰ć‚­ćƒ¼ć‚’å‰Šé™¤ć—ć¾ć™ć€‚ + + ['a', 'b', 'c', 'b'] - 'b' + # would return ['a', 'c'] + + {'a'=>1,'b'=>2,'c'=>3} - ['b','c']) + # would return {'a' => '1'} + +内蔵の +[`regsubst`](https://puppet.com/docs/puppet/latest/function.html#regsubst)é–¢ę•°ć§ć€ę–‡å­—åˆ—ć‹ć‚‰ć‚°ćƒ­ćƒ¼ćƒćƒ«å‰Šé™¤ć‚’å®Ÿč”Œć§ćć¾ć™ć€‚ + + 'abracadabra'.regsubst(/bra/, '', 'G') + #は、'acada'を返します。 + +é€šåøøć€å†…č”µć® +[`filter`](https://puppet.com/docs/puppet/latest/function.html#filter) é–¢ę•°ć«ć‚ˆć£ć¦ć€ć‚­ćƒ¼ćØå€¤ćØć®ēµ„ćæåˆć‚ć›ć«åŸŗć„ćć€é…åˆ—ćØćƒćƒƒć‚·ćƒ„ć‹ć‚‰ć‚Øćƒ³ćƒˆćƒŖć‚’ćƒ•ć‚£ćƒ«ć‚æćƒŖćƒ³ć‚°ć§ćć¾ć™ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `delete_at` + +ę±ŗć‚ć‚‰ć‚ŒćŸć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ä»˜ćå€¤ć‚’é…åˆ—ć‹ć‚‰å‰Šé™¤ć—ć¾ć™ć€‚ + +例: `delete_at(['a','b','c'], 1)`は['a','c']を返します。 + +Puppet 4ä»„é™ć§ćÆć€å†…č”µć® +[`filter`](https://puppet.com/docs/puppet/latest/function.html#filter)é–¢ę•°ć‚’ä½æć£ć¦ć€ć“ć‚Œć‚’č”Œć†ć“ćØćŒć§ćć¾ć™ć€‚ + + ['a', 'b', 'c'].filter |$pos, $val | { $pos != 1 } # returns ['a', 'c'] + ['a', 'b', 'c', 'd'].filter |$pos, $val | { $pos % 2 != 0 } # returns ['b', 'd'] + +ć‚ć‚‹ć„ćÆć€é…åˆ—ć®ęœ€åˆć‚‚ć—ććÆęœ€å¾Œć‹ć‚‰ć€ć¾ćŸćÆäø”ē«Æć‹ć‚‰åŒę™‚ć«å‰Šé™¤ć—ćŸć„å “åˆćÆć€ć‚¹ćƒ©ć‚¤ć‚¹ę¼”ē®—å­`[ ]`を使用します。 + + $array[0, -1] # ć™ć¹ć¦ć®å€¤ćØåŒć˜ + $array[2, -1] # ęœ€åˆć®2ć¤ć®č¦ē“ ć‚’é™¤ćć™ć¹ć¦ + $array[0, -3] # ęœ€å¾Œć®2ć¤ć®č¦ē“ ć‚’é™¤ćć™ć¹ć¦ + + $array[1, -2] # ęœ€åˆćØęœ€å¾Œć®č¦ē“ ć‚’é™¤ćć™ć¹ć¦ + + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `delete_regex` + +ęē¤ŗć•ć‚ŒćŸę­£č¦č”Øē¾ć«ćƒžćƒƒćƒć™ć‚‹ä»»ę„ć®č¦ē“ ć®ć‚¤ćƒ³ć‚¹ć‚æćƒ³ć‚¹ć‚’ć€é…åˆ—ć¾ćŸćÆćƒćƒƒć‚·ćƒ„ć‹ć‚‰ć™ć¹ć¦å‰Šé™¤ć—ć¾ć™ć€‚ę–‡å­—åˆ—ćÆ1ć‚¢ć‚¤ćƒ†ćƒ é…åˆ—ćØć—ć¦å‡¦ē†ć•ć‚Œć¾ć™ć€‚ + +*注:* この関数はRubyć‚Æćƒ©ć‚¹ć®å®Ÿč£…ć«ć‚ćŸć‚Šć€UTF8ćØć®äŗ’ę›ę€§ćŒćŖć„åÆčƒ½ę€§ćŒć‚ć‚Šć¾ć™ć€‚äŗ’ę›ę€§ć‚’ē¢ŗäæć™ć‚‹ć«ćÆć€Ruby 2.4.0ä»„é™ć§ć“ć®é–¢ę•°ć‚’ä½æē”Øć—ć¦ćć ć•ć„ć€‚ + + +例 + +* `delete_regex(['a','b','c','b'], 'b')`は['a','c']を返します。 +* `delete_regex({'a' => 1,'b' => 2,'c' => 3},['b','c'])`は{'a'=> 1}を返します。 +* `delete_regex(['abf', 'ab', 'ac'], '^ab.*')`は['ac']を返します。 +* `delete_regex(['ab', 'b'], 'b')`は['ab']を返します。 + +Puppet 4.0.0ä»„é™ć§ćÆć€å†…č”µć®[`filter`](https://puppet.com/docs/puppet/latest/function.html#filter)é–¢ę•°ć§åŒē­‰ć®å‡¦ē†ć‚’č”Œć„ć¾ć™ć€‚ + + ["aaa", "aba", "aca"].filter |$val| { $val !~ /b/ } + # ['aaa', 'aca']を返します + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `delete_values` + +ä»»ę„ć®å€¤ć®ć‚¤ćƒ³ć‚¹ć‚æćƒ³ć‚¹ć‚’ćƒćƒƒć‚·ćƒ„ć‹ć‚‰ć™ć¹ć¦å‰Šé™¤ć—ć¾ć™ć€‚ + +例:怀 + +* `delete_values({'a'=>'A','b'=>'B','c'=>'C','B'=>'D'}, 'B')`は{'a'=>'A','c'=>'C','B'=>'D'}を返します。 + +Puppet 4.0.0ä»„é™ć§ćÆć€å†…č”µć®[`filter`](https://puppet.com/docs/puppet/latest/function.html#filter)é–¢ę•°ć§åŒē­‰ć®å‡¦ē†ć‚’č”Œć„ć¾ć™ć€‚ + + $array.filter |$val| { $val != 'B' } + $hash.filter |$key, $val| { $val != 'B' } + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `delete_undef_values` + +`undef`å€¤ć®ć‚¤ćƒ³ć‚¹ć‚æćƒ³ć‚¹ć‚’ć‚¢ćƒ¬ć‚¤ć¾ćŸćÆćƒćƒƒć‚·ćƒ„ć‹ć‚‰ć™ć¹ć¦å‰Šé™¤ć—ć¾ć™ć€‚ + +例:怀 + +* `$hash = delete_undef_values({a=>'A', b=>'', c=>`undef`, d => false})`は{a => 'A', b => '', d => false}を返します。 + +Puppet 4.0.0ä»„é™ć§ćÆć€å†…č”µć®[`filter`](https://puppet.com/docs/puppet/latest/function.html#filter)é–¢ę•°ć§åŒē­‰ć®å‡¦ē†ć‚’č”Œć„ć¾ć™ć€‚ + + $array.filter |$val| { $val =~ NotUndef } + $hash.filter |$key, $val| { $val =~ NotUndef } + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `deprecation` + +éžęŽØå„Øč­¦å‘Šć‚’ćƒ—ćƒŖćƒ³ćƒˆć—ć€ä»»ę„ć®ć‚­ćƒ¼ć«ć¤ć„ć¦č­¦å‘Šć‚’äø€åŗ¦čØ˜éŒ²ć—ć¾ć™: + +```puppet +deprecation(key, message) +``` + +引数: + +* ć‚­ćƒ¼ć‚’ęŒ‡å®šć™ć‚‹ę–‡å­—åˆ—: Puppetćƒ—ćƒ­ć‚»ć‚¹ć®ē¶™ē¶šęœŸé–“äø­ć«ćƒ”ćƒƒć‚»ćƒ¼ć‚øć®ę•°ć‚’å°‘ćŖćęŠ‘ćˆć‚‹ćŸć‚ć«ć€1ć¤ć®ć‚­ćƒ¼ć«ć¤ć1ć¤ć®ćƒ”ćƒƒć‚»ćƒ¼ć‚øć®ćæć‚’čØ˜éŒ²ć—ć¾ć™ć€‚ +* ćƒ”ćƒƒć‚»ćƒ¼ć‚øć‚’ęŒ‡å®šć™ć‚‹ę–‡å­—åˆ—: čØ˜éŒ²ć•ć‚Œć‚‹ćƒ†ć‚­ć‚¹ćƒˆć€‚ + +*ć‚æć‚¤ćƒ—*: ć‚¹ćƒ†ćƒ¼ćƒˆćƒ”ćƒ³ćƒˆ + +**`deprecation`ć«å½±éŸæć‚’äøŽćˆć‚‹čØ­å®š** + +Puppetć®ä»–ć®čØ­å®šćÆć€stdlib恮`deprecation`é–¢ę•°ć«å½±éŸæć‚’äøŽćˆć¾ć™ć€‚ + +* [`disable_warnings`](https://puppet.com/docs/puppet/latest/configuration.html#disablewarnings) +* [`max_deprecations`](https://puppet.com/docs/puppet/latest/configuration.html#maxdeprecations) +* [`strict`](https://puppet.com/docs/puppet/latest/configuration.html#strict): + + * `error`: éžęŽØå„Øćƒ”ćƒƒć‚»ćƒ¼ć‚øć«ć‚ˆć‚Šć€ćŸć ć”ć«ę©Ÿčƒ½ć—ćŖććŖć‚Šć¾ć™ć€‚ + * `off`: ćƒ”ćƒƒć‚»ćƒ¼ć‚øćŒć‚¢ć‚¦ćƒˆćƒ—ćƒƒćƒˆć•ć‚Œć¾ć›ć‚“ć€‚ + * `warning`: ć™ć¹ć¦ć®č­¦å‘Šć‚’čØ˜éŒ²ć—ć¾ć™ć€‚ć“ć‚ŒćŒćƒ‡ćƒ•ć‚©ćƒ«ćƒˆčØ­å®šć§ć™ć€‚ + +* ē’°å¢ƒå¤‰ę•°`STDLIB_LOG_DEPRECATIONS` + + éžęŽØå„Øč­¦å‘Šć‚’čØ˜éŒ²ć™ć‚‹ć‹ć©ć†ć‹ć‚’ęŒ‡å®šć—ć¾ć™ć€‚ć“ć‚ŒćÆē‰¹ć«ć€č‡Ŗå‹•ćƒ†ć‚¹ćƒˆć®éš›ć€ē§»č”Œć®ęŗ–å‚™ćŒć§ćć‚‹å‰ć«ćƒ­ć‚°ć«ęƒ…å ±ćŒę°¾ęæ«ć™ć‚‹ć®ć‚’éæć‘ć‚‹ć†ćˆć§å½¹ē«‹ć”ć¾ć™ć€‚ + + ć“ć®å¤‰ę•°ćÆćƒ–ćƒ¼ćƒŖć‚¢ćƒ³ć§ć€ä»„äø‹ć®åŠ¹ęžœćŒć‚ć‚Šć¾ć™: + + * `true`: č­¦å‘Šć‚’čØ˜éŒ²ć—ć¾ć™ć€‚ + * `false`: č­¦å‘ŠćÆčØ˜éŒ²ć•ć‚Œć¾ć›ć‚“ć€‚ + * å€¤ć‚’čØ­å®šć—ćŖć„å “åˆ: Puppet 4ćÆč­¦å‘Šć‚’å‡ŗć—ć¾ć™ćŒć€Puppet 3は出しません。 + +#### `difference` + +2ć¤ć®é…åˆ—ć®é–“ć®å·®ē•°ć‚’čæ”ć—ć¾ć™ć€‚čæ”ć•ć‚Œć‚‹é…åˆ—ćÆć‚ŖćƒŖć‚øćƒŠćƒ«é…åˆ—ć®ć‚³ćƒ”ćƒ¼ć§ć€ē¬¬2ć®é…åˆ—ć«ć‚‚č¦‹ć‚‰ć‚Œć‚‹ć‚¢ć‚¤ćƒ†ćƒ ćŒć‚ć‚Œć°ć€ćć‚ŒćŒå–ć‚Šé™¤ć‹ć‚Œć¾ć™ć€‚ + +例:怀 + +* `difference(["a","b","c"],["b","c","d"])`は["a"]を返します。 + +Puppet 4ä»„é™ć§ćÆć€PuppetčØ€čŖžć®ćƒžć‚¤ćƒŠć‚¹(`-`)ę¼”ē®—å­ćÆåŒć˜ć“ćØć‚’č”Œć„ć¾ć™ć€‚ + + ['a', 'b', 'c'] - ['b', 'c', 'd'] + # ['a']を返します + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `dig` + +**éžęŽØå„Ø:**この関数は、Puppet 4.5.0で、内蔵の[`dig`](https://puppet.com/docs/puppet/latest/function.html#dig)é–¢ę•°ć«ē½®ćę›ćˆć‚‰ć‚Œć¾ć—ćŸć€‚äø‹ä½äŗ’ę›ę€§ć‚’å¾—ć‚‹ć«ćÆć€[`dig44()`](#dig44)ć‚’ä½æē”Øć™ć‚‹ć‹ć€ę–°ć—ć„ćƒćƒ¼ć‚øćƒ§ćƒ³ć‚’ä½æē”Øć—ć¦ćć ć•ć„ć€‚ + +ćƒ‘ć‚¹ć‚’å«ć‚€ć‚­ćƒ¼é…åˆ—ć‚’é€šć˜ć¦ć€č¤‡ę•°ćƒ¬ć‚¤ćƒ¤ćƒ¼ć®ćƒćƒƒć‚·ćƒ„ćŠć‚ˆć³ć‚¢ćƒ¬ć‚¤å†…ć®å€¤ć‚’ęŽ¢ć—ć¾ć™ć€‚ć“ć®é–¢ę•°ćÆå„ćƒ‘ć‚¹ć‚³ćƒ³ćƒćƒ¼ćƒćƒ³ćƒˆć«ć‚ˆć‚Šę§‹é€ å†…ć‚’ē§»å‹•ć—ć€ćƒ‘ć‚¹ć®ęœ€å¾Œć§å€¤ć‚’čæ”ć™ć‚ˆć†č©¦ćæć¾ć™ć€‚ + +ć“ć®é–¢ę•°ć§ćÆć€åæ…č¦ćØć•ć‚Œć‚‹ćƒ‘ć‚¹å¼•ę•°ć«åŠ ćˆć€ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆć®å¼•ę•°ć‚’ä½æē”Øć§ćć¾ć™ć€‚ćƒ‘ć‚¹ćŒę­£ć—ććŖć„å “åˆć‚„ć€å€¤ćŒč¦‹ć¤ć‹ć‚‰ćŖć„å “åˆć€ćć®ä»–ć®ć‚Øćƒ©ćƒ¼ćŒē”Ÿć˜ćŸå “åˆćÆć€ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆć®å¼•ę•°ć‚’čæ”ć—ć¾ć™ć€‚ + +```ruby +$data = { + 'a' => { + 'b' => [ + 'b1', + 'b2', + 'b3', + ] + } +} + +$value = dig($data, ['a', 'b', 2]) +# $value = 'b3' + +# with all possible options +$value = dig($data, ['a', 'b', 2], 'not_found') +# $value = 'b3' + +# using the default value +$value = dig($data, ['a', 'b', 'c', 'd'], 'not_found') +# $value = 'not_found' +``` + +1. **$data** å–ć‚Šę‰±ć†ćƒ‡ćƒ¼ć‚æę§‹é€ ć€‚ +2. **['a', 'b', 2]** ćƒ‘ć‚¹é…åˆ—ć€‚ +3. **'not_found'** ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆå€¤ć€‚ä½•ć‚‚č¦‹ć¤ć‹ć‚‰ćŖć„å “åˆć«čæ”ć•ć‚Œć¾ć™ć€‚ + +ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆå€¤: `undef`怂 + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `dig44` + +ćƒ‘ć‚¹ć‚’å«ć‚€ć‚­ćƒ¼é…åˆ—ć‚’é€šć˜ć¦ć€č¤‡ę•°ćƒ¬ć‚¤ćƒ¤ćƒ¼ć®ćƒćƒƒć‚·ćƒ„ćŠć‚ˆć³ć‚¢ćƒ¬ć‚¤å†…ć®å€¤ć‚’ęŽ¢ć—ć¾ć™ć€‚ć“ć®é–¢ę•°ćÆå„ćƒ‘ć‚¹ć‚³ćƒ³ćƒćƒ¼ćƒćƒ³ćƒˆć«ć‚ˆć‚Šę§‹é€ å†…ć‚’ē§»å‹•ć—ć€ćƒ‘ć‚¹ć®ęœ€å¾Œć§å€¤ć‚’čæ”ć™ć‚ˆć†č©¦ćæć¾ć™ć€‚ + +ć“ć®é–¢ę•°ć§ćÆć€åæ…č¦ćØć•ć‚Œć‚‹ćƒ‘ć‚¹å¼•ę•°ć«åŠ ćˆć€ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆć®å¼•ę•°ć‚’ä½æē”Øć§ćć¾ć™ć€‚ćƒ‘ć‚¹ćŒę­£ć—ććŖć„å “åˆć‚„ć€å€¤ćŒč¦‹ć¤ć‹ć‚‰ćŖć„å “åˆć€ćć®ä»–ć®ć‚Øćƒ©ćƒ¼ćŒē”Ÿć˜ćŸå “åˆćÆć€ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆć®å¼•ę•°ć‚’čæ”ć—ć¾ć™ć€‚ + +```ruby +$data = { + 'a' => { + 'b' => [ + 'b1', + 'b2', + 'b3', + ] + } +} + +$value = dig44($data, ['a', 'b', 2]) +# $value = 'b3' + +# with all possible options +$value = dig44($data, ['a', 'b', 2], 'not_found') +# $value = 'b3' + +# using the default value +$value = dig44($data, ['a', 'b', 'c', 'd'], 'not_found') +# $value = 'not_found' +``` + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +1. **$data** å–ć‚Šę‰±ć†ćƒ‡ćƒ¼ć‚æę§‹é€ ć€‚ +2. **['a', 'b', 2]** ćƒ‘ć‚¹é…åˆ—ć€‚ +3. **'not_found'** ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆå€¤ć€‚ä½•ć‚‚č¦‹ć¤ć‹ć‚‰ćŖć„å “åˆć«čæ”ć•ć‚Œć¾ć™ć€‚ + (ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć€ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆćÆ`undef`) + +#### `dirname` + +ćƒ‘ć‚¹ć®`dirname`ć‚’čæ”ć—ć¾ć™ć€‚ćŸćØćˆć°ć€`dirname('/path/to/a/file.ext')`は'/path/to/a'を返します。 + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `dos2unix` + +äøŽćˆć‚‰ć‚ŒćŸę–‡å­—åˆ—ć®Unixćƒćƒ¼ć‚øćƒ§ćƒ³ć‚’čæ”ć—ć¾ć™ć€‚ć‚Æćƒ­ć‚¹ćƒ—ćƒ©ćƒƒćƒˆćƒ•ć‚©ćƒ¼ćƒ ćƒ†ćƒ³ćƒ—ćƒ¬ćƒ¼ćƒˆć§ćƒ•ć‚”ć‚¤ćƒ«ćƒŖć‚½ćƒ¼ć‚¹ć‚’ä½æē”Øć™ć‚‹å “åˆć«éžåøøć«å½¹ē«‹ć”ć¾ć™ć€‚ + +```puppet +file { $config_file: + ensure => file, + content => dos2unix(template('my_module/settings.conf.erb')), +} +``` + +[unix2dos](#unix2dos)ć‚‚å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `downcase` + +**éžęŽØå„Ø:**この関数は、Puppet 5.5.0で、内蔵の[`downcase`](https://puppet.com/docs/puppet/latest/function.html#downcase)é–¢ę•°ć«ē½®ćę›ćˆć‚‰ć‚Œć¾ć—ćŸć€‚ + +é…åˆ—å†…ć®1ć¤ć®ę–‡å­—åˆ—ć¾ćŸćÆć™ć¹ć¦ć®ę–‡å­—åˆ—ć®å¤§ę–‡å­—ćØå°ę–‡å­—ć®åˆ„ć‚’ć€å°ę–‡å­—ć«å¤‰ę›ć—ć¾ć™ć€‚ + +*注:* この関数はRubyć‚Æćƒ©ć‚¹ć®å®Ÿč£…ć«ć‚ćŸć‚Šć€UTF8ćØć®äŗ’ę›ę€§ćŒćŖć„åÆčƒ½ę€§ćŒć‚ć‚Šć¾ć™ć€‚äŗ’ę›ę€§ć‚’ē¢ŗäæć™ć‚‹ć«ćÆć€Ruby 2.4.0ä»„é™ć§ć“ć®é–¢ę•°ć‚’ä½æē”Øć—ć¦ćć ć•ć„ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `empty` + +**éžęŽØå„Ø:**この関数は、Puppet 5.5.0で、内蔵の[`empty`](https://puppet.com/docs/puppet/latest/function.html#empty)é–¢ę•°ć«ē½®ćę›ćˆć‚‰ć‚Œć¾ć—ćŸć€‚ + +å¼•ę•°ćŒč¦ē“ ć‚’å«ć¾ćŖć„é…åˆ—ć‹ćƒćƒƒć‚·ćƒ„ć€ć¾ćŸćÆē©ŗę–‡å­—åˆ—ć§ć‚ć‚‹å “åˆć«ć€`true`ć‚’čæ”ć—ć¾ć™ć€‚å¼•ę•°ćŒę•°å€¤ć®å “åˆć«`false`を返します。 + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `enclose_ipv6` + +IPć‚¢ćƒ‰ćƒ¬ć‚¹ć®é…åˆ—ć‚’å–å¾—ć—ć€ipv6ć‚¢ćƒ‰ćƒ¬ć‚¹ć‚’å¤§ę‹¬å¼§ć§ććć‚Šć¾ć™ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `ensure_packages` + +é…åˆ—ć¾ćŸćÆćƒćƒƒć‚·ćƒ„å†…ć®ćƒ‘ćƒƒć‚±ćƒ¼ć‚øć®ćƒŖć‚¹ćƒˆć‚’å–å¾—ć—ć€ć™ć§ć«å­˜åœØć—ćŖć„å “åˆć«ć®ćæć€ćć‚Œć‚‰ć‚’ć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ«ć—ć¾ć™ć€‚ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć§ć€ćƒćƒƒć‚·ćƒ„ć‚’ē¬¬2ć®ćƒ‘ćƒ©ćƒ”ćƒ¼ć‚æćØć—ć¦å–å¾—ć—ć€ē¬¬3の引数として`ensure_resource()`または `ensure_resources()`関数に渔します。 + +*ć‚æć‚¤ćƒ—*: ć‚¹ćƒ†ćƒ¼ćƒˆćƒ”ćƒ³ćƒˆ + +é…åˆ—ć®å “åˆ: + +```puppet +ensure_packages(['ksh','openssl'], {'ensure' => 'present'}) +``` + +ćƒćƒƒć‚·ćƒ„ć®å “åˆ: + +```puppet +ensure_packages({'ksh' => { ensure => '20120801-1' } , 'mypackage' => { source => '/tmp/myrpm-1.0.0.x86_64.rpm', provider => "rpm" }}, {'ensure' => 'present'}) +``` + +#### `ensure_resource` + +ćƒŖć‚½ćƒ¼ć‚¹ć‚æć‚¤ćƒ—ć€ć‚æć‚¤ćƒˆćƒ«ć€ćƒŖć‚½ćƒ¼ć‚¹ć‚’čØ˜čæ°ć™ć‚‹å±žę€§ć®ćƒćƒƒć‚·ćƒ„ć‚’å–å¾—ć—ć¾ć™ć€‚ + +``` +user { 'dan': + ensure => present, +} +``` + +ć“ć®ä¾‹ć§ćÆć€ć™ć§ć«å­˜åœØć—ćŖć„å “åˆć«ć®ćæćƒŖć‚½ćƒ¼ć‚¹ćŒä½œęˆć•ć‚Œć¾ć™: + + `ensure_resource('user', 'dan', {'ensure' => 'present' })` + +ćƒŖć‚½ćƒ¼ć‚¹ćŒć™ć§ć«å­˜åœØć—ć¦ć„ć‚‹ć‚‚ć®ć®ć€ęŒ‡å®šć•ć‚ŒćŸćƒ‘ćƒ©ćƒ”ćƒ¼ć‚æćØćƒžćƒƒćƒć—ćŖć„å “åˆćÆć€ćƒŖć‚½ćƒ¼ć‚¹ć®å†ä½œęˆćŒč©¦ćæć‚‰ć‚Œć€é‡č¤‡ćƒŖć‚½ćƒ¼ć‚¹å®šē¾©ć‚Øćƒ©ćƒ¼ć«ć¤ćŖćŒć‚Šć¾ć™ć€‚ + +ćƒŖć‚½ćƒ¼ć‚¹ć®é…åˆ—ć‚’ęē¤ŗć™ć‚‹ć“ćØć‚‚åÆčƒ½ć§ć™ć€‚ćć‚Œćžć‚Œć®ćƒŖć‚½ćƒ¼ć‚¹ćÆć€ć™ć§ć«å­˜åœØć—ćŖć„å “åˆć«ć€ęŒ‡å®šć®ć‚æć‚¤ćƒ—ćŠć‚ˆć³ćƒ‘ćƒ©ćƒ”ćƒ¼ć‚æć«ć‚ˆć‚Šä½œęˆć•ć‚Œć¾ć™ć€‚ + +`ensure_resource('user', ['dan','alex'], {'ensure' => 'present'})` + +*ć‚æć‚¤ćƒ—*: ć‚¹ćƒ†ćƒ¼ćƒˆćƒ”ćƒ³ćƒˆ + +#### `ensure_resources` + +ćƒćƒƒć‚·ćƒ„ć‹ć‚‰ćƒŖć‚½ćƒ¼ć‚¹å®£čØ€ć‚’ä½œęˆć—ć¾ć™ćŒć€ć™ć§ć«å®£čØ€ć•ć‚Œć¦ć„ć‚‹ćƒŖć‚½ćƒ¼ć‚¹ćØćÆåÆ¾ē«‹ć—ć¾ć›ć‚“ć€‚ + +ćƒŖć‚½ćƒ¼ć‚¹ć‚æć‚¤ćƒ—ć€ć‚æć‚¤ćƒˆćƒ«ć€ćƒŖć‚½ćƒ¼ć‚¹ć‚’čØ˜čæ°ć™ć‚‹å±žę€§ć®ćƒćƒƒć‚·ćƒ„ć‚’ęŒ‡å®šć—ć¾ć™ć€‚ + +```puppet +user { 'dan': + gid => 'mygroup', + ensure => present, +} + +ensure_resources($user) +``` + +ćƒŖć‚½ćƒ¼ć‚¹ć®ćƒćƒƒć‚·ćƒ„ć‚’ęē¤ŗć—ć¾ć™ć€‚ćƒŖć‚¹ćƒˆć«ć‚ć‚‹ćƒŖć‚½ćƒ¼ć‚¹ćÆć€ć™ć§ć«å­˜åœØć—ćŖć„å “åˆć«ć€ęŒ‡å®šć®ć‚æć‚¤ćƒ—ćŠć‚ˆć³ćƒ‘ćƒ©ćƒ”ćƒ¼ć‚æć«ć‚ˆć‚Šä½œęˆć•ć‚Œć¾ć™ć€‚ + + ensure_resources('user', {'dan' => { gid => 'mygroup', uid => '600' } , 'alex' => { gid => 'mygroup' }}, {'ensure' => 'present'}) + +Hieraćƒćƒƒć‚Æć‚Øćƒ³ćƒ‰ć‹ć‚‰: + +```yaml +userlist: + dan: + gid: 'mygroup' + uid: '600' + alex: + gid: 'mygroup' +``` + +```puppet +ensure_resources('user', hiera_hash('userlist'), {'ensure' => 'present'}) +``` + +#### `fact` + +ęŒ‡å®šć•ć‚ŒćŸfactć®å€¤ć‚’čæ”ć—ć¾ć™ć€‚ę§‹é€ åŒ–ć•ć‚ŒćŸfactć‚’å‚ē…§ć™ć‚‹å “åˆć«ćƒ‰ćƒƒćƒˆč”ØčØ˜ć‚’ä½æē”Øć™ć‚‹ć“ćØćŒć§ćć¾ć™ć€‚ęŒ‡å®šć•ć‚ŒćŸfactćŒå­˜åœØć—ćŖć„å “åˆćÆć€Undefを返します。 + +使用例: + +```puppet +fact('kernel') +fact('osfamily') +fact('os.architecture') +``` + +é…åˆ—ć®ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹: + +```puppet +$first_processor = fact('processors.models.0') +$second_processor = fact('processors.models.1') +``` + +åå‰ć«ć€Œ.ć€ć‚’å«ć‚€fact: + +```puppet +fact('vmware."VRA.version"') +``` + +#### `flatten` + +**éžęŽØå„Ø:**この関数は、Puppet 5.5.0で、内蔵の[`flatten`](https://puppet.com/docs/puppet/latest/function.html#flatten)é–¢ę•°ć«ē½®ćę›ćˆć‚‰ć‚Œć¾ć—ćŸć€‚ + +ćƒć‚¹ćƒˆć®ę·±ć„ć‚¢ćƒ¬ć‚¤ć‚’å¹³å¦åŒ–ć—ć€ēµęžœćØć—ć¦å˜äø€ć®ćƒ•ćƒ©ćƒƒćƒˆé…åˆ—ć‚’čæ”ć—ć¾ć™ć€‚ + +ćŸćØćˆć°ć€`flatten(['a', ['b', ['c']]])`は['a','b','c']を返します。 + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `floor` + +**éžęŽØå„Ø:**この関数は、Puppet 5.5.0で、内蔵の[`floor`](https://puppet.com/docs/puppet/latest/function.html#floor)é–¢ę•°ć«ē½®ćę›ćˆć‚‰ć‚Œć¾ć—ćŸć€‚ + +å¼•ę•°ä»„äø‹ć®ęœ€å¤§ę•“ę•°ć‚’čæ”ć—ć¾ć™ć€‚ + +引数: å˜äø€ć®ę•°å€¤ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `fqdn_rand_string` + +ćƒ©ćƒ³ćƒ€ćƒ ćŖč‹±ę•°å­—ę–‡å­—åˆ—ć‚’ē”Ÿęˆć—ć¾ć™ć€‚`$fqdn` factćØć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć®ć‚·ćƒ¼ćƒ‰ć‚’ēµ„ćæåˆć‚ć›ć‚‹ćØć€åå¾©ēš„ćŖē„”ä½œē‚ŗęŠ½å‡ŗćŒåÆčƒ½ć§ć™ć€‚ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć§ć€ć“ć®é–¢ę•°ć«ä½æē”Øć™ć‚‹ę–‡å­—ć‚»ćƒƒćƒˆć‚’ęŒ‡å®šć™ć‚‹ć“ćØć‚‚ć§ćć¾ć™(ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆćÆč‹±ę•°å­—)怂 + +*使用例:* + +```puppet +fqdn_rand_string(LENGTH, [CHARSET], [SEED]) +``` + +*例:* + +```puppet +fqdn_rand_string(10) +fqdn_rand_string(10, 'ABCDEF!@#$%^') +fqdn_rand_string(10, '', 'custom seed') +``` + +引数: + +* ę•“ę•°ć€å¾—ć‚‰ć‚Œć‚‹ę–‡å­—åˆ—ć®é•·ć•ć‚’ęŒ‡å®šć€‚ +* ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć§ć€ę–‡å­—ć‚»ćƒƒćƒˆć‚’ęŒ‡å®šć™ć‚‹ę–‡å­—åˆ—ć€‚ +* ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć§ć€åå¾©ēš„ćŖē„”ä½œē‚ŗęŠ½å‡ŗć‚’åÆčƒ½ć«ć™ć‚‹ć‚·ćƒ¼ćƒ‰ć‚’ęŒ‡å®šć™ć‚‹ę–‡å­—åˆ—ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `fqdn_rotate` + +é…åˆ—ćØę–‡å­—åˆ—ć‚’ćƒ©ćƒ³ćƒ€ćƒ ćŖå›žę•°ć§å›žč»¢ć•ć›ć¾ć™ć€‚`$fqdn` factćØć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć®ć‚·ćƒ¼ćƒ‰ć‚’ēµ„ćæåˆć‚ć›ć‚‹ćØć€åå¾©ēš„ćŖē„”ä½œē‚ŗęŠ½å‡ŗćŒåÆčƒ½ć§ć™ć€‚ + +*使用例:* + +```puppet +fqdn_rotate(VALUE, [SEED]) +``` + +*例:* + +```puppet +fqdn_rotate(['a', 'b', 'c', 'd']) +fqdn_rotate('abcd') +fqdn_rotate([1, 2, 3], 'custom seed') +``` + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `fqdn_uuid` + +DNSćƒćƒ¼ćƒ ć‚¹ćƒšćƒ¼ć‚¹ć®FQDNę–‡å­—åˆ—ć‚’ć‚‚ćØć«ć€[RFC 4122](https://tools.ietf.org/html/rfc4122)ęœ‰åŠ¹ćƒćƒ¼ć‚øćƒ§ćƒ³5 UUIDを返します: + + * fqdn_uuid('puppetlabs.com')は'9c70320f-6815-5fc5-ab0f-debe68bf764c'を返します。 + * fqdn_uuid('google.com')は'64ee70a4-8cc1-5d25-abf2-dea6c79a09c8'を返します。 + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `get_module_path` + +ē¾åœØć®ē’°å¢ƒć«ć¤ć„ć¦ć€ęŒ‡å®šć•ć‚ŒćŸćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ć®ēµ¶åÆ¾ćƒ‘ć‚¹ć‚’čæ”ć—ć¾ć™ć€‚ + +```puppet +$module_path = get_module_path('stdlib') +``` + +Puppet 5.4.0ä»„é™ć§ćÆć€å†…č”µć® [`module_directory`](https://puppet.com/docs/puppet/latest/function.html#module_directory)é–¢ę•°ćÆåŒć˜ć“ćØć‚’č”Œć„ć€č¤‡ę•°ć®å€¤ć¾ćŸćÆé…åˆ—ćŒäøŽćˆć‚‰ć‚Œć¦ć„ć‚‹å “åˆć€ęœ€åˆć«č¦‹ć¤ć‹ć£ćŸćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ćøć®ćƒ‘ć‚¹ć‚’čæ”ć—ć¾ć™ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `getparam` +ćƒŖć‚½ćƒ¼ć‚¹ć®ćƒ‘ćƒ©ćƒ”ćƒ¼ć‚æć®å€¤ć‚’čæ”ć—ć¾ć™ć€‚ + +引数: ćƒŖć‚½ćƒ¼ć‚¹ćƒŖćƒ•ć‚”ćƒ¬ćƒ³ć‚¹ćŠć‚ˆć³ćƒ‘ćƒ©ćƒ”ćƒ¼ć‚æć®åå‰ć€‚ + +> ę³Øę„: ćƒ¦ćƒ¼ć‚¶å®šē¾©ć®ćƒŖć‚½ćƒ¼ć‚¹ć‚æć‚¤ćƒ—ćÆé…ć‚Œć¦č©•ä¾”ć•ć‚Œć¾ć™ć€‚ + +*例:* + +```puppet +# define a resource type with a parameter +define example_resource($param) { +} + +# declare an instance of that type +example_resource { "example_resource_instance": + param => "'the value we are getting in this example''" +} + +# Because of order of evaluation, a second definition is needed +# that will be evaluated after the first resource has been declared +# +define example_get_param { + # This will notice the value of the parameter + notice(getparam(Example_resource["example_resource_instance"], "param")) +} + +# Declare an instance of the second resource type - this will call notice +example_get_param { 'show_notify': } +``` + +'ć“ć®ä¾‹ć§å–å¾—ć—ć¦ć„ć‚‹å€¤'ć‚’é€šēŸ„ć—ć¾ć™ + +Puppet 4.0.0ä»„é™ć§ćÆć€ćƒ‡ćƒ¼ć‚æć‚æć‚¤ćƒ— +と[ ]ę¼”ē®—å­ć‚’ä½æē”Øć—ć¦ćƒ‘ćƒ©ćƒ”ćƒ¼ć‚æå€¤ć‚’å–å¾—ć§ćć¾ć™ć€‚ę¬”ć®ä¾‹ćÆć€getparam()ć®å‘¼ć³å‡ŗć—ćØåŒć˜ć§ć™ć€‚ + +```puppet +Example_resource['example_resource_instance']['param'] +``` + +#### `getvar` +**éžęŽØå„Ø:** この関数は、Puppet 6.0.0で、内蔵の[`getvar`](https://puppet.com/docs/puppet/latest/function.html#getvar) +é–¢ę•°ć«ē½®ćę›ćˆć‚‰ć‚Œć¾ć—ćŸć€‚ę–°ć—ć„ćƒćƒ¼ć‚øćƒ§ćƒ³ć§ć‚‚ć€ę§‹é€ åŒ–ć•ć‚ŒćŸå€¤ćøć®ęŽ˜ć‚Šäø‹ć’ćŒć‚µćƒćƒ¼ćƒˆć•ć‚Œć¾ć™ć€‚ + +ćƒŖćƒ¢ćƒ¼ćƒˆćƒćƒ¼ćƒ ć‚¹ćƒšćƒ¼ć‚¹ć®å¤‰ę•°ć‚’čŖæć¹ć¾ć™ć€‚ + +例:怀 + +```puppet +$foo = getvar('site::data::foo') +# $foo = $site::data::fooćØåŒē­‰ +``` + +ć“ć®é–¢ę•°ćÆć€ćƒćƒ¼ćƒ ć‚¹ćƒšćƒ¼ć‚¹ćć®ć‚‚ć®ćŒę–‡å­—åˆ—ć«äæå­˜ć•ć‚Œć¦ć„ć‚‹å “åˆć«å½¹ē«‹ć”ć¾ć™: + +```puppet +$datalocation = 'site::data' +$bar = getvar("${datalocation}::bar") +# Equivalent to $bar = $site::data::bar +``` + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `glob` + +ćƒ‘ć‚¹ćƒ‘ć‚æćƒ¼ćƒ³ć«äø€č‡“ć™ć‚‹ćƒ‘ć‚¹ć®ę–‡å­—åˆ—é…åˆ—ć‚’čæ”ć—ć¾ć™ć€‚ + +引数: ćƒ‘ć‚¹ćƒ‘ć‚æćƒ¼ćƒ³ć‚’ęŒ‡å®šć™ć‚‹ę–‡å­—åˆ—ć¾ćŸćÆę–‡å­—åˆ—é…åˆ—ć€‚ + +```puppet +$confs = glob(['/etc/**/*.conf', '/opt/**/*.conf']) +``` + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `grep` + +é…åˆ—å†…ć‚’ę¤œē“¢ć—ć€ęē¤ŗć•ć‚ŒćŸę­£č¦č”Øē¾ć«äø€č‡“ć™ć‚‹č¦ē“ ć‚’čæ”ć—ć¾ć™ć€‚ + +ćŸćØćˆć°ć€`grep(['aaa','bbb','ccc','aaaddd'], 'aaa')`は['aaa','aaaddd']を返します。 + +Puppet 4.0.0ä»„é™ć§ćÆć€å†…č”µć®[`filter`](https://puppet.com/docs/puppet/latest/function.html#filter)é–¢ę•°ćÆåŒć˜ć“ćØć‚’č”Œć„ć¾ć™ć€‚ę­£č¦č”Øē¾ćØćÆåÆ¾ē…§ēš„ć«ć€ć©ć®ćƒ­ć‚øćƒƒć‚Æć§ć‚‚ćƒ•ć‚£ćƒ«ć‚æćƒŖćƒ³ć‚°ć«ä½æē”Øć§ćć¾ć™ć€‚ + + ['aaa', 'bbb', 'ccc', 'aaaddd']. filter |$x| { $x =~ 'aaa' } + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `has_interface_with` + +ēØ®é”žćŠć‚ˆć³å€¤ć«åŸŗć„ććƒ–ćƒ¼ćƒŖć‚¢ćƒ³ć‚’čæ”ć—ć¾ć™: + + * macaddress + * netmask + * ipaddress + * network + +*例:* + +```puppet +has_interface_with("macaddress", "x:x:x:x:x:x") +has_interface_with("ipaddress", "127.0.0.1") => true +``` + +ēØ®é”žćŒęē¤ŗć•ć‚Œć¦ć„ćŖć„å “åˆćÆć€ć‚¤ćƒ³ć‚æćƒ¼ćƒ•ć‚§ćƒ¼ć‚¹ć®ęœ‰ē„”ćŒē¢ŗčŖć•ć‚Œć¾ć™: + +```puppet +has_interface_with("lo") => true +``` + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `has_ip_address` + +äø€éƒØć®ć‚¤ćƒ³ć‚æćƒ¼ćƒ•ć‚§ćƒ¼ć‚¹äøŠć§ć€ćƒŖć‚Æć‚Øć‚¹ćƒˆć•ć‚ŒćŸIPć‚¢ćƒ‰ćƒ¬ć‚¹ćŒć‚Æćƒ©ć‚¤ć‚¢ćƒ³ćƒˆć«å­˜åœØć™ć‚‹å “åˆćÆ`true`を返します。この関数は`interfaces` factć§åå¾©ć•ć‚Œć€`ipaddress_IFACE` factsć‚’ćƒć‚§ćƒƒć‚Æć—ć€ē°”å˜ćŖę–‡å­—åˆ—ęÆ”č¼ƒć‚’å®Ÿč”Œć—ć¾ć™ć€‚ + +引数: IPć‚¢ćƒ‰ćƒ¬ć‚¹ć‚’ęŒ‡å®šć™ć‚‹ę–‡å­—åˆ—ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `has_ip_network` + +ćƒŖć‚Æć‚Øć‚¹ćƒˆć•ć‚ŒćŸćƒćƒƒćƒˆćƒÆćƒ¼ć‚Æå†…ć§IPć‚¢ćƒ‰ćƒ¬ć‚¹ćŒć‚Æćƒ©ć‚¤ć‚¢ćƒ³ćƒˆć«å­˜åœØć™ć‚‹å “åˆćÆ`true`を返します。この関数は`interfaces` factć§åå¾©ć•ć‚Œć€ `network_IFACE` factsć‚’ćƒć‚§ćƒƒć‚Æć—ć€ē°”å˜ćŖę–‡å­—åˆ—ęÆ”č¼ƒć‚’å®Ÿč”Œć—ć¾ć™ć€‚ + +引数: IPć‚¢ćƒ‰ćƒ¬ć‚¹ć‚’ęŒ‡å®šć™ć‚‹ę–‡å­—åˆ—ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `has_key` +**éžęŽØå„Ø:** この関数は、内蔵の`in`ę¼”ē®—å­ć«ē½®ćę›ćˆć‚‰ć‚Œć¾ć—ćŸć€‚ + +ćƒćƒƒć‚·ćƒ„ć«ē‰¹å®šć®ć‚­ćƒ¼å€¤ćŒć‚ć‚‹ć‹ć©ć†ć‹ć‚’åˆ¤å®šć—ć¾ć™ć€‚ + +*例*: + +``` +$my_hash = {'key_one' => 'value_one'} +if has_key($my_hash, 'key_two') { + notice('we will not reach here') +} +if has_key($my_hash, 'key_one') { + notice('this will be printed') +} +``` + +Puppet 4.0.0ä»„é™ć§ćÆć€ć“ć‚ŒćÆć€PuppetčØ€čŖžć«ćŠć„ć¦ć€ę¬”ć®åŒē­‰ć®å¼ć‚’ē”Øć„ć¦å®Ÿē¾ć§ćć¾ć™ć€‚ + + $my_hash = {'key_one' => 'value_one'} + if 'key_one' in $my_hash { + notice('this will be printed') + } + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `hash` + +**éžęŽØå„Ø:** ć“ć®é–¢ę•°ćÆć€ć»ćØć‚“ć©ć™ć¹ć¦ć®ćƒ‡ćƒ¼ć‚æć‚æć‚¤ćƒ—ć®ę–°ć—ć„å€¤ć‚’ä½œęˆć™ć‚‹å†…č”µć®ę©Ÿčƒ½ć«ē½®ćę›ćˆć‚‰ć‚Œć¾ć—ćŸć€‚ +Puppetに内蔵の[`Hash.new`](https://puppet.com/docs/puppet/latest/function.html#conversion-to-hash-and-struct)é–¢ę•°ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +é…åˆ—ć‚’ćƒćƒƒć‚·ćƒ„ć«å¤‰ę›ć—ć¾ć™ć€‚ + +ä¾‹ćˆć°(éžęŽØå„Ø)态`hash(['a',1,'b',2,'c',3])`は、 {'a'=>1,'b'=>2,'c'=>3}を返します。 + +ä¾‹ćˆć°(内蔵)态`Hash(['a',1,'b',2,'c',3])`は、{'a'=>1,'b'=>2,'c'=>3}を返します。 + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `intersection` + +2ć¤ć®å…±é€šéƒØåˆ†ć®é…åˆ—ć‚’čæ”ć—ć¾ć™ć€‚ + +ćŸćØćˆć°ć€`intersection(["a","b","c"],["b","c","d"])`は["b","c"]を返します。 + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `is_a` + +ćƒ–ćƒ¼ćƒŖć‚¢ćƒ³ćƒć‚§ćƒƒć‚Æć«ć‚ˆć‚Šć€å¤‰ę•°ćŒä»»ę„ć®ćƒ‡ćƒ¼ć‚æć‚æć‚¤ćƒ—ć®ć‚‚ć®ć‹ć©ć†ć‹ć‚’åˆ¤å®šć—ć¾ć™ć€‚ć“ć‚ŒćÆ`=~`ć‚æć‚¤ćƒ—ćƒć‚§ćƒƒć‚Æć«ē›øå½“ć—ć¾ć™ć€‚ć“ć®é–¢ę•°ćÆPuppet 4と、"future"ćƒ‘ćƒ¼ć‚µćƒ¼ć‚’å‚™ćˆćŸPuppet 3ć§ć®ćæä½æē”Øć§ćć¾ć™ć€‚ + +``` +foo = 3 +$bar = [1,2,3] +$baz = 'A string!' + +if $foo.is_a(Integer) { + notify { 'foo!': } +} +if $bar.is_a(Array) { + notify { 'bar!': } +} +if $baz.is_a(String) { + notify { 'baz!': } +} +``` + +* ć‚æć‚¤ćƒ—ć«é–¢ć™ć‚‹č©³ē“°ćÆć€[Puppetć‚æć‚¤ćƒ—ć‚·ć‚¹ćƒ†ćƒ ](https://puppet.com/docs/puppet/latest/lang_data.html)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ +* å€¤ć®ć‚æć‚¤ćƒ—ć‚’ē‰¹å®šć™ć‚‹å„ēØ®ć®ę–¹ę³•ć«ć¤ć„ć¦ćÆć€[`assert_type()`](https://puppet.com/docs/puppet/latest/function.html#asserttype)é–¢ę•°ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +#### `is_absolute_path` + +**éžęŽØå„Ø:**ä»Šå¾Œć®ćƒćƒ¼ć‚øćƒ§ćƒ³ć®stdlibć§ćÆå‰Šé™¤ć•ć‚Œć¾ć™ć€‚[`validate_legacy`](#validate_legacy)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +äøŽćˆć‚‰ć‚ŒćŸćƒ‘ć‚¹ćŒēµ¶åÆ¾ćƒ‘ć‚¹ć§ć‚ć‚‹å “åˆć«`true`を返します。 + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `is_array` + +**éžęŽØå„Ø:**ä»Šå¾Œć®ćƒćƒ¼ć‚øćƒ§ćƒ³ć®stdlibć§ćÆå‰Šé™¤ć•ć‚Œć¾ć™ć€‚[`validate_legacy`](#validate_legacy)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +ć“ć®é–¢ę•°ć«ęø”ć•ć‚ŒćŸå¤‰ę•°ćŒé…åˆ—ć§ć‚ć‚‹å “åˆć«`true`を返します。 + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `is_bool` + +**éžęŽØå„Ø:**ä»Šå¾Œć®ćƒćƒ¼ć‚øćƒ§ćƒ³ć®stdlibć§ćÆå‰Šé™¤ć•ć‚Œć¾ć™ć€‚[`validate_legacy`](#validate_legacy)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +ć“ć®é–¢ę•°ć«ęø”ć•ć‚ŒćŸå¤‰ę•°ćŒćƒ–ćƒ¼ćƒŖć‚¢ćƒ³ć§ć‚ć‚‹å “åˆć«`true`を返します。 + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `is_domain_name` + +**éžęŽØå„Ø:**ä»Šå¾Œć®ćƒćƒ¼ć‚øćƒ§ćƒ³ć®stdlibć§ćÆå‰Šé™¤ć•ć‚Œć¾ć™ć€‚[`validate_legacy`](#validate_legacy)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +ć“ć®é–¢ę•°ć«ęø”ć•ć‚ŒćŸę–‡å­—åˆ—ćŒę§‹ę–‡ēš„ć«ę­£ć—ć„ćƒ‰ćƒ”ć‚¤ćƒ³åć§ć‚ć‚‹å “åˆć«`true`を返します。 + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `is_email_address` + +ć“ć®é–¢ę•°ć«ęø”ć•ć‚ŒćŸę–‡å­—åˆ—ćŒęœ‰åŠ¹ćŖćƒ”ćƒ¼ćƒ«ć‚¢ćƒ‰ćƒ¬ć‚¹ć§ć‚ć‚‹å “åˆć«trueを返します。 + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + + +#### `is_float` + +**éžęŽØå„Ø:**ä»Šå¾Œć®ćƒćƒ¼ć‚øćƒ§ćƒ³ć®stdlibć§ćÆå‰Šé™¤ć•ć‚Œć¾ć™ć€‚[`validate_legacy`](#validate_legacy)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +ć“ć®é–¢ę•°ć«ęø”ć•ć‚ŒćŸå¤‰ę•°ćŒćƒ•ćƒ­ćƒ¼ćƒˆåž‹ć§ć‚ć‚‹å “åˆć«`true`を返します。 + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `is_function_available` + +**éžęŽØå„Ø:**ä»Šå¾Œć®ćƒćƒ¼ć‚øćƒ§ćƒ³ć®stdlibć§ćÆå‰Šé™¤ć•ć‚Œć¾ć™ć€‚[`validate_legacy`](#validate_legacy)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +ę–‡å­—åˆ—ć‚’å¼•ę•°ćØć—ć¦å—ć‘å…„ć‚Œć€Puppetćƒ©ćƒ³ć‚æć‚¤ćƒ ćŒćć®åå‰ć‚’ē”Øć„ć¦é–¢ę•°ć«ć‚¢ć‚Æć‚»ć‚¹ć§ćć‚‹ć‹ć©ć†ć‹ć‚’åˆ¤å®šć—ć¾ć™ć€‚é–¢ę•°ćŒå­˜åœØć™ć‚‹å “åˆćÆ`true`ć€å­˜åœØć—ćŖć„å “åˆćÆ`false`を返します。 + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `is_hash` + +**éžęŽØå„Ø:**ä»Šå¾Œć®ćƒćƒ¼ć‚øćƒ§ćƒ³ć®stdlibć§ćÆå‰Šé™¤ć•ć‚Œć¾ć™ć€‚[`validate_legacy`](#validate_legacy)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +ć“ć®é–¢ę•°ć«ęø”ć•ć‚ŒćŸå¤‰ę•°ćŒćƒćƒƒć‚·ćƒ„ć§ć‚ć‚‹å “åˆć«`true`を返します。 + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `is_integer` + +**éžęŽØå„Ø:**ä»Šå¾Œć®ćƒćƒ¼ć‚øćƒ§ćƒ³ć®stdlibć§ćÆå‰Šé™¤ć•ć‚Œć¾ć™ć€‚[`validate_legacy`](#validate_legacy)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +ć“ć®ę–‡å­—åˆ—ć«čæ”ć•ć‚ŒćŸå¤‰ę•°ćŒę•“ę•°ć§ć‚ć‚‹å “åˆć«`true`を返します。 + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `is_ip_address` + +**éžęŽØå„Ø:**ä»Šå¾Œć®ćƒćƒ¼ć‚øćƒ§ćƒ³ć®stdlibć§ćÆå‰Šé™¤ć•ć‚Œć¾ć™ć€‚[`validate_legacy`](#validate_legacy)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +ć“ć®é–¢ę•°ć«ęø”ć•ć‚ŒćŸę–‡å­—åˆ—ćŒęœ‰åŠ¹ćŖIPć‚¢ćƒ‰ćƒ¬ć‚¹ć§ć‚ć‚‹å “åˆć«`true`を返します。 + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `is_ipv6_address` + +**éžęŽØå„Ø:**ä»Šå¾Œć®ćƒćƒ¼ć‚øćƒ§ćƒ³ć®stdlibć§ćÆå‰Šé™¤ć•ć‚Œć¾ć™ć€‚[`validate_legacy`](#validate_legacy)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +ć“ć®é–¢ę•°ć«ęø”ć•ć‚ŒćŸę–‡å­—åˆ—ćŒęœ‰åŠ¹ćŖIPv6ć‚¢ćƒ‰ćƒ¬ć‚¹ć§ć‚ć‚‹å “åˆć«`true`を返します。 + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `is_ipv4_address` + +**éžęŽØå„Ø:**ä»Šå¾Œć®ćƒćƒ¼ć‚øćƒ§ćƒ³ć®stdlibć§ćÆå‰Šé™¤ć•ć‚Œć¾ć™ć€‚[`validate_legacy`](#validate_legacy)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +ć“ć®é–¢ę•°ć«ęø”ć•ć‚ŒćŸę–‡å­—åˆ—ćŒęœ‰åŠ¹ćŖIPv4ć‚¢ćƒ‰ćƒ¬ć‚¹ć§ć‚ć‚‹å “åˆć«`true`を返します。 + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `is_mac_address` + +ć“ć®é–¢ę•°ć«ęø”ć•ć‚ŒćŸę–‡å­—åˆ—ćŒęœ‰åŠ¹ćŖMACć‚¢ćƒ‰ćƒ¬ć‚¹ć§ć‚ć‚‹å “åˆć«`true`を返します。 + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `is_numeric` + +**éžęŽØå„Ø:**ä»Šå¾Œć®ćƒćƒ¼ć‚øćƒ§ćƒ³ć®stdlibć§ćÆå‰Šé™¤ć•ć‚Œć¾ć™ć€‚[`validate_legacy`](#validate_legacy)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +ć“ć®é–¢ę•°ć«ęø”ć•ć‚ŒćŸå¤‰ę•°ćŒę•°å­—ć§ć‚ć‚‹å “åˆć«`true`を返します。 + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `is_string` + +**éžęŽØå„Ø:**ä»Šå¾Œć®ćƒćƒ¼ć‚øćƒ§ćƒ³ć®stdlibć§ćÆå‰Šé™¤ć•ć‚Œć¾ć™ć€‚[`validate_legacy`](#validate_legacy)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +ć“ć®é–¢ę•°ć«ęø”ć•ć‚ŒćŸå¤‰ę•°ćŒę–‡å­—åˆ—ć§ć‚ć‚‹å “åˆć«`true`を返します。 + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `join` + +**éžęŽØå„Ø:** この関数は、Puppet 5.5.0で、内蔵の[`join`](https://puppet.com/docs/puppet/latest/function.html#join)é–¢ę•°ć«ē½®ćę›ćˆć‚‰ć‚Œć¾ć—ćŸć€‚ + +åŒŗåˆ‡ć‚Šę–‡å­—ć‚’ē”Øć„ć¦ć€é…åˆ—ć‚’ę–‡å­—åˆ—ć«ēµåˆć—ć¾ć™ć€‚ćŸćØćˆć°ć€`join(['a','b','c'], ",")`は"a,b,c"ć«ćŖć‚Šć¾ć™ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `join_keys_to_values` + +åŒŗåˆ‡ć‚Šę–‡å­—ć‚’ē”Øć„ć¦ć€ćƒćƒƒć‚·ćƒ„ć®å„ć‚­ćƒ¼ć‚’ćć®ć‚­ćƒ¼ć«åÆ¾åæœć™ć‚‹å€¤ćØēµåˆć—ć€ēµęžœć‚’ę–‡å­—åˆ—ćØć—ć¦čæ”ć—ć¾ć™ć€‚ + +å€¤ćŒé…åˆ—ć®å “åˆćÆć€ć‚­ćƒ¼ćÆå„č¦ē“ ć®å‰ć«ē½®ć‹ć‚Œć¾ć™ć€‚čæ”ć•ć‚Œć‚‹å€¤ćÆć€å¹³å¦åŒ–ć—ćŸé…åˆ—ć«ćŖć‚Šć¾ć™ć€‚ + +ćŸćØćˆć°ć€`join_keys_to_values({'a'=>1,'b'=>[2,3]}, " is ")`は["a is 1","b is 2","b is 3"]ć«ćŖć‚Šć¾ć™ć€‚ + +Puppet 5.0.0ä»„é™ć§ćÆć€ę›øå¼ć®åˆ¶å¾”ćŒå¼·åŒ–ć•ć‚Œć¦ć„ć¾ć™ļ¼ˆć‚¤ćƒ³ćƒ‡ćƒ³ćƒˆć‚„ę”¹č”Œć€é…åˆ—ćØćƒćƒƒć‚·ćƒ„ć‚Øćƒ³ćƒˆćƒŖć€ćƒćƒƒć‚·ćƒ„ć‚Øćƒ³ćƒˆćƒŖć®ć‚­ćƒ¼/å€¤ć®é–“ć®åŒŗåˆ‡ć‚Šć€é…åˆ—ć«ćŠć‘ć‚‹å€¤ć®å€‹ć€…ć® +ę›øå¼ćŖć©)。内蔵の[`String.new`](https://docs.puppet.com/puppet/latest/function.html#conversion-to-string)é–¢ę•°ć€ćŠć‚ˆć³`配列`と`ćƒćƒƒć‚·ćƒ„`ć®ę›øå¼čØ­å®šć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `keys` + +**éžęŽØå„Ø:** この関数は、Puppet 5.5.0で、内蔵の[`keys`](https://puppet.com/docs/puppet/latest/function.html#keys)é–¢ę•°ć«ē½®ćę›ćˆć‚‰ć‚Œć¾ć—ćŸć€‚ + +ćƒćƒƒć‚·ćƒ„ć®ć‚­ćƒ¼ć‚’é…åˆ—ćØć—ć¦čæ”ć—ć¾ć™ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `length` + +**éžęŽØå„Ø:** この関数は、Puppet 5.5.0で、内蔵の[`length`](https://puppet.com/docs/puppet/latest/function.html#length)é–¢ę•°ć«ē½®ćę›ćˆć‚‰ć‚Œć¾ć—ćŸć€‚ + +äøŽćˆć‚‰ć‚ŒćŸę–‡å­—åˆ—ć€é…åˆ—ć€ćƒćƒƒć‚·ćƒ„ć®é•·ć•ć‚’čæ”ć—ć¾ć™ć€‚å»ƒę­¢ć•ć‚ŒćŸ`size()`é–¢ę•°ć«ä»£ć‚ć‚‹ć‚‚ć®ć§ć™ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `loadyaml` + +é…åˆ—ć€ę–‡å­—åˆ—ć€ćƒćƒƒć‚·ćƒ„ć‚’å«ć‚€YAMLćƒ•ć‚”ć‚¤ćƒ«ć‚’ćƒ­ćƒ¼ćƒ‰ć—ć€åÆ¾åæœć™ć‚‹ćƒć‚¤ćƒ†ć‚£ćƒ–ćƒ‡ćƒ¼ć‚æć‚æć‚¤ćƒ—ć§ćƒ‡ćƒ¼ć‚æć‚’čæ”ć—ć¾ć™ć€‚ + +例:怀 + +```puppet +$myhash = loadyaml('/etc/puppet/data/myhash.yaml') +``` + +第2ć®ćƒ‘ćƒ©ćƒ”ćƒ¼ć‚æćÆć€ćƒ•ć‚”ć‚¤ćƒ«ćŒč¦‹ć¤ć‹ć‚‰ćŖć‹ć£ćŸå “åˆć€ć¾ćŸćÆę§‹ę–‡č§£ęžć§ććŖć‹ć£ćŸå “åˆć«čæ”ć•ć‚Œć¾ć™ć€‚ + +例:怀 + +```puppet +$myhash = loadyaml('no-file.yaml', {'default'=>'value'}) +``` + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `loadjson` + +é…åˆ—ć€ę–‡å­—åˆ—ć€ćƒćƒƒć‚·ćƒ„ć‚’å«ć‚€JSONćƒ•ć‚”ć‚¤ćƒ«ć‚’ćƒ­ćƒ¼ćƒ‰ć—ć€åÆ¾åæœć™ć‚‹ćƒć‚¤ćƒ†ć‚£ćƒ–ćƒ‡ćƒ¼ć‚æć‚æć‚¤ćƒ—ć§ćƒ‡ćƒ¼ć‚æć‚’čæ”ć—ć¾ć™ć€‚ + +例:怀 + +ęœ€åˆć®ćƒ‘ćƒ©ćƒ”ćƒ¼ć‚æćÆć€ēµ¶åÆ¾ćƒ•ć‚”ć‚¤ćƒ«ćƒ‘ć‚¹ć¾ćŸćÆURL恧恙怂 + +```puppet +$myhash = loadjson('/etc/puppet/data/myhash.json') +``` + +第2ć®ćƒ‘ćƒ©ćƒ”ćƒ¼ć‚æćÆć€ćƒ•ć‚”ć‚¤ćƒ«ćŒč¦‹ć¤ć‹ć‚‰ćŖć‹ć£ćŸå “åˆć€ć¾ćŸćÆę§‹ę–‡č§£ęžć§ććŖć‹ć£ćŸå “åˆć«čæ”ć•ć‚Œć¾ć™ć€‚ + +例:怀 + +```puppet + $myhash = loadjson('no-file.json', {'default'=>'value'}) + ``` + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `load_module_metadata` + +ć‚æćƒ¼ć‚²ćƒƒćƒˆćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ć®metadata.jsonć‚’ćƒ­ćƒ¼ćƒ‰ć—ć¾ć™ć€‚ćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ć®ćƒćƒ¼ć‚øćƒ§ćƒ³ć‚„ć€ćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ć®å‹•ēš„ć‚µćƒćƒ¼ćƒˆć«é–¢ć™ć‚‹ć‚Ŗćƒ¼ć‚µćƒ¼ć‚·ćƒƒćƒ—ć®åˆ¤å®šć«ä½æē”Øć§ćć¾ć™ć€‚ + +```puppet +$metadata = load_module_metadata('archive') +notify { $metadata['author']: } +``` + +ćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ć®ćƒ”ć‚æćƒ‡ćƒ¼ć‚æćƒ•ć‚”ć‚¤ćƒ«ćŒå­˜åœØć—ćŖć„å “åˆć€ć‚«ć‚æćƒ­ć‚°ć‚³ćƒ³ćƒ‘ć‚¤ćƒ«ć«å¤±ę•—ć—ć¾ć™ć€‚ć“ć‚Œć‚’éæć‘ć‚‹ę–¹ę³•ćÆć€ä»„äø‹ć®ćØćŠć‚Šć§ć™: + +``` +$metadata = load_module_metadata('mysql', true) +if empty($metadata) { + notify { "ć“ć®ćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ć«ćÆmetadata.jsonćƒ•ć‚”ć‚¤ćƒ«ćŒć‚ć‚Šć¾ć›ć‚“ć€‚": } +} +``` + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `lstrip` + +**éžęŽØå„Ø:** この関数は、Puppet 6.0.0で、内蔵の[`lstrip`](https://puppet.com/docs/puppet/latest/function.html#lstrip) é–¢ę•°ć«ē½®ćę›ćˆć‚‰ć‚Œć¾ć—ćŸć€‚ + +ę–‡å­—åˆ—ć®å·¦å“ć®ć‚¹ćƒšćƒ¼ć‚¹ć‚’å–ć‚Šé™¤ćć¾ć™ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `max` + +**éžęŽØå„Ø:** この関数は、Puppet 6.0.0で、内蔵の[`max`](https://puppet.com/docs/puppet/latest/function.html#max) é–¢ę•°ć«ē½®ćę›ćˆć‚‰ć‚Œć¾ć—ćŸć€‚ + +ć™ć¹ć¦ć®å¼•ę•°ć®ęœ€å¤§å€¤ć‚’čæ”ć—ć¾ć™ć€‚å°‘ćŖććØć‚‚1ć¤ć®å¼•ę•°ćŒåæ…č¦ć§ć™ć€‚ + +引数: ę•°å­—ć¾ćŸćÆę•°å­—ć‚’č”Øć™ę–‡å­—åˆ—ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `member` + +å¤‰ę•°ćŒé…åˆ—ć®ę§‹ęˆč¦ē“ ć‹ć©ć†ć‹ć‚’åˆ¤å®šć—ć¾ć™ć€‚å¤‰ę•°ć«ćÆę–‡å­—åˆ—ć€é…åˆ—ć€fixnumćŒä½æē”Øć§ćć¾ć™ć€‚ + +ćŸćØćˆć°ć€`member(['a','b'], 'b')`ćŠć‚ˆć³`member(['a','b','c'], ['b','c'])`は`true`を返し、`member(['a','b'], 'c')`ćŠć‚ˆć³`member(['a','b','c'], ['c','d'])`は`false`を返します。 + +*注*: ć“ć®é–¢ę•°ćÆć€ćƒć‚¹ćƒˆåŒ–ć—ćŸé…åˆ—ć«ćÆåÆ¾åæœć—ć¦ć„ć¾ć›ć‚“ć€‚ęœ€åˆć®å¼•ę•°ć«ćƒć‚¹ćƒˆåŒ–ć—ćŸé…åˆ—ćŒå«ć¾ć‚Œć¦ć„ć‚‹å “åˆćÆć€å†åø°ēš„å‡¦ē†ćÆč”Œć‚ć‚Œć¾ć›ć‚“ć€‚ + +Puppet 4.0.0ä»„é™ć§ćÆć€PuppetčØ€čŖžć«ćŠć„ć¦åŒć˜ć“ćØć‚’å®Ÿč”Œć§ćć¾ć™ć€‚å€¤ćŒå˜äø€ć®å “åˆć«ćÆć€ +`in`演算子を使用します。 + + 'a' in ['a', 'b'] # true + +ć¾ćŸć€é…åˆ—ć®å “åˆć«ćÆć€`-`演算子を使用してdiffć‚’čØˆē®—ć—ć¾ć™ć€‚ + + ['d', 'b'] - ['a', 'b', 'c'] == [] # 'd'ćŒęø›ē®—ć•ć‚ŒćŖć„ćŸć‚ć€false + ['a', 'b'] - ['a', 'b', 'c'] == [] # 'a'と'b'ć®äø”ę–¹ćŒęø›ē®—ć•ć‚Œć‚‹ćŸć‚ć€true + +ć¾ćŸć€Puppet 5.2.0ä»„é™ć§ćÆć€é…åˆ—ć‚„ćƒćƒƒć‚·ćƒ„ć®å†…å®¹ć‚’ćƒ†ć‚¹ćƒˆć™ć‚‹äø€čˆ¬ēš„ćŖå½¢å¼ćÆć€å†…č”µć•ć‚Œć¦ć„ć‚‹[`any`](https://puppet.com/docs/puppet/latest/function.html#any)ćŠć‚ˆć³[`all`](https://puppet.com/docs/puppet/latest/function.html#all)の各関数を使用することです。 + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `merge` + +2ć¤ä»„äøŠć®ćƒćƒƒć‚·ćƒ„ć‚’ēµ±åˆć—ć€ćć®ēµęžœå¾—ć‚‰ć‚ŒćŸćƒćƒƒć‚·ćƒ„ć‚’čæ”ć—ć¾ć™ć€‚ + +*例*: + +```puppet +$hash1 = {'one' => 1, 'two' => 2} +$hash2 = {'two' => 'dos', 'three' => 'tres'} +$merged_hash = merge($hash1, $hash2) +# The resulting hash is equivalent to: +# $merged_hash = {'one' => 1, 'two' => 'dos', 'three' => 'tres'} +``` + +é‡č¤‡ć‚­ćƒ¼ćŒå­˜åœØć™ć‚‹å “åˆćÆć€ęœ€å³ć®ćƒćƒƒć‚·ćƒ„ć®ć‚­ćƒ¼ćŒäøŠä½ć«ćŖć‚Šć¾ć™ć€‚ + +Puppet 4.0.0ä»„é™ć§ćÆć€+ ę¼”ē®—å­ć‚’ä½æē”Øć—ć¦åŒć˜ćƒžćƒ¼ć‚øć‚’å®Ÿč”Œć™ć‚‹ć“ćØćŒć§ćć¾ć™ć€‚ + + $merged_hash = $hash1 + $hash2 + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `min` + +**éžęŽØå„Ø:** この関数は、Puppet 6.0.0で、内蔵の[`min`](https://puppet.com/docs/puppet/latest/function.html#min)é–¢ę•°ć«ē½®ćę›ćˆć‚‰ć‚Œć¾ć—ćŸć€‚ + +ć™ć¹ć¦ć®å¼•ę•°ć®ęœ€å°å€¤ć‚’čæ”ć—ć¾ć™ć€‚å°‘ćŖććØć‚‚1ć¤ć®å¼•ę•°ćŒåæ…č¦ć§ć™ć€‚ + +引数: ę•°å­—ć¾ćŸćÆę•°å­—ć‚’č”Øć™ę–‡å­—åˆ—ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `num2bool` + +ę•°å­—ć¾ćŸćÆę•°å­—ć®ę–‡å­—åˆ—č”Øē¾ć‚’ę­£å½“ćŖćƒ–ćƒ¼ćƒŖć‚¢ćƒ³ć«å¤‰ę›ć—ć¾ć™ć€‚0ć¾ćŸćÆéžę•°å­—ćÆ`false`ć«ćŖć‚Šć¾ć™ć€‚0ć‚ˆć‚Šå¤§ćć„ę•°å­—ćÆ`true`ć«ćŖć‚Šć¾ć™ć€‚ + +Puppet 5.0.0ä»„é™ć§ćÆć€ć‚æć‚¤ćƒ—ć‚·ć‚¹ćƒ†ćƒ ć‚’ä½æē”Øć—ć¦åŒć˜ć“ćØćŒč”Œćˆć¾ć™ć€‚ +åˆ©ē”ØåÆčƒ½ćŖå¤šćć®ć‚æć‚¤ćƒ—å¤‰ę›ć«ć¤ć„ć¦ćÆć€Puppet恮[`Boolean.new`](https://puppet.com/docs/puppet/latest/function.html#conversion-to-boolean) +é–¢ę•°ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + + Boolean(0) # false + Boolean(1) # true + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `parsejson` + +JSONć®ę–‡å­—åˆ—ć‚’ę­£ē¢ŗćŖPuppetę§‹é€ ć«å¤‰ę›ć—ć¾ć™(ćƒćƒƒć‚·ćƒ„ć€é…åˆ—ć€ę–‡å­—åˆ—ć€ę•“ę•°ć€ć¾ćŸćÆćć‚Œć‚‰ć®ēµ„ćæåˆć‚ć›ćØć—ć¦)怂 + +引数: +* 第1ć®å¼•ę•°ćØć—ć¦ć€å¤‰ę›ć•ć‚Œć‚‹JSONę–‡å­—åˆ—ć€‚ +* ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć§ć€ē¬¬2ć®ć‚Øćƒ©ćƒ¼ćØć—ć¦ć€å¤‰ę›ć«å¤±ę•—ć—ćŸå “åˆć«čæ”ć•ć‚Œć‚‹ēµęžœć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `parseyaml` + +YAMLć®ę–‡å­—åˆ—ć‚’ę­£ē¢ŗćŖPuppetę§‹é€ ć«å¤‰ę›ć—ć¾ć™ć€‚ + +引数: +* 第1ć®å¼•ę•°ćØć—ć¦ć€å¤‰ę›ć•ć‚Œć‚‹YAMLę–‡å­—åˆ—ć€‚ +* ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć§ć€ē¬¬2ć®ć‚Øćƒ©ćƒ¼ćØć—ć¦ć€å¤‰ę›ć«å¤±ę•—ć—ćŸå “åˆć«čæ”ć•ć‚Œć‚‹ēµęžœć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `pick` + +å€¤ć®ćƒŖć‚¹ćƒˆć‹ć‚‰ć€ęœŖå®šē¾©ć¾ćŸćÆē©ŗę–‡å­—åˆ—ć§ćÆćŖć„ęœ€åˆć®å€¤ć‚’čæ”ć—ć¾ć™ć€‚å¼•ę•°ć‹ć‚‰ä»»ę„ć®ę•°å­—ć‚’ćØć‚Šć€ć™ć¹ć¦ć®å€¤ćŒęœŖå®šē¾©ć¾ćŸćÆē©ŗć®å “åˆćÆć‚Øćƒ©ćƒ¼ćŒē”Ÿć˜ć¾ć™ć€‚ + +```puppet +$real_jenkins_version = pick($::jenkins_version, '1.449') +``` + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `pick_default` + +å€¤ć®ćƒŖć‚¹ćƒˆć«ć‚ć‚‹ęœ€åˆć®å€¤ć‚’čæ”ć—ć¾ć™ć€‚`pick()`é–¢ę•°ćØćÆē•°ćŖć‚Šć€`pick_default()`ćÆć€ć™ć¹ć¦ć®å¼•ę•°ćŒē©ŗć®å “åˆć‚‚å¤±ę•—ć«ćÆćŖć‚Šć¾ć›ć‚“ć€‚ćć®ćŸć‚ć€ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆćØć—ć¦ē©ŗć®å€¤ć‚’ä½æē”Øć§ćć¾ć™ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `prefix` + +é…åˆ—ć®ć™ć¹ć¦ć®č¦ē“ ć€ć¾ćŸćÆćƒćƒƒć‚·ćƒ„ć®ć‚­ćƒ¼ć«ęŽ„é ­č¾žć‚’é©ē”Øć—ć¾ć™ć€‚ + +例:怀 + +* `prefix(['a','b','c'], 'p')`は['pa','pb','pc']を返します。 +* `prefix({'a'=>'b','b'=>'c','c'=>'d'}, 'p')`は{'pa'=>'b','pb'=>'c','pc'=>'d'}を返します。 + +Puppet 4.0.0ä»„é™ć§ćÆć€å†…č”µć®[`map`](https://docs.puppet.com/puppet/latest/function.html#map)é–¢ę•°ć‚’ä½æē”Øć—ć¦é…åˆ—ć®å€¤ć‚’å¤‰ę›“ć—ć¾ć™ć€‚ +ć“ć®ä¾‹ćÆć€äøŠčØ˜ć®ęœ€åˆć®ä¾‹ćØåŒć˜ć§ć™ć€‚ + + ['a', 'b', 'c'].map |$x| { "p${x}" } + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `pry` + +ē¾åœØć®ć‚¹ć‚³ćƒ¼ćƒ—ć‚Ŗćƒ–ć‚øć‚§ć‚Æćƒˆć§pryćƒ‡ćƒćƒƒć‚°ć‚»ćƒƒć‚·ćƒ§ćƒ³ć‚’čµ·å‹•ć—ć¾ć™ć€‚ć‚³ćƒ³ćƒ‘ć‚¤ćƒ«äø­ć®ē‰¹å®šćƒć‚¤ćƒ³ćƒˆć«ćŠć‘ć‚‹ćƒžćƒ‹ćƒ•ć‚§ć‚¹ćƒˆć‚³ćƒ¼ćƒ‰ć®ćƒ‡ćƒćƒƒć‚°ć«å½¹ē«‹ć”ć¾ć™ć€‚`puppet apply`ć®å®Ÿč”Œäø­ć¾ćŸćÆćƒ•ć‚©ć‚¢ć‚°ćƒ©ć‚¦ćƒ³ćƒ‰ć§Puppet serverć‚’å®Ÿč”Œć—ć¦ć„ć‚‹ćØćć«ć®ćæä½æē”Øć™ć‚‹åæ…č¦ćŒć‚ć‚Šć¾ć™ć€‚Puppet恮RubyGems恫`pry` gemćŒć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ«ć•ć‚Œć¦ć„ć‚‹åæ…č¦ćŒć‚ć‚Šć¾ć™ć€‚ + +*例:* + +```puppet +pry() +``` + +pryć‚»ćƒƒć‚·ćƒ§ćƒ³ć§å½¹ē«‹ć¤ć‚³ćƒžćƒ³ćƒ‰ćÆä»„äø‹ć®ćØćŠć‚Šć§ć™: + +* `catalog`ć‚’å®Ÿč”Œć™ć‚‹ćØć€ē¾åœØć‚«ć‚æćƒ­ć‚°ć‚’ć‚³ćƒ³ćƒ‘ć‚¤ćƒ«ć—ć¦ć„ć‚‹ć‚³ćƒ³ćƒ†ćƒ³ćƒ„ć‚’č¦‹ć‚‰ć‚Œć¾ć™ć€‚ +* `cd catalog`ćŠć‚ˆć³`ls`ć‚’å®Ÿč”Œć™ć‚‹ćØć€ć‚«ć‚æćƒ­ć‚°ćƒ”ć‚½ćƒƒćƒ‰ćŠć‚ˆć³ć‚¤ćƒ³ć‚¹ć‚æćƒ³ć‚¹å¤‰ę•°ć‚’č¦‹ć‚‰ć‚Œć¾ć™ć€‚ +* `@resource_table`ć‚’å®Ÿč”Œć™ć‚‹ćØć€ē¾åœØć®ć‚«ć‚æćƒ­ć‚°ćƒŖć‚½ćƒ¼ć‚¹ćƒ†ćƒ¼ćƒ–ćƒ«ć‚’č¦‹ć‚‰ć‚Œć¾ć™ć€‚ + +#### `pw_hash` + +crypté–¢ę•°ć‚’ē”Øć„ć¦ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ć‚’ćƒćƒƒć‚·ćƒ„ć—ć¾ć™ć€‚ć»ćØć‚“ć©ć®POSIXć‚·ć‚¹ćƒ†ćƒ ć§ä½æćˆć‚‹ćƒćƒƒć‚·ćƒ„ć‚’ęä¾›ć—ć¾ć™ć€‚ + +ć“ć®é–¢ę•°ć®ęœ€åˆć®å¼•ę•°ćÆć€ćƒćƒƒć‚·ćƒ„ć™ć‚‹ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ć§ć™ć€‚`undef`ć¾ćŸćÆē©ŗę–‡å­—åˆ—ć®å “åˆćÆć€ć“ć®é–¢ę•°ć«ć‚ˆć‚Š`undef`ćŒčæ”ć•ć‚Œć¾ć™ć€‚ + +この関数の第2ć®å¼•ę•°ćÆć€ä½æē”Øć™ć‚‹ćƒćƒƒć‚·ćƒ„ć®ć‚æć‚¤ćƒ—ć§ć™ć€‚é©åˆ‡ćŖcrypt(3)ćƒćƒƒć‚·ćƒ„ęŒ‡å®šå­ć«å¤‰ę›ć•ć‚Œć¾ć™ć€‚ęœ‰åŠ¹ćŖćƒćƒƒć‚·ćƒ„ć‚æć‚¤ćƒ—ćÆä»„äø‹ć®ćØćŠć‚Šć§ć™: + +|ćƒćƒƒć‚·ćƒ„ć‚æć‚¤ćƒ— |ęŒ‡å®šå­| +|---------------------|---------| +|MD5 |1 | +|SHA-256 |5 | +|SHA-512 (ęŽØå„Ø)|6 | + +この関数の第3ć®å¼•ę•°ćÆć€ä½æē”Øć™ć‚‹ć‚½ćƒ«ćƒˆć§ć™ć€‚ + +この関数は、Puppet server恮crypt(3)å®Ÿč£…ć‚’ä½æē”Øć—ć¦ć„ć¾ć™ć€‚ćŠä½æć„ć®ē’°å¢ƒć«č¤‡ę•°ć®ē•°ćŖć‚‹ć‚Ŗćƒšćƒ¬ćƒ¼ćƒ†ć‚£ćƒ³ć‚°ć‚·ć‚¹ćƒ†ćƒ ćŒå«ć¾ć‚Œć¦ć„ć‚‹å “åˆćÆć€ć“ć®é–¢ę•°ć‚’ä½æē”Øć™ć‚‹å‰ć«ć€äŗ’ę›ę€§ćŒć‚ć‚‹ć“ćØć‚’ē¢ŗčŖć—ć¦ćć ć•ć„ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +*注:* この関数はRubyć‚Æćƒ©ć‚¹ć®å®Ÿč£…ć«ć‚ćŸć‚Šć€UTF8ćØć®äŗ’ę›ę€§ćŒćŖć„åÆčƒ½ę€§ćŒć‚ć‚Šć¾ć™ć€‚äŗ’ę›ę€§ć‚’ē¢ŗäæć™ć‚‹ć«ćÆć€Ruby 2.4.0ä»„é™ć§ć“ć®é–¢ę•°ć‚’ä½æē”Øć—ć¦ćć ć•ć„ć€‚ + +#### `range` + +'(start, stop)'ć®å½¢å¼ć§äøŽćˆć‚‰ć‚ŒćŸå “åˆć«ć€é ˜åŸŸć‚’é…åˆ—ćØć—ć¦å¤–ęŒæć—ć¾ć™ć€‚ćŸćØćˆć°ć€`range("0", "9")`は[0,1,2,3,4,5,6,7,8,9]ć‚’čæ”ć—ć¾ć™ć€‚ć‚¼ćƒ­ćƒ‘ćƒ‡ć‚£ćƒ³ć‚°ć•ć‚ŒćŸę–‡å­—åˆ—ćÆć€č‡Ŗå‹•ēš„ć«ę•“ę•°ć«å¤‰ę›ć•ć‚Œć¾ć™ć€‚ć—ćŸćŒć£ć¦ć€`range("00", "09")`は[0,1,2,3,4,5,6,7,8,9]を返します。 + +éžę•“ę•°ę–‡å­—åˆ—ć‚’ä½æē”Øć§ćć¾ć™: + +* `range("a", "c")`は、["a","b","c"]を返します。 +* `range("host01", "host10")`は、["host01", "host02", ..., "host09", "host10"]を返します。 + +ęœ«å°¾ć®ć‚¼ćƒ­ć‚’ę˜Žē¤ŗēš„ć«å«ć‚ć‚‹åæ…č¦ćŒć‚ć‚Šć¾ć™ć€‚ćć†ć§ćŖć„ćØć€äø‹å±¤ć®Rubyé–¢ę•°ćŒé©åˆ‡ć«ę©Ÿčƒ½ć—ć¾ć›ć‚“ć€‚ + +第3ć®å¼•ę•°ć‚’ęø”ć™ćØć€ē”Ÿęˆć•ć‚ŒćŸé ˜åŸŸćŒćć®é–“éš”ć§åˆ»ć¾ć‚Œć¾ć™ć€‚ä¾‹: + +* `range("0", "9", "2")`は["0","2","4","6","8"]を返します。 + +> ę³Øę„: PuppetčØ€čŖžć§ćÆć€ć‚æć‚¤ćƒ—ć‚·ć‚¹ćƒ†ćƒ ć‚’ä½æē”Øć—ć¦ć€`ę•“ę•°`と`ćƒ•ćƒ­ćƒ¼ćƒˆ`ć®ēÆ„å›²ć‚’ć‚µćƒćƒ¼ćƒˆć—ć¦ć„ć¾ć™ć€‚ć“ć‚Œć‚‰ćÆć€ęŒ‡å®šć•ć‚ŒćŸå›žę•°ć®åå¾©ć«é©ć—ć¦ć„ć¾ć™ć€‚ + +å€¤ć®ć‚¹ć‚­ćƒƒćƒ—ć«ć¤ć„ć¦ćÆć€Puppetに内蔵の[`step`](https://docs.puppet.com/puppet/latest/function.html#step)é–¢ę•°ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + + ę•“ę•°[0, 9]ć€‚ćć‚Œćžć‚Œć®|$x| { notice($x) } #は、0, 1, 2, ... 9ć‚’é€šēŸ„ć—ć¾ć™ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `regexpescape` + +ę–‡å­—åˆ—ć¾ćŸćÆę–‡å­—åˆ—ć®é…åˆ—ć‚’ę­£č¦č”Øē¾ć‚Øć‚¹ć‚±ćƒ¼ćƒ—ć—ć¾ć™ć€‚ć‚¤ćƒ³ćƒ—ćƒƒćƒˆćØć—ć¦ć€å˜äø€ć®ę–‡å­—åˆ—ć¾ćŸćÆé…åˆ—ć®ć„ćšć‚Œć‹ćŒåæ…č¦ć§ć™ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `reject` + +é…åˆ—ć‚’ę¤œē“¢ć—ć€ęē¤ŗć•ć‚ŒćŸę­£č¦č”Øē¾ć«äø€č‡“ć™ć‚‹č¦ē“ ć‚’ć™ć¹ć¦ćƒŖć‚øć‚§ć‚Æćƒˆć—ć¾ć™ć€‚ + +ćŸćØćˆć°ć€`reject(['aaa','bbb','ccc','aaaddd'], 'aaa')`は['bbb','ccc']を返します。 + +Puppet 4.0.0ä»„é™ć§ćÆć€Puppetに内蔵の[`filter`](https://docs.puppet.com/puppet/latest/function.html#filter)é–¢ę•°ć«ć‚‚åŒć˜ć“ćØćŒå½“ć¦ćÆć¾ć‚Šć¾ć™ć€‚ +stdlib恮`reject`関数に相当します。 + + ['aaa','bbb','ccc','aaaddd'].filter |$x| { $x !~ /aaa/ } + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `reverse` + +ę–‡å­—åˆ—ć¾ćŸćÆé…åˆ—ć®é †åŗć‚’é€†č»¢ć—ć¾ć™ć€‚ + +> *ę³Øę„*: Puppetでは、内蔵の[`reverse_each`](https://docs.puppet.com/puppet/latest/function.html#reverse_each)é–¢ę•°ć‚’ä½æć£ć¦åŒć˜ć“ćØćŒč”Œćˆć¾ć™ć€‚ + + +#### `round` + +**éžęŽØå„Ø:**この関数は、Puppet 5.5.0で、内蔵の[`round`](https://puppet.com/docs/puppet/latest/function.html#round)é–¢ę•°ć«ē½®ćę›ćˆć‚‰ć‚Œć¾ć—ćŸć€‚ + +ę•°å€¤ć‚’ęœ€ć‚‚čæ‘ć„ę•“ę•°ć«äøøć‚ć¾ć™ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `rstrip` + +**éžęŽØå„Ø:**この関数は、Puppet 5.5.0で、内蔵の[`rstrip`](https://puppet.com/docs/puppet/latest/function.html#`rstrip`)é–¢ę•°ć«ē½®ćę›ćˆć‚‰ć‚Œć¾ć—ćŸć€‚ + +ę–‡å­—åˆ—ć®å³å“ć®ć‚¹ćƒšćƒ¼ć‚¹ć‚’å–ć‚Šé™¤ćć¾ć™ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `seeded_rand` + +ę•“ę•°ć®ęœ€å¤§å€¤ćØę–‡å­—åˆ—ć®ć‚·ćƒ¼ćƒ‰å€¤ć‚’å–ć‚Šć€ęœ€å¤§å€¤ć‚ˆć‚Šć‚‚å°ć•ć„åå¾©åÆčƒ½ć‹ć¤ćƒ©ćƒ³ćƒ€ćƒ ćŖę•“ę•°ć‚’čæ”ć—ć¾ć™ć€‚`fqdn_rand`ćØåŒę§˜ć§ć™ćŒć€ć‚·ćƒ¼ćƒ‰ć«ćƒŽćƒ¼ćƒ‰å›ŗęœ‰ć®ćƒ‡ćƒ¼ć‚æćŒčæ½åŠ ć•ć‚Œć¾ć›ć‚“ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `seeded_rand_string` + +(ć‚·ćƒ¼ćƒ‰å€¤ć«åŸŗć„ć„ć¦)äø€č²«ę€§ć®ć‚ć‚‹ćƒ©ćƒ³ćƒ€ćƒ ćŖę–‡å­—åˆ—ć‚’ē”Ÿęˆć—ć¾ć™ć€‚ē•°ćŖć‚‹ćƒ›ć‚¹ćƒˆć«äø€č‡“ć™ć‚‹ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ć‚’ē”Ÿęˆć™ć‚‹å “åˆć«ä¾æåˆ©ć§ć™ć€‚ + +#### `shell_escape` + +ę–‡å­—åˆ—ć‚’ć‚Øć‚¹ć‚±ćƒ¼ćƒ—ć—ć€Bourneć‚·ć‚§ćƒ«ć‚³ćƒžćƒ³ćƒ‰ćƒ©ć‚¤ćƒ³ć§å®‰å…Øć«ä½æē”Øć§ćć‚‹ć‚ˆć†ć«ć—ć¾ć™ć€‚å¾—ć‚‰ć‚Œć‚‹ę–‡å­—åˆ—ćÆć‚Æć‚©ćƒ¼ćƒˆćŖć—ć§ä½æē”Øć™ć‚‹åæ…č¦ćŒć‚ć‚Šć€ćƒ€ćƒ–ćƒ«ć‚Æć‚©ćƒ¼ćƒˆć¾ćŸćÆć‚·ćƒ³ć‚°ćƒ«ć‚Æć‚©ćƒ¼ćƒˆć§ć®ä½æē”ØćÆę„å›³ć•ć‚Œć¦ć„ć¾ć›ć‚“ć€‚ć“ć®é–¢ę•°ćÆć€Ruby恮`Shellwords.shellescape()`é–¢ę•°ćØåŒę§˜ć«ęŒ™å‹•ć—ć¾ć™ć€‚[Rubyćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆ](http://ruby-doc.org/stdlib-2.3.0/libdoc/shellwords/rdoc/Shellwords.html#method-c-shellescape)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +例:怀 + +```puppet +shell_escape('foo b"ar') => 'foo\ b\"ar' +``` + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `shell_join` + +äøŽćˆć‚‰ć‚ŒćŸę–‡å­—åˆ—ć®é…åˆ—ć‹ć‚‰ć‚³ćƒžćƒ³ćƒ‰ćƒ©ć‚¤ćƒ³ę–‡å­—åˆ—ć‚’ę§‹ēÆ‰ć—ć¾ć™ć€‚å„é…åˆ—ć‚¢ć‚¤ćƒ†ćƒ ćŒć€Bourneć‚·ć‚§ćƒ«ć§ä½æē”Øć§ćć‚‹ć‚ˆć†ć«ć‚Øć‚¹ć‚±ćƒ¼ćƒ—ć•ć‚Œć¾ć™ć€‚ćć®å¾Œć€ć™ć¹ć¦ć®ć‚¢ć‚¤ćƒ†ćƒ ćŒć¾ćØć‚ć‚‰ć‚Œć€é–“ć«ć‚·ćƒ³ć‚°ćƒ«ć‚¹ćƒšćƒ¼ć‚¹ćŒé…ć•ć‚Œć¾ć™ć€‚ć“ć®é–¢ę•°ćÆć€Ruby恮`Shellwords.shelljoin()`é–¢ę•°ćØåŒę§˜ć«ęŒ™å‹•ć—ć¾ć™ć€‚[Rubyćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆ](http://ruby-doc.org/stdlib-2.3.0/libdoc/shellwords/rdoc/Shellwords.html#method-c-shelljoin)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +例:怀 + +```puppet +shell_join(['foo bar', 'ba"z']) => 'foo\ bar ba\"z' +``` + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `shell_split` + +ę–‡å­—åˆ—ć‚’ćƒˆćƒ¼ć‚Æćƒ³ć®é…åˆ—ć«åˆ†å‰²ć—ć¾ć™ć€‚ć“ć®é–¢ę•°ćÆć€Ruby恮`Shellwords.shellsplit()`é–¢ę•°ćØåŒę§˜ć«ęŒ™å‹•ć—ć¾ć™ć€‚[Rubyćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆ](http://ruby-doc.org/stdlib-2.3.0/libdoc/shellwords/rdoc/Shellwords.html#method-c-shellsplit)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +*例:* + +```puppet +shell_split('foo\ bar ba\"z') => ['foo bar', 'ba"z'] +``` + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `shuffle` + +ę–‡å­—åˆ—ć¾ćŸćÆé…åˆ—ć®é †åŗć‚’ćƒ©ćƒ³ćƒ€ćƒ åŒ–ć—ć¾ć™ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `size` + +**éžęŽØå„Ø:** この関数は、Puppet 6.0.0で、内蔵の[`size`](https://puppet.com/docs/puppet/latest/function.html#size) é–¢ę•°ć«ē½®ćę›ćˆć‚‰ć‚Œć¾ć—ćŸ(`サイズ`は、`長恕`ć®ć‚Øć‚¤ćƒŖć‚¢ć‚¹ć§ć™)怂 + +ę–‡å­—åˆ—ć€é…åˆ—ć€ćƒćƒƒć‚·ćƒ„ć®č¦ē“ ę•°ć‚’čæ”ć—ć¾ć™ć€‚ć“ć®é–¢ę•°ćÆć€ä»Šå¾Œć®ćƒŖćƒŖćƒ¼ć‚¹ć§ćÆå»ƒę­¢ć•ć‚Œć¾ć™ć€‚Puppet 4では、`length`é–¢ę•°ć‚’ä½æē”Øć—ć¦ćć ć•ć„ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `sprintf_hash` + +**éžęŽØå„Ø:** Puppet 4.10.10ćŠć‚ˆć³5.3.4では、内蔵の[`sprintf`](https://docs.puppet.com/puppet/latest/function.html#sprintf)é–¢ę•°ć‚’ä½æć£ć¦åŒć˜ę©Ÿčƒ½ć‚’é”ęˆć§ćć¾ć™ć€‚ć“ć®é–¢ę•°ćÆć€ä»Šå¾Œć®ćƒŖćƒŖćƒ¼ć‚¹ć§ćÆå‰Šé™¤ć•ć‚Œć¾ć™ć€‚ + +åå‰ćŒęŒ‡å®šć•ć‚ŒćŸćƒ†ć‚­ć‚¹ćƒˆć®ćƒŖćƒ•ć‚”ćƒ¬ćƒ³ć‚¹ć§printfć‚¹ć‚æć‚¤ćƒ«ć®ćƒ•ć‚©ćƒ¼ćƒžćƒƒćƒˆć‚’å®Ÿč”Œć—ć¾ć™ć€‚ + +ęœ€åˆć®ćƒ‘ćƒ©ćƒ”ćƒ¼ć‚æćÆć€ćƒćƒƒć‚·ćƒ„å†…ć§ć®ę®‹ć‚Šć®ćƒ‘ćƒ©ćƒ”ćƒ¼ć‚æć®ćƒ•ć‚©ćƒ¼ćƒžćƒƒćƒˆę–¹ę³•ć‚’čØ˜čæ°ć™ć‚‹ćƒ•ć‚©ćƒ¼ćƒžćƒƒćƒˆę–‡å­—åˆ—ć§ć™ć€‚č©³ē“°ć«ć¤ć„ć¦ćÆć€Ruby恮[`Kernel::sprintf`](https://ruby-doc.org/core-2.4.2/Kernel.html#method-i-sprintf)ę©Ÿčƒ½ć®ćƒžćƒ‹ćƒ„ć‚¢ćƒ«ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +例:怀 + +```puppet +$output = sprintf_hash('String: %s / number converted to binary: %b', + { 'foo' => 'a string', 'number' => 5 }) +# $output = 'String: a string / number converted to binary: 101' +``` + +*Type*: rvalue + +#### `sort` + +**éžęŽØå„Ø:**この関数は、Puppet 5.5.0で、内蔵の[`sort`](https://puppet.com/docs/puppet/latest/function.html#sort)é–¢ę•°ć«ē½®ćę›ćˆć‚‰ć‚Œć¾ć—ćŸć€‚ + +ę–‡å­—åˆ—ćØé…åˆ—ć‚’čŖžå½™ēš„ć«åˆ†é”žć—ć¾ć™ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +>*注:* この関数はRubyć‚Æćƒ©ć‚¹ć®å®Ÿč£…ć«ć‚ćŸć‚Šć€UTF8ćØć®äŗ’ę›ę€§ćŒćŖć„åÆčƒ½ę€§ćŒć‚ć‚Šć¾ć™ć€‚äŗ’ę›ę€§ć‚’ē¢ŗäæć™ć‚‹ć«ćÆć€Ruby 2.4.0ä»„é™ć§ć“ć®é–¢ę•°ć‚’ä½æē”Øć—ć¦ćć ć•ć„ć€‚ + +#### `squeeze` + +ę–‡å­—åˆ—å†…ć®é€£ē¶šć—ćŸē¹°ć‚Ščæ”ć—('aaaa'など)ć‚’å˜äø€ę–‡å­—ć«ē½®ćę›ćˆć€ę–°ćŸćŖę–‡å­—åˆ—ć‚’čæ”ć—ć¾ć™ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `str2bool` + +ē‰¹å®šć®ę–‡å­—åˆ—ć‚’ćƒ–ćƒ¼ćƒŖć‚¢ćƒ³ć«å¤‰ę›ć—ć¾ć™ć€‚å€¤'1'态'true'态't'态'y'态'yes'ć‚’å«ć‚€ę–‡å­—åˆ—ćÆ`true`ć«å¤‰ę›ć•ć‚Œć¾ć™ć€‚å€¤'0'态'false'态'f'态'n'态'no'ć‚’å«ć‚€ę–‡å­—åˆ—ć€ćŠć‚ˆć³ē©ŗę–‡å­—åˆ—ć¾ćŸćÆęœŖå®šē¾©ę–‡å­—åˆ—ćÆ`false`ć«å¤‰ę›ć•ć‚Œć¾ć™ć€‚ćć®ä»–ć®å€¤ć®å “åˆć€ć‚Øćƒ©ćƒ¼ćŒē”Ÿć˜ć¾ć™ć€‚ć“ć®ćƒć‚§ćƒƒć‚Æć§ćÆć€å¤§ę–‡å­—ćØå°ę–‡å­—ćÆåŒŗåˆ„ć•ć‚Œć¾ć›ć‚“ć€‚ + +Puppet 5.0.0ä»„é™ć§ćÆć€ć‚æć‚¤ćƒ—ć‚·ć‚¹ćƒ†ćƒ ć‚’ä½æē”Øć—ć¦åŒć˜ć“ćØćŒč”Œćˆć¾ć™ć€‚ +åˆ©ē”ØåÆčƒ½ćŖå¤šćć®ć‚æć‚¤ćƒ—å¤‰ę›ć«ć¤ć„ć¦ćÆć€Puppet恮[`Boolean.new`](https://puppet.com/docs/puppet/latest/function.html#conversion-to-boolean) +é–¢ę•°ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + + Boolean('false'), Boolean('n'), Boolean('no') # すべてfalse + Boolean('true'), Boolean('y'), Boolean('yes') # すべてtrue + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `str2saltedsha512` + +OS Xćƒćƒ¼ć‚øćƒ§ćƒ³10.7ä»„äøŠć§ä½æē”Øć•ć‚Œć‚‹ć‚½ćƒ«ćƒˆä»˜ćSHA512ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ćƒćƒƒć‚·ćƒ„ć«ę–‡å­—åˆ—ć‚’å¤‰ę›ć—ć¾ć™ć€‚hexćƒćƒ¼ć‚øćƒ§ćƒ³ć®ć‚½ćƒ«ćƒˆä»˜ćSHA512ćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰ćƒćƒƒć‚·ćƒ„ć‚’čæ”ć—ć¾ć™ć€‚ć“ć‚ŒćÆć€ęœ‰åŠ¹ćŖćƒ‘ć‚¹ćƒÆćƒ¼ćƒ‰å±žę€§ćØć—ć¦Puppetćƒžćƒ‹ćƒ•ć‚§ć‚¹ćƒˆć«ęŒæå…„ć™ć‚‹ć“ćØćŒć§ćć¾ć™ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +>*注:* この関数はRubyć‚Æćƒ©ć‚¹ć®å®Ÿč£…ć«ć‚ćŸć‚Šć€UTF8ćØć®äŗ’ę›ę€§ćŒćŖć„åÆčƒ½ę€§ćŒć‚ć‚Šć¾ć™ć€‚äŗ’ę›ę€§ć‚’ē¢ŗäæć™ć‚‹ć«ćÆć€Ruby 2.4.0ä»„é™ć§ć“ć®é–¢ę•°ć‚’ä½æē”Øć—ć¦ćć ć•ć„ć€‚ + +#### `strftime` + +**éžęŽØå„Ø:**この関数は、Puppet 5.5.0で、内蔵の[`strftime`](https://puppet.com/docs/puppet/latest/function.html#`strftime`)é–¢ę•°ć«ē½®ćę›ćˆć‚‰ć‚Œć¾ć—ćŸć€‚ + +ćƒ•ć‚©ćƒ¼ćƒžćƒƒćƒˆć•ć‚ŒćŸę™‚åˆ»ć‚’čæ”ć—ć¾ć™ć€‚ + +ćŸćØćˆć°ć€`strftime("%s")`はUnixć‚Øćƒćƒƒć‚Æć‹ć‚‰ć®ēµŒéŽę™‚é–“ć‚’čæ”ć—ć€`strftime("%Y-%m-%d")`ćÆę—„ä»˜ć‚’čæ”ć—ć¾ć™ć€‚ + +引数: `strftime`ćƒ•ć‚©ćƒ¼ćƒžćƒƒćƒˆć§ę™‚é–“ć‚’ęŒ‡å®šć™ć‚‹ę–‡å­—åˆ—ć€‚č©³ē“°ć«ć¤ć„ć¦ćÆć€Ruby [strftime](https://ruby-doc.org/core-2.1.9/Time.html#method-i-strftime)ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +>*注:* この関数はRubyć‚Æćƒ©ć‚¹ć®å®Ÿč£…ć«ć‚ćŸć‚Šć€UTF8ćØć®äŗ’ę›ę€§ćŒćŖć„åÆčƒ½ę€§ćŒć‚ć‚Šć¾ć™ć€‚äŗ’ę›ę€§ć‚’ē¢ŗäæć™ć‚‹ć«ćÆć€Ruby 2.4.0ä»„é™ć§ć“ć®é–¢ę•°ć‚’ä½æē”Øć—ć¦ćć ć•ć„ć€‚ + +*ćƒ•ć‚©ćƒ¼ćƒžćƒƒćƒˆ:* + +* `%a`: ę›œę—„ć®åē§°ć®ēŸ­ēø®å½¢('Sun') +* `%A`: ę›œę—„ć®å®Œå…ØćŖåē§°('Sunday') +* `%b`: ęœˆć®åē§°ć®ēŸ­ēø®å½¢('Jan') +* `%B`: ęœˆć®å®Œå…ØćŖåē§°('January') +* `%c`: ęŽØå„Øć•ć‚Œć‚‹åœ°åŸŸć®ę—„ä»˜ćŠć‚ˆć³ę™‚åˆ»ć®č”Øē¾ +* `%C`: äø–ē“€(2009å¹“ć§ć‚ć‚Œć°20) +* `%d`: ćć®ęœˆć®ę—„(01..31) +* `%D`: ę—„ä»˜(%m/%d/%y) +* `%e`: ćć®ęœˆć®ę—„ć€1ę”ć®å “åˆćÆåŠč§’ē©ŗē™½ć§åŸ‹ć‚ć‚‹( 1..31) +* `%F`: %Y-%m-%d(ISO 8601ć®ę—„ä»˜ćƒ•ć‚©ćƒ¼ćƒžćƒƒćƒˆ)ćØåŒē­‰ +* `%h`: %bćØåŒē­‰ +* `%H`: 24ę™‚é–“åˆ¶ć®ę™‚(00..23) +* `%I`: 12ę™‚é–“åˆ¶ć®ę™‚(01..12) +* `%j`: å¹“äø­ć®é€šē®—ę—„(001..366) +* `%k`: 24ę™‚é–“åˆ¶ć®ę™‚ć€1ę”ć®å “åˆćÆåŠč§’ē©ŗē™½ć§åŸ‹ć‚ć‚‹( 0..23) +* `%l`: 12ę™‚é–“åˆ¶ć®ę™‚ć€1ę”ć®å “åˆćÆåŠč§’ē©ŗē™½ć§åŸ‹ć‚ć‚‹( 0..12) +* `%L`: ćƒŸćƒŖē§’(000..999) +* `%m`: ćć®å¹“ć®ęœˆ(01..12) +* `%M`: 分(00..59) +* `%n`: ę”¹č”Œ(\n) +* `%N`: ē§’ć®å°ę•°ē‚¹ä»„äø‹ć®ę”ć€ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆćÆ9ꔁ(ćƒŠćƒŽē§’) + * `%3N`: ćƒŸćƒŖē§’(3ꔁ) + * `%6N`: ćƒžć‚¤ć‚Æćƒ­ē§’(6ꔁ) + * `%9N`: ćƒŠćƒŽē§’(9ꔁ) +* `%p`: åˆå‰ć¾ćŸćÆåˆå¾Œ('AM'または'PM') +* `%P`: åˆå‰ć¾ćŸćÆåˆå¾Œ('am'または'pm') +* `%r`: 12ę™‚é–“åˆ¶ć®ę™‚åˆ»(%I:%M:%S %pćØåŒē­‰) +* `%R`: 24ę™‚é–“åˆ¶ć®ę™‚åˆ»(%H:%M) +* `%s`: Unixć‚Øćƒćƒƒć‚Æć€1970-01-01 00:00:00 UTCć‹ć‚‰ć®ēµŒéŽē§’ +* `%S`: ē§’(00..60) +* `%t`: ć‚æćƒ–ę–‡å­—( ) +* `%T`: 24ę™‚é–“åˆ¶ć®ę™‚åˆ»(%H:%M:%S) +* `%u`: ęœˆę›œę—„ć‚’1ćØć—ćŸć€ę›œę—„ć®ę•°å€¤č”Øē¾(1..7) +* `%U`: ęœ€åˆć®ę—„ę›œę—„ć‚’ē¬¬1é€±ć®å§‹ć¾ć‚ŠćØć—ćŸć€ē¾åœØć®é€±ć‚’č”Øć™ę•°(00..53) +* `%v`: VMSå½¢å¼ć®ę—„ä»˜(%e-%b-%Y) +* `%V`: ISO 8601å½¢å¼ć®ęš¦é€±(01..53) +* `%W`: ęœ€åˆć®ęœˆę›œę—„ć‚’ē¬¬1é€±ć®å§‹ć¾ć‚ŠćØć—ćŸć€ē¾åœØć®é€±ć‚’č”Øć™ę•°(00..53) +* `%w`: ę›œę—„(ę—„ę›œćŒ0态0..6) +* `%x`: ęŽØå„Øć•ć‚Œć‚‹ę—„ä»˜ć®ćæć®č”Øē¾ć€ę™‚åˆ»ćÆćŖć— +* `%X`: ęŽØå„Øć•ć‚Œć‚‹ę™‚åˆ»ć®ćæć®č”Øē¾ć€ę—„ä»˜ćÆćŖć— +* `%y`: 世瓀なしの幓(00..99) +* `%Y`: äø–ē“€ć‚ć‚Šć®å¹“ +* `%z`: ć‚æć‚¤ćƒ ć‚¾ćƒ¼ćƒ³ć€UTCć‹ć‚‰ć®ć‚Ŗćƒ•ć‚»ćƒƒćƒˆ(+0900など) +* `%Z`: ć‚æć‚¤ćƒ ć‚¾ćƒ¼ćƒ³ć®åē§° +* `%%`: '%'文字 + +#### `strip` + +**éžęŽØå„Ø:**この関数は、Puppet 5.5.0で、内蔵の[`strip`](https://puppet.com/docs/puppet/latest/function.html#`strip`)é–¢ę•°ć«ē½®ćę›ćˆć‚‰ć‚Œć¾ć—ćŸć€‚ + +1ć¤ć®ę–‡å­—åˆ—ć€ć¾ćŸćÆé…åˆ—å†…ć®ć™ć¹ć¦ć®ę–‡å­—åˆ—ć‹ć‚‰ć€å†’é ­ćŠć‚ˆć³ęœ«å°¾ć®ē©ŗē™½ć‚’å‰Šé™¤ć—ć¾ć™ć€‚ćŸćØćˆć°ć€`strip(" aaa ")`は"aaa"ć«ćŖć‚Šć¾ć™ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `suffix` + +é…åˆ—ć®ć™ć¹ć¦ć®č¦ē“ ć€ć¾ćŸćÆćƒćƒƒć‚·ćƒ„ć®ć™ć¹ć¦ć®ć‚­ćƒ¼ć«ęŽ„å°¾č¾žć‚’é©ē”Øć—ć¾ć™ć€‚ + +例:怀 + +* `suffix(['a','b','c'], 'p')`は['ap','bp','cp']を返します。 +* `suffix({'a'=>'b','b'=>'c','c'=>'d'}, 'p')`は{'ap'=>'b','bp'=>'c','cp'=>'d'}を返します。 + +Puppet 4.0.0ä»„é™ć§ćÆć€å†…č”µć®[`map`](https://docs.puppet.com/puppet/latest/function.html#map)é–¢ę•°ć‚’ä½æē”Øć—ć¦é…åˆ—ć®å€¤ć‚’å¤‰ę›“ć—ć¾ć™ć€‚ć“ć®ä¾‹ćÆć€äøŠčØ˜ć®ęœ€åˆć®ä¾‹ćØåŒć˜ć§ć™ć€‚ + + ['a', 'b', 'c'].map |$x| { "${x}p" } + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `swapcase` + +ę–‡å­—åˆ—ć®ē¾åœØć®å¤§ę–‡å­—ćØå°ę–‡å­—ć‚’å…„ć‚Œę›æćˆć¾ć™ć€‚ćŸćØćˆć°ć€`swapcase("aBcD")`は"AbCd"ć«ćŖć‚Šć¾ć™ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +>*注:* この関数はRubyć‚Æćƒ©ć‚¹ć®å®Ÿč£…ć«ć‚ćŸć‚Šć€UTF8ćØć®äŗ’ę›ę€§ćŒćŖć„åÆčƒ½ę€§ćŒć‚ć‚Šć¾ć™ć€‚äŗ’ę›ę€§ć‚’ē¢ŗäæć™ć‚‹ć«ćÆć€Ruby 2.4.0ä»„é™ć§ć“ć®é–¢ę•°ć‚’ä½æē”Øć—ć¦ćć ć•ć„ć€‚ + +#### `time` + +ē¾åœØć®Unixć‚Øćƒćƒƒć‚Æę™‚åˆ»ć‚’ę•“ę•°ćØć—ć¦čæ”ć—ć¾ć™ć€‚ + +ćŸćØćˆć°ć€`time()`は'1311972653'などを返します。 + +Puppet 4.8.0ä»„é™ć€PuppetčØ€čŖžć«ćÆć€``Timestamp` (時点)と`Timespan` (ꜟ間)ć®å„ćƒ‡ćƒ¼ć‚æć‚æć‚¤ćƒ—ćŒć‚ć‚Šć¾ć™ć€‚ę¬”ć®ä¾‹ćÆć€å¼•ę•°ćŖć—ć§`time()`ć‚’å‘¼ć³å‡ŗć™ć®ćØåŒć˜ć§ć™ć€‚ + +ć‚æć‚¤ćƒ ć‚¹ć‚æćƒ³ćƒ—() + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `to_bytes` + +å¼•ę•°ć‚’ćƒć‚¤ćƒˆć«å¤‰ę›ć—ć¾ć™ć€‚ + +ćŸćØćˆć°ć€"4 kB"は"4096"ć«ćŖć‚Šć¾ć™ć€‚ + +引数: å˜äø€ć®ę–‡å­—åˆ—ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `to_json` + +å…„åŠ›å€¤ć‚’JSONå½¢å¼ć®ę–‡å­—åˆ—ć«å¤‰ę›ć—ć¾ć™ć€‚ + +ä¾‹ćˆć°ć€`{ "key" => "value" }`は`{"key":"value"}`ć«ćŖć‚Šć¾ć™ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `to_json_pretty` + +å…„åŠ›å€¤ć‚’ę•“å½¢ć•ć‚ŒćŸJSONå½¢å¼ć®ę–‡å­—åˆ—ć«å¤‰ę›ć—ć¾ć™ć€‚ + +ä¾‹ćˆć°ć€`{ "key" => "value" }`は`{\n \"key\": \"value\"\n}`ć«ćŖć‚Šć¾ć™ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `to_yaml` + +å…„åŠ›å€¤ć‚’YAMLå½¢å¼ć®ę–‡å­—åˆ—ć«å¤‰ę›ć—ć¾ć™ć€‚ + +ä¾‹ćˆć°ć€`{ "key" => "value" }`は`"---\nkey: value\n"`ć«ćŖć‚Šć¾ć™ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `try_get_value` + +**éžęŽØå„Ø:** `dig()`ć«ē½®ćę›ćˆć‚‰ć‚Œć¾ć—ćŸć€‚ + +ćƒćƒƒć‚·ćƒ„ćŠć‚ˆć³é…åˆ—ć®č¤‡ę•°ćƒ¬ć‚¤ćƒ¤ćƒ¼å†…ć®å€¤ć‚’å–å¾—ć—ć¾ć™ć€‚ + +引数: + +* 第1ć®å¼•ę•°ćØć—ć¦ć€ćƒ‘ć‚¹ć‚’å«ć‚€ę–‡å­—åˆ—ć€‚ć“ć®å¼•ę•°ćÆć€ć‚¼ćƒ­ć§ćÆć˜ć¾ć‚Šć€ćƒ‘ć‚¹åŒŗåˆ‡ć‚Šę–‡å­—(ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆćÆ"/")ć§åŒŗåˆ‡ć£ćŸćƒćƒƒć‚·ćƒ„ć‚­ćƒ¼ć¾ćŸćÆé…åˆ—ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ć®ę–‡å­—åˆ—ćØć—ć¦ęē¤ŗć—ć¦ćć ć•ć„ć€‚ć“ć®é–¢ę•°ćÆå„ćƒ‘ć‚¹ć‚³ćƒ³ćƒćƒ¼ćƒćƒ³ćƒˆć«ć‚ˆć‚Šę§‹é€ å†…ć‚’ē§»å‹•ć—ć€ćƒ‘ć‚¹ć®ęœ€å¾Œć§å€¤ć‚’čæ”ć™ć‚ˆć†č©¦ćæć¾ć™ć€‚ + +* ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆć®ē¬¬2ć®å¼•ę•°ć€‚ćƒ‘ć‚¹ćŒę­£ć—ććŖć„å “åˆć‚„ć€å€¤ćŒč¦‹ć¤ć‹ć‚‰ćŖć„å “åˆć€ćć®ä»–ć®ć‚Øćƒ©ćƒ¼ćŒē”Ÿć˜ćŸå “åˆćÆć€ć“ć®å¼•ę•°ćŒčæ”ć•ć‚Œć¾ć™ć€‚ +* ęœ€å¾Œć®å¼•ę•°ćØć—ć¦ć€ćƒ‘ć‚¹åŒŗåˆ‡ć‚Šę–‡å­—ć€‚ + +```ruby +$data = { + 'a' => { + 'b' => [ + 'b1', + 'b2', + 'b3', + ] + } +} + +$value = try_get_value($data, 'a/b/2') +# $value = 'b3' + +# with all possible options +$value = try_get_value($data, 'a/b/2', 'not_found', '/') +# $value = 'b3' + +# using the default value +$value = try_get_value($data, 'a/b/c/d', 'not_found') +# $value = 'not_found' + +# using custom separator +$value = try_get_value($data, 'a|b', [], '|') +# $value = ['b1','b2','b3'] +``` + +1. **$data** å–ć‚Šę‰±ć†ćƒ‡ćƒ¼ć‚æę§‹é€ ć€‚ +2. **'a/b/2'** ćƒ‘ć‚¹ę–‡å­—åˆ—ć€‚ +3. **'not_found'** ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆå€¤ć€‚ä½•ć‚‚č¦‹ć¤ć‹ć‚‰ćŖć„å “åˆć«čæ”ć•ć‚Œć¾ć™ć€‚ + (ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć€ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆćÆ`undef`) +4. **'/'** ćƒ‘ć‚¹åŒŗåˆ‡ć‚Šę–‡å­—ć€‚ + (ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć€ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆćÆ*'/'*) + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `type3x` + +**éžęŽØå„Ø:**ć“ć®é–¢ę•°ćÆć€ä»Šå¾Œć®ćƒŖćƒŖćƒ¼ć‚¹ć§å»ƒę­¢ć•ć‚Œć¾ć™ć€‚ + +äøŽćˆć‚‰ć‚ŒćŸå€¤ć®ć‚æć‚¤ćƒ—ć‚’čŖ¬ę˜Žć™ć‚‹ę–‡å­—åˆ—ć‚’čæ”ć—ć¾ć™ć€‚ć‚æć‚¤ćƒ—ćØć—ć¦ćÆć€ę–‡å­—åˆ—ć€é…åˆ—ć€ćƒćƒƒć‚·ćƒ„ć€ćƒ•ćƒ­ćƒ¼ćƒˆć€ę•“ę•°ć€ćƒ–ćƒ¼ćƒŖć‚¢ćƒ³ćŒåÆčƒ½ć§ć™ć€‚Puppet 4ć§ćÆć€ć“ć®ä»£ć‚ć‚Šć«ę–°ć—ć„ć‚æć‚¤ćƒ—ć‚·ć‚¹ćƒ†ćƒ ć‚’ä½æē”Øć—ć¦ćć ć•ć„ć€‚ + +引数: + +* ę–‡å­—åˆ— +* 配列 +* ćƒćƒƒć‚·ćƒ„ +* ćƒ•ćƒ­ćƒ¼ćƒˆ +* ę•“ę•° +* ćƒ–ćƒ¼ćƒŖć‚¢ćƒ³ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `type_of` + +ć“ć®é–¢ę•°ćÆäø‹ä½äŗ’ę›ę€§ć‚’å¾—ć‚‹ćŸć‚ć«ęä¾›ć•ć‚Œć¦ć„ć¾ć™ćŒć€Puppetć§ęä¾›ć•ć‚Œć¦ć„ć‚‹å†…č”µć®[type()関数](https://puppet.com/docs/puppet/latest/function.html#type)ć®ä½æē”Øć‚’ęŽØå„Øć—ć¾ć™ć€‚ + +äøŽćˆć‚‰ć‚ŒćŸå€¤ć®ćƒŖćƒ†ćƒ©ćƒ«åž‹ć‚’čæ”ć—ć¾ć™ć€‚Puppet 4ćŒåæ…č¦ć§ć™ć€‚`if type_of($some_value) <= Array[String] { ... }`ć®ć‚ˆć†ć«(ć“ć‚ŒćÆ`if $some_value =~ Array[String] { ... }`に相当します)态`<=`ć‚’ē”Øć„ćŸć‚æć‚¤ćƒ—ć®ęÆ”č¼ƒć«å½¹ē«‹ć”ć¾ć™ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `union` + +2ć¤ä»„äøŠć®é…åˆ—ć‚’é‡č¤‡ćŖć—ć§ēµåˆć—ćŸć‚‚ć®ć‚’čæ”ć—ć¾ć™ć€‚ + +ćŸćØćˆć°ć€`union(["a","b","c"],["b","c","d"])`は["a","b","c","d"]を返します。 + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `unique` + +ę–‡å­—åˆ—ćŠć‚ˆć³é…åˆ—ć‹ć‚‰é‡č¤‡ć‚’å‰Šé™¤ć—ć¾ć™ć€‚ + +ćŸćØćˆć°ć€`unique("aabbcc")`は'abc'悒态`unique(["a","a","b","b","c","c"])`は["a","b","c"]を返します。 + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `unix2dos` + +äøŽćˆć‚‰ć‚ŒćŸę–‡å­—åˆ—ć®DOSćƒćƒ¼ć‚øćƒ§ćƒ³ć‚’čæ”ć—ć¾ć™ć€‚ć‚Æćƒ­ć‚¹ćƒ—ćƒ©ćƒƒćƒˆćƒ•ć‚©ćƒ¼ćƒ ćƒ†ćƒ³ćƒ—ćƒ¬ćƒ¼ćƒˆć§ćƒ•ć‚”ć‚¤ćƒ«ćƒŖć‚½ćƒ¼ć‚¹ć‚’ä½æē”Øć™ć‚‹å “åˆć«å½¹ē«‹ć”ć¾ć™ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +```puppet +file { $config_file: + ensure => file, + content => unix2dos(template('my_module/settings.conf.erb')), +} +``` + +[dos2unix](#dos2unix)ć‚‚å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +#### `upcase` + +**éžęŽØå„Ø:**この関数は、Puppet 5.5.0で、内蔵の[`upcase`](https://puppet.com/docs/puppet/latest/function.html#upcase)é–¢ę•°ć«ē½®ćę›ćˆć‚‰ć‚Œć¾ć—ćŸć€‚ + +ć‚Ŗćƒ–ć‚øć‚§ć‚Æćƒˆć€é…åˆ—ć€ć‚Ŗćƒ–ć‚øć‚§ć‚Æćƒˆć®ćƒćƒƒć‚·ćƒ„ć‚’å¤§ę–‡å­—ć«å¤‰ę›ć—ć¾ć™ć€‚å¤‰ę›ć•ć‚Œć‚‹ć‚Ŗćƒ–ć‚øć‚§ć‚ÆćƒˆćÆć€å¤§ę–‡å­—åŒ–ć«åÆ¾åæœć™ć‚‹ć‚‚ć®ć§ćŖć‘ć‚Œć°ćŖć‚Šć¾ć›ć‚“ć€‚ + +ćŸćØćˆć°ć€`upcase('abcd')`は'ABCD'を返します。 + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +*注:* この関数はRubyć‚Æćƒ©ć‚¹ć®å®Ÿč£…ć«ć‚ćŸć‚Šć€UTF8ćØć®äŗ’ę›ę€§ćŒćŖć„åÆčƒ½ę€§ćŒć‚ć‚Šć¾ć™ć€‚äŗ’ę›ę€§ć‚’ē¢ŗäæć™ć‚‹ć«ćÆć€Ruby 2.4.0ä»„é™ć§ć“ć®é–¢ę•°ć‚’ä½æē”Øć—ć¦ćć ć•ć„ć€‚ + +#### `uriescape` + +ę–‡å­—åˆ—ć¾ćŸćÆę–‡å­—åˆ—ć®é…åˆ—ć‚’URLć‚Øćƒ³ć‚³ćƒ¼ćƒ‰ć—ć¾ć™ć€‚ + +引数: å˜äø€ć®ę–‡å­—åˆ—ć¾ćŸćÆę–‡å­—åˆ—ć®é…åˆ—ć€‚ + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +>*注:* この関数はRubyć‚Æćƒ©ć‚¹ć®å®Ÿč£…ć«ć‚ćŸć‚Šć€UTF8ćØć®äŗ’ę›ę€§ćŒćŖć„åÆčƒ½ę€§ćŒć‚ć‚Šć¾ć™ć€‚äŗ’ę›ę€§ć‚’ē¢ŗäæć™ć‚‹ć«ćÆć€Ruby 2.4.0ä»„é™ć§ć“ć®é–¢ę•°ć‚’ä½æē”Øć—ć¦ćć ć•ć„ć€‚ + +#### `validate_absolute_path` + +ćƒ•ć‚”ć‚¤ćƒ«ć‚·ć‚¹ćƒ†ćƒ ć®ēµ¶åÆ¾ćƒ‘ć‚¹ć‚’č”Øć™ä»»ę„ć®ę–‡å­—åˆ—ć®ęœ‰åŠ¹ę€§ć‚’ē¢ŗčŖć—ć¾ć™ć€‚WindowsćŠć‚ˆć³Unixå½¢å¼ć®ćƒ‘ć‚¹ć§ę©Ÿčƒ½ć—ć¾ć™ć€‚ + +ä»„äø‹ć®å€¤ćŒęø”ć•ć‚Œć¾ć™: + +```puppet +$my_path = 'C:/Program Files (x86)/Puppet Labs/Puppet' +validate_absolute_path($my_path) +$my_path2 = '/var/lib/puppet' +validate_absolute_path($my_path2) +$my_path3 = ['C:/Program Files (x86)/Puppet Labs/Puppet','C:/Program Files/Puppet Labs/Puppet'] +validate_absolute_path($my_path3) +$my_path4 = ['/var/lib/puppet','/usr/share/puppet'] +validate_absolute_path($my_path4) +``` + +ä»„äø‹ć®å€¤ćÆå¤±ę•—ć«ćŖć‚Šć€ć‚³ćƒ³ćƒ‘ć‚¤ćƒ«ćŒäø­ę­¢ć•ć‚Œć¾ć™: + +```puppet +validate_absolute_path(true) +validate_absolute_path('../var/lib/puppet') +validate_absolute_path('var/lib/puppet') +validate_absolute_path([ 'var/lib/puppet', '/var/foo' ]) +validate_absolute_path([ '/var/lib/puppet', 'var/foo' ]) +$undefined = `undef` +validate_absolute_path($undefined) +``` + +*ć‚æć‚¤ćƒ—*: ć‚¹ćƒ†ćƒ¼ćƒˆćƒ”ćƒ³ćƒˆ + +#### `validate_array` + +**éžęŽØå„Ø:**ä»Šå¾Œć®ćƒćƒ¼ć‚øćƒ§ćƒ³ć®stdlibć§ćÆå‰Šé™¤ć•ć‚Œć¾ć™ć€‚[`validate_legacy`](#validate_legacy)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +ęø”ć•ć‚ŒćŸć™ć¹ć¦ć®å€¤ćŒé…åˆ—ćƒ‡ćƒ¼ć‚æę§‹é€ ć§ć‚ć‚‹ć“ćØć‚’ē¢ŗčŖć—ć¾ć™ć€‚ć“ć®ćƒć‚§ćƒƒć‚Æć§äøåˆę ¼ćØćŖć£ćŸå€¤ćŒć‚ć‚‹å “åˆćÆć€ć‚«ć‚æćƒ­ć‚°ć‚³ćƒ³ćƒ‘ć‚¤ćƒ«ćŒäø­ę­¢ć•ć‚Œć¾ć™ć€‚ + +ä»„äø‹ć®å€¤ćŒęø”ć•ć‚Œć¾ć™: + +```puppet +$my_array = [ 'one', 'two' ] +validate_array($my_array) +``` + +ä»„äø‹ć®å€¤ćÆå¤±ę•—ć«ćŖć‚Šć€ć‚³ćƒ³ćƒ‘ć‚¤ćƒ«ćŒäø­ę­¢ć•ć‚Œć¾ć™: + +```puppet +validate_array(true) +validate_array('some_string') +$undefined = `undef` +validate_array($undefined) +``` + +*ć‚æć‚¤ćƒ—*: ć‚¹ćƒ†ćƒ¼ćƒˆćƒ”ćƒ³ćƒˆ + +#### `validate_augeas` + +Augeasćƒ¬ćƒ³ć‚ŗć‚’ē”Øć„ć¦ę–‡å­—åˆ—ć‚’ē¢ŗčŖć—ć¾ć™ć€‚ + +引数: + +* 第1ć®å¼•ę•°ćØć—ć¦ć€ćƒ†ć‚¹ćƒˆć™ć‚‹ę–‡å­—åˆ—ć€‚ +* 第2の引数として、使用するAugeasćƒ¬ćƒ³ć‚ŗć®åå‰ć€‚ +* ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć®ē¬¬3ć®ę–‡å­—åˆ—ćØć—ć¦ć€ćƒ•ć‚”ć‚¤ćƒ«å†…ć§č¦‹ć¤ć‹ć‚‹ć¹ć**ではない**ćƒ‘ć‚¹ć®ćƒŖć‚¹ćƒˆć€‚ +* ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć®ē¬¬4ć®å¼•ę•°ćØć—ć¦ć€ćƒ¦ćƒ¼ć‚¶ć«č”Øē¤ŗć™ć‚‹ć‚Øćƒ©ćƒ¼ćƒ”ćƒƒć‚»ćƒ¼ć‚øć€‚ + +AugeasćŒćƒ¬ćƒ³ć‚ŗć«ć‚ˆć‚‹ę–‡å­—åˆ—ć®ę§‹ę–‡č§£ęžć«å¤±ę•—ć—ćŸå “åˆćÆć€ę§‹ę–‡ć‚Øćƒ©ćƒ¼ć«ć‚ˆć‚Šć‚³ćƒ³ćƒ‘ć‚¤ćƒ«ćŒäø­ę­¢ć•ć‚Œć¾ć™ć€‚ + +`$file`変数は、Augeasćƒ„ćƒŖćƒ¼ć§ćƒ†ć‚¹ćƒˆć•ć‚Œć‚‹äø€ę™‚ćƒ•ć‚”ć‚¤ćƒ«ć®ćƒ­ć‚±ćƒ¼ć‚·ćƒ§ćƒ³ć‚’ē¤ŗć—ć¾ć™ć€‚ + +ćŸćØćˆć°ć€$passwdcontentć«ćƒ¦ćƒ¼ć‚¶ć®`foo`ćŒå«ć¾ć‚ŒćŖć„ć‚ˆć†ć«ć™ć‚‹ć«ćÆć€ē¬¬3ć®å¼•ę•°ć‚’ä»„äø‹ć®ć‚ˆć†ć«ć—ć¾ć™: + +```puppet +validate_augeas($passwdcontent, 'Passwd.lns', ['$file/foo']) +``` + +ć‚Øćƒ©ćƒ¼ćƒ”ćƒƒć‚»ćƒ¼ć‚øć‚’ē”Ÿęˆć—ć¦č”Øē¤ŗć™ć‚‹ć«ćÆć€ē¬¬4ć®å¼•ę•°ć‚’ä»„äø‹ć®ć‚ˆć†ć«ć—ć¾ć™: + +```puppet +validate_augeas($sudoerscontent, 'Sudoers.lns', [], 'Failed to validate sudoers content with Augeas') +``` + +*ć‚æć‚¤ćƒ—*: ć‚¹ćƒ†ćƒ¼ćƒˆćƒ”ćƒ³ćƒˆ + +#### `validate_bool` + +**éžęŽØå„Ø:**ä»Šå¾Œć®ćƒćƒ¼ć‚øćƒ§ćƒ³ć®stdlibć§ćÆå‰Šé™¤ć•ć‚Œć¾ć™ć€‚[`validate_legacy`](#validate_legacy)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +ęø”ć•ć‚ŒćŸć™ć¹ć¦ć®å€¤ćŒ`true`または`false`ć§ć‚ć‚‹ć“ćØć‚’ē¢ŗčŖć—ć¾ć™ć€‚ć“ć®ćƒć‚§ćƒƒć‚Æć§äøåˆę ¼ćØćŖć£ćŸå€¤ćŒć‚ć‚‹å “åˆćÆć€ć‚«ć‚æćƒ­ć‚°ć‚³ćƒ³ćƒ‘ć‚¤ćƒ«ćŒäø­ę­¢ć•ć‚Œć¾ć™ć€‚ + +ä»„äø‹ć®å€¤ćŒęø”ć•ć‚Œć¾ć™: + +```puppet +$iamtrue = true +validate_bool(true) +validate_bool(true, true, false, $iamtrue) +``` + +ä»„äø‹ć®å€¤ćÆå¤±ę•—ć«ćŖć‚Šć€ć‚³ćƒ³ćƒ‘ć‚¤ćƒ«ćŒäø­ę­¢ć•ć‚Œć¾ć™: + +```puppet +$some_array = [ true ] +validate_bool("false") +validate_bool("true") +validate_bool($some_array) +``` + +*ć‚æć‚¤ćƒ—*: ć‚¹ćƒ†ćƒ¼ćƒˆćƒ”ćƒ³ćƒˆ + +#### `validate_cmd` + +å¤–éƒØć‚³ćƒžćƒ³ćƒ‰ć«ć‚ˆć‚Šę–‡å­—åˆ—ć‚’ē¢ŗčŖć—ć¾ć™ć€‚ + +引数: +* 第1ć®å¼•ę•°ćØć—ć¦ć€ćƒ†ć‚¹ćƒˆć™ć‚‹ę–‡å­—åˆ—ć€‚ +* 第2ć®å¼•ę•°ćØć—ć¦ć€ćƒ†ć‚¹ćƒˆć‚³ćƒžćƒ³ćƒ‰ć®ćƒ‘ć‚¹ć€‚ć“ć®å¼•ę•°ćÆć€ćƒ•ć‚”ć‚¤ćƒ«ćƒ‘ć‚¹ć®ćƒ—ćƒ¬ćƒ¼ć‚¹ćƒ›ćƒ«ćƒ€ā€•ćØć—ć¦%ć‚’ćØć‚Šć¾ć™(%ćƒ—ćƒ¬ćƒ¼ć‚¹ćƒ›ćƒ«ćƒ€ćƒ¼ćŒäøŽćˆć‚‰ć‚Œć¦ć„ćŖć„å “åˆć€ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆćÆć‚³ćƒžćƒ³ćƒ‰ęœ«å°¾)ć€‚ćƒ‘ć‚¹ć—ćŸę–‡å­—åˆ—ć‚’å«ć‚€äø€ę™‚ćƒ•ć‚”ć‚¤ćƒ«ć«åÆ¾ć—ć¦ć‚³ćƒžćƒ³ćƒ‰ćŒčµ·å‹•ć—ćŸå “åˆć‚„ć€ć‚¼ćƒ­ć§ćÆćŖć„å€¤ćŒčæ”ć•ć‚ŒćŸå “åˆćÆć€ę§‹ę–‡ć‚Øćƒ©ćƒ¼ć«ć‚ˆć‚Šć‚³ćƒ³ćƒ‘ć‚¤ćƒ«ćŒäø­ę­¢ć•ć‚Œć¾ć™ć€‚ +* ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć®ē¬¬3ć®å¼•ę•°ćØć—ć¦ć€ćƒ¦ćƒ¼ć‚¶ć«č”Øē¤ŗć™ć‚‹ć‚Øćƒ©ćƒ¼ćƒ”ćƒƒć‚»ćƒ¼ć‚øć€‚ + +```puppet +# Defaults to end of path +validate_cmd($sudoerscontent, '/usr/sbin/visudo -c -f', 'Visudo failed to validate sudoers content') +``` + +```puppet +# % as file location +validate_cmd($haproxycontent, '/usr/sbin/haproxy -f % -c', 'Haproxy failed to validate config content') +``` + +*ć‚æć‚¤ćƒ—*: ć‚¹ćƒ†ćƒ¼ćƒˆćƒ”ćƒ³ćƒˆ + +#### `validate_domain_name` + +**éžęŽØå„Ø:**ä»Šå¾Œć®ćƒćƒ¼ć‚øćƒ§ćƒ³ć®stdlibć§ćÆå‰Šé™¤ć•ć‚Œć¾ć™ć€‚[`validate_legacy`](#validate_legacy)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +ęø”ć•ć‚ŒćŸć™ć¹ć¦ć®å€¤ćŒę§‹ę–‡ēš„ć«ę­£ć—ć„ćƒ‰ćƒ”ć‚¤ćƒ³åć§ć‚ć‚‹ć“ćØć‚’ē¢ŗčŖć—ć¾ć™ć€‚ć“ć®ćƒć‚§ćƒƒć‚Æć§äøåˆę ¼ćØćŖć£ćŸå€¤ćŒć‚ć‚‹å “åˆćÆć€ć‚«ć‚æćƒ­ć‚°ć‚³ćƒ³ćƒ‘ć‚¤ćƒ«ćŒäø­ę­¢ć•ć‚Œć¾ć™ć€‚ + +ä»„äø‹ć®å€¤ćŒęø”ć•ć‚Œć¾ć™: + +~~~ +$my_domain_name = 'server.domain.tld' +validate_domain_name($my_domain_name) +validate_domain_name('domain.tld', 'puppet.com', $my_domain_name) +~~~ + +ä»„äø‹ć®å€¤ćŒäøåˆę ¼ćØćŖć‚Šć€ć‚³ćƒ³ćƒ‘ć‚¤ćƒ«ćŒäø­ę­¢ć•ć‚Œć¾ć™: + +~~~ +validate_domain_name(1) +validate_domain_name(true) +validate_domain_name('invalid domain') +validate_domain_name('-foo.example.com') +validate_domain_name('www.example.2com') +~~~ + +*ć‚æć‚¤ćƒ—*: ć‚¹ćƒ†ćƒ¼ćƒˆćƒ”ćƒ³ćƒˆ + +#### `validate_email_address` + +ęø”ć•ć‚ŒćŸć™ć¹ć¦ć®å€¤ćŒęœ‰åŠ¹ćŖćƒ”ćƒ¼ćƒ«ć‚¢ćƒ‰ćƒ¬ć‚¹ć§ć‚ć‚‹ć“ćØć‚’ē¢ŗčŖć—ć¾ć™ć€‚ć“ć®ćƒć‚§ćƒƒć‚Æć§äøåˆę ¼ćØćŖć£ćŸå€¤ćŒć‚ć‚‹å “åˆć€ć‚³ćƒ³ćƒ‘ć‚¤ćƒ«ćŒå¤±ę•—ć—ć¾ć™ć€‚ + +ä»„äø‹ć®å€¤ćŒęø”ć•ć‚Œć¾ć™: + +~~~ +$my_email = "waldo@gmail.com" +validate_email_address($my_email) +validate_email_address("bob@gmail.com", "alice@gmail.com", $my_email) +~~~ + +ä»„äø‹ć®å€¤ćŒäøåˆę ¼ćØćŖć‚Šć€ć‚³ćƒ³ćƒ‘ć‚¤ćƒ«ćŒäø­ę­¢ć•ć‚Œć¾ć™: + +~~~ +$some_array = [ 'bad_email@/d/efdf.com' ] +validate_email_address($some_array) +~~~ + +*ć‚æć‚¤ćƒ—*: ć‚¹ćƒ†ćƒ¼ćƒˆćƒ”ćƒ³ćƒˆ + +#### `validate_hash` + +**éžęŽØå„Ø:**ä»Šå¾Œć®ćƒćƒ¼ć‚øćƒ§ćƒ³ć®stdlibć§ćÆå‰Šé™¤ć•ć‚Œć¾ć™ć€‚[`validate_legacy`](#validate_legacy)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +ęø”ć•ć‚ŒćŸć™ć¹ć¦ć®å€¤ćŒćƒćƒƒć‚·ćƒ„ćƒ‡ćƒ¼ć‚æę§‹é€ ć§ć‚ć‚‹ć“ćØć‚’ē¢ŗčŖć—ć¾ć™ć€‚ć“ć®ćƒć‚§ćƒƒć‚Æć§äøåˆę ¼ćØćŖć£ćŸå€¤ćŒć‚ć‚‹å “åˆćÆć€ć‚«ć‚æćƒ­ć‚°ć‚³ćƒ³ćƒ‘ć‚¤ćƒ«ćŒäø­ę­¢ć•ć‚Œć¾ć™ć€‚ + +ä»„äø‹ć®å€¤ćŒęø”ć•ć‚Œć¾ć™: + +```puppet +$my_hash = { 'one' => 'two' } +validate_hash($my_hash) +``` + +ä»„äø‹ć®å€¤ćÆå¤±ę•—ć«ćŖć‚Šć€ć‚³ćƒ³ćƒ‘ć‚¤ćƒ«ćŒäø­ę­¢ć•ć‚Œć¾ć™: + +```puppet +validate_hash(true) +validate_hash('some_string') +$undefined = `undef` +validate_hash($undefined) +``` + +*ć‚æć‚¤ćƒ—*: ć‚¹ćƒ†ćƒ¼ćƒˆćƒ”ćƒ³ćƒˆ + +#### `validate_integer` + +**éžęŽØå„Ø:**ä»Šå¾Œć®ćƒćƒ¼ć‚øćƒ§ćƒ³ć®stdlibć§ćÆå‰Šé™¤ć•ć‚Œć¾ć™ć€‚[`validate_legacy`](#validate_legacy)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +ę•“ę•°ć¾ćŸćÆę•“ę•°ć®é…åˆ—ć‚’ē¢ŗčŖć—ć¾ć™ć€‚ć„ćšć‚Œć‹ćŒćƒć‚§ćƒƒć‚Æć§äøåˆę ¼ć«ćŖć£ćŸå “åˆć«ćÆć€ć‚«ć‚æćƒ­ć‚°ć‚³ćƒ³ćƒ‘ć‚¤ćƒ«ćŒäø­ę­¢ć•ć‚Œć¾ć™ć€‚ + +引数: + +* 第1ć®å¼•ę•°ćØć—ć¦ć€ę•“ę•°ć¾ćŸćÆę•“ę•°ć®é…åˆ—ć€‚ +* ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć®ē¬¬2ć®å¼•ę•°ćØć—ć¦ć€ęœ€å¤§å€¤ć€‚ē¬¬1の引数(のすべての要瓠)ćÆć€ć“ć®ęœ€å¤§å€¤ä»„äø‹ć§ćŖć‘ć‚Œć°ćŖć‚Šć¾ć›ć‚“ć€‚ +* ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć®ē¬¬3ć®å¼•ę•°ćØć—ć¦ć€ęœ€å°å€¤ć€‚ē¬¬1の引数(のすべての要瓠)ćÆć€ć“ć®ęœ€å¤§å€¤ä»„äøŠć§ćŖć‘ć‚Œć°ćŖć‚Šć¾ć›ć‚“ć€‚ + +第1ć®å¼•ę•°ćŒę•“ę•°ć¾ćŸćÆę•“ę•°ć®é…åˆ—ć§ćŖć„å “åˆć‚„ć€ē¬¬2または第3ć®å¼•ę•°ćŒę•“ę•°ć«å¤‰ę›ć§ććŖć„å “åˆćÆć€ć“ć®é–¢ę•°ćÆå¤±ę•—ć«ćŖć‚Šć¾ć™ć€‚ćŸć ć—ć€ęœ€å°å€¤ćŒäøŽćˆć‚‰ć‚Œć¦ć„ć‚‹å “åˆćÆ(ć“ć®å “åˆć«é™ć‚‰ć‚Œć¾ć™)、第2ć®å¼•ę•°ć‚’ē©ŗę–‡å­—åˆ—ć¾ćŸćÆ`undef`ć«ć™ć‚‹ć“ćØćŒåÆčƒ½ć§ć™ć€‚ć“ć‚ŒćÆć€ęœ€å°ćƒć‚§ćƒƒć‚Æć‚’ē¢ŗå®Ÿć«č”Œć†ćŸć‚ć®ćƒ—ćƒ¬ćƒ¼ć‚¹ćƒ›ćƒ«ćƒ€ćƒ¼ćØć—ć¦ę©Ÿčƒ½ć—ć¾ć™ć€‚ + +ä»„äø‹ć®å€¤ćŒęø”ć•ć‚Œć¾ć™: + +```puppet +validate_integer(1) +validate_integer(1, 2) +validate_integer(1, 1) +validate_integer(1, 2, 0) +validate_integer(2, 2, 2) +validate_integer(2, '', 0) +validate_integer(2, `undef`, 0) +$foo = `undef` +validate_integer(2, $foo, 0) +validate_integer([1,2,3,4,5], 6) +validate_integer([1,2,3,4,5], 6, 0) +``` + +* åŠ ćˆć¦ć€äøŠčæ°ć®ć™ć¹ć¦ć€‚ćŸć ć—ć€ę–‡å­—åˆ—ćØć—ć¦ęø”ć•ć‚ŒćŸå€¤ć‚’ä»»ę„ć«ēµ„ćæåˆć‚ć›ćŸć‚‚ć®('1'または"1")怂 +* åŠ ćˆć¦ć€äøŠčæ°ć®ć™ć¹ć¦ć€‚ćŸć ć—ć€č² ć®ę•“ę•°å€¤ć‚’(é©åˆ‡ć«)ēµ„ćæåˆć‚ć›ćŸć‚‚ć®ć€‚ + +ä»„äø‹ć®å€¤ćÆå¤±ę•—ć«ćŖć‚Šć€ć‚³ćƒ³ćƒ‘ć‚¤ćƒ«ćŒäø­ę­¢ć•ć‚Œć¾ć™: + +```puppet +validate_integer(true) +validate_integer(false) +validate_integer(7.0) +validate_integer({ 1 => 2 }) +$foo = `undef` +validate_integer($foo) +validate_integer($foobaridontexist) + +validate_integer(1, 0) +validate_integer(1, true) +validate_integer(1, '') +validate_integer(1, `undef`) +validate_integer(1, , 0) +validate_integer(1, 2, 3) +validate_integer(1, 3, 2) +validate_integer(1, 3, true) +``` + +* åŠ ćˆć¦ć€äøŠčæ°ć®ć™ć¹ć¦ć€‚ćŸć ć—ć€ę–‡å­—åˆ—ćØć—ć¦ęø”ć•ć‚ŒćŸå€¤ć‚’ä»»ę„ć«ēµ„ćæåˆć‚ć›ćŸć‚‚ć® (`false`ć€ć¾ćŸćÆ"false")怂 +* åŠ ćˆć¦ć€äøŠčæ°ć®ć™ć¹ć¦ć€‚ćŸć ć—ć€č² ć®ę•“ę•°å€¤ć‚’äøé©åˆ‡ć«ēµ„ćæåˆć‚ć›ćŸć‚‚ć®ć€‚ +* åŠ ćˆć¦ć€äøŠčæ°ć®ć™ć¹ć¦ć€‚ćŸć ć—ć€é…åˆ—å†…ć®éžę•“ę•°ć‚¢ć‚¤ćƒ†ćƒ ć¾ćŸćÆęœ€å¤§/ęœ€å°å¼•ę•°ć‚’ē”Øć„ćŸć‚‚ć®ć€‚ + +*ć‚æć‚¤ćƒ—*: ć‚¹ćƒ†ćƒ¼ćƒˆćƒ”ćƒ³ćƒˆ + +#### `validate_ip_address` + +**éžęŽØå„Ø:**ä»Šå¾Œć®ćƒćƒ¼ć‚øćƒ§ćƒ³ć®stdlibć§ćÆå‰Šé™¤ć•ć‚Œć¾ć™ć€‚[`validate_legacy`](#validate_legacy)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +IPv4ć‚¢ćƒ‰ćƒ¬ć‚¹ć‹IPv6ć‚¢ćƒ‰ćƒ¬ć‚¹ć‹ć«ć‹ć‹ć‚ć‚‰ćšć€å¼•ę•°ćŒIPć‚¢ćƒ‰ćƒ¬ć‚¹ć§ć‚ć‚‹ć“ćØć‚’ē¢ŗčŖć—ć¾ć™ć€‚ć¾ćŸć€ćƒćƒƒćƒˆćƒžć‚¹ć‚Æć«ć‚ˆć‚ŠIPć‚¢ćƒ‰ćƒ¬ć‚¹ć‚’ē¢ŗčŖć—ć¾ć™ć€‚ + +引数: IPć‚¢ćƒ‰ćƒ¬ć‚¹ć‚’ęŒ‡å®šć™ć‚‹ę–‡å­—åˆ—ć€‚ + +ä»„äø‹ć®å€¤ćŒęø”ć•ć‚Œć¾ć™: + +```puppet +validate_ip_address('0.0.0.0') +validate_ip_address('8.8.8.8') +validate_ip_address('127.0.0.1') +validate_ip_address('194.232.104.150') +validate_ip_address('3ffe:0505:0002::') +validate_ip_address('::1/64') +validate_ip_address('fe80::a00:27ff:fe94:44d6/64') +validate_ip_address('8.8.8.8/32') +``` + +ä»„äø‹ć®å€¤ćÆå¤±ę•—ć«ćŖć‚Šć€ć‚³ćƒ³ćƒ‘ć‚¤ćƒ«ćŒäø­ę­¢ć•ć‚Œć¾ć™: + +```puppet +validate_ip_address(1) +validate_ip_address(true) +validate_ip_address(0.0.0.256) +validate_ip_address('::1', {}) +validate_ip_address('0.0.0.0.0') +validate_ip_address('3.3.3') +validate_ip_address('23.43.9.22/64') +validate_ip_address('260.2.32.43') +``` + + +#### `validate_legacy` + +ęŒ‡å®šć—ćŸć‚æć‚¤ćƒ—ćŠć‚ˆć³éžęŽØå„Øć®ē¢ŗčŖé–¢ę•°ć®äø”ę–¹ć«ē…§ć‚‰ć—ć¦å€¤ć‚’ē¢ŗčŖć—ć¾ć™ć€‚äø”ę–¹ć«ćƒ‘ć‚¹ć—ćŸå “åˆćÆćć®ć¾ć¾ćƒ‘ć‚¹ć—ć€ē‰‡ę–¹ć®ē¢ŗčŖć®ćæć«ćƒ‘ć‚¹ć—ćŸå “åˆćÆć‚Øćƒ©ćƒ¼ćŒē”Ÿć˜ć€äø”ę–¹ć®ē¢ŗčŖć§falsećŒčæ”ć•ć‚ŒćŸå “åˆćÆå¤±ę•—ć«ćŖć‚Šć¾ć™ć€‚ + +引数: + +* å€¤ć®ćƒć‚§ćƒƒć‚Æć«ē”Øć„ć‚‹ć‚æć‚¤ćƒ—ć€‚ +* éŽåŽ»ć®ē¢ŗčŖé–¢ę•°ć®ćƒ•ćƒ«ćƒćƒ¼ćƒ ć€‚ +* ćƒć‚§ćƒƒć‚Æć™ć‚‹å€¤ć€‚ +* éŽåŽ»ć®ē¢ŗčŖé–¢ę•°ć«åæ…č¦ćŖå¼•ę•°ć®äøē‰¹å®šę•°ć€‚ + +例: + +```puppet +validate_legacy('Optional[String]', 'validate_re', 'Value to be validated', ["."]) +``` + +この関数は、Puppet 3å½¢å¼ć®å¼•ę•°ē¢ŗčŖ(stdlib恮`validate_*`関数を使用)恋悉Puppet 4ćƒ‡ćƒ¼ć‚æć‚æć‚¤ćƒ—ćøć®ćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ć®ć‚¢ćƒƒćƒ—ćƒ‡ćƒ¼ćƒˆć«åÆ¾åæœć—ć¦ćŠć‚Šć€Puppet 3å½¢å¼ć®ē¢ŗčŖć«é ¼ć£ć¦ć„ć‚‹å “åˆć‚‚ę©Ÿčƒ½ę€§ćŒäø­ę–­ć™ć‚‹ć“ćØćÆć‚ć‚Šć¾ć›ć‚“ć€‚ + +> 注: この関数は、Puppet 4.4.0 (PE 2016.1)ä»„é™ć«ć®ćæåÆ¾åæœć—ć¦ć„ć¾ć™ć€‚ + +##### ćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ćƒ¦ćƒ¼ć‚¶ćø + +Puppet 4ć‚’ä½æē”Øć—ć¦ć„ć‚‹å “åˆć€`validate_legacy`é–¢ę•°ć‚’ä½æćˆć°ć€éžęŽØå„Øć®Puppet 3恮`validate_*`é–¢ę•°ć‚’ęŽ¢ć—ć€åˆ†é›¢ć™ć‚‹ć“ćØćŒć§ćć¾ć™ć€‚ć“ć‚Œć‚‰ć®é–¢ę•°ćÆć€stdlibćƒćƒ¼ć‚øćƒ§ćƒ³4.13ę™‚ē‚¹ć§éžęŽØå„Øć«ćŖć£ć¦ćŠć‚Šć€ä»Šå¾Œć®stdlibćƒćƒ¼ć‚øćƒ§ćƒ³ć§ćÆå‰Šé™¤ć•ć‚Œć¾ć™ć€‚ + +Puppet 4では、[ćƒ‡ćƒ¼ć‚æć‚æć‚¤ćƒ—](https://puppet.com/docs/puppet/latest/lang_data.html)ć‚’ē”Øć„ćŸę”¹č‰Æē‰ˆć®ćƒ¦ćƒ¼ć‚¶å®šē¾©ć‚æć‚¤ćƒ—ć®ćƒć‚§ćƒƒć‚ÆćŒåÆčƒ½ć§ć™ć€‚ćƒ‡ćƒ¼ć‚æć‚æć‚¤ćƒ—ć§ćÆć€Puppet 3恮`validate_*`é–¢ę•°ć§č¦‹ć‚‰ć‚ŒćŸć€äøę•“åˆć«ć¤ćŖćŒć‚‹ć„ćć¤ć‹ć®å•é”Œć‚’å›žéæć§ćć¾ć™ć€‚ä¾‹ćˆć°ć€[validate_numeric](#validate_numeric)ć§ćÆć€ę•°å­—ć ć‘ć§ćŖćć€ę•°å­—ć®é…åˆ—ć‚„ę•°å­—ć®ć‚ˆć†ć«č¦‹ćˆć‚‹ę–‡å­—åˆ—ć‚‚ę„å›³ć«åć—ć¦čØ±åÆć•ć‚Œć¦ć„ć¾ć—ćŸć€‚ + +Puppet 4ćØćØć‚‚ć«ć€éžęŽØå„Øć® `validate_*`é–¢ę•°ć‚’ē”Øć„ćŸćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ć‚’ä½æē”Øć—ć¦ć„ć‚‹å “åˆćÆć€éžęŽØå„Øćƒ”ćƒƒć‚»ćƒ¼ć‚øćŒč”Øē¤ŗć•ć‚Œć‚‹ć“ćØćŒć‚ć‚Šć¾ć™ć€‚`validate_legacy`é–¢ę•°ć‚’ä½æćˆć°ć€ćć†ć—ćŸå·®ē•°ć‚’åÆč¦–åŒ–ć—ć€ć‚ˆć‚Šę˜Žåæ«ćŖPuppet 4ę§‹ę–‡ć«ē°”å˜ć«ē§»č”Œć™ć‚‹ć“ćØćŒć§ćć¾ć™ć€‚ + +č”Øē¤ŗć•ć‚Œć‚‹éžęŽØå„Øćƒ”ćƒƒć‚»ćƒ¼ć‚øćÆć€ä½æē”Øć—ć¦ć„ć‚‹ćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ć‚„ćƒ‡ćƒ¼ć‚æć«ć‚ˆć£ć¦ē•°ćŖć‚‹ć“ćØćŒć‚ć‚Šć¾ć™ć€‚ä»„äø‹ć®éžęŽØå„Øćƒ”ćƒƒć‚»ćƒ¼ć‚øćÆć€Puppet 4ć§ć®ćæćƒ‡ćƒ•ć‚©ćƒ«ćƒˆć§č”Øē¤ŗć•ć‚Œć¾ć™: + +* `Notice: Accepting previously invalid value for target type ''`: ć“ć®ćƒ”ćƒƒć‚»ćƒ¼ć‚øćÆć€ęƒ…å ±ęä¾›ć®ē›®ēš„ć®ćæć§č”Øē¤ŗć•ć‚Œć‚‹ć‚‚ć®ć§ć™ć€‚ä½æē”Øć—ć¦ć„ć‚‹å€¤ćÆć€ę–°å½¢å¼ć§čØ±åÆć•ć‚Œć¦ć„ć¾ć™ćŒć€ę—§ē¢ŗčŖé–¢ę•°ć§ćÆē„”åŠ¹ćØćŖć‚Šć¾ć™ć€‚ +* `Warning: This method is deprecated, please use the stdlib validate_legacy function`: ćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ćŒć¾ć `validate_legacy`ć«ć‚¢ćƒƒćƒ—ć‚°ćƒ¬ćƒ¼ćƒ‰ć•ć‚Œć¦ć„ć¾ć›ć‚“ć€‚[deprecation](#deprecation)ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć‚’ä½æē”Øć—ć¦ć•ć—ć‚ćŸć‚Šč­¦å‘Šć‚’č§£é™¤ć™ć‚‹ć‹ć€ćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ć®é–‹ē™ŗč€…ć«äæ®ę­£ē‰ˆć‚’ęå‡ŗć•ć›ć¦ćć ć•ć„ć€‚ć“ć®å•é”Œć®č§£ę±ŗę–¹ę³•ć«ć¤ć„ć¦ćÆć€ä»„äø‹ć®[ćƒ¢ć‚øćƒ„ćƒ¼ćƒ«é–‹ē™ŗč€…ćø](#ćƒ¢ć‚øćƒ„ćƒ¼ćƒ«é–‹ē™ŗč€…ćø)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ +* `Warning: validate_legacy() expected value, got _`: ć‚³ćƒ¼ćƒ‰ćŒęø”ć™å€¤ćÆć€Puppet 3å½¢å¼ć®ē¢ŗčŖć§ćÆčŖć‚ć‚‰ć‚Œć¾ć™ćŒć€ę¬”ćƒćƒ¼ć‚øćƒ§ćƒ³ć®ćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ć§ćÆčŖć‚ć‚‰ć‚Œć¾ć›ć‚“ć€‚ć»ćØć‚“ć©ć®å “åˆć€ę•°å­—ć¾ćŸćÆćƒ–ćƒ¼ćƒŖć‚¢ćƒ³ć‹ć‚‰ć‚Æć‚©ćƒ¼ćƒˆć‚’å‰Šé™¤ć™ć‚Œć°ć€ć“ć®å•é”Œć‚’č§£ę±ŗć™ć‚‹ć“ćØćŒć§ćć¾ć™ć€‚ +* `Error: Evaluation Error: Error while evaluating a Resource Statement, Evaluation Error: Error while evaluating a Function Call, validate_legacy() expected value, got `: ć‚³ćƒ¼ćƒ‰ć®ęø”ć™å€¤ćÆć€ę–°å½¢å¼ć®ē¢ŗčŖć§ć‚‚ę—§å½¢å¼ć®ē¢ŗčŖć§ć‚‚čŖć‚ć‚‰ć‚Œć¾ć›ć‚“ć€‚ + +##### ćƒ¢ć‚øćƒ„ćƒ¼ćƒ«é–‹ē™ŗč€…ćø + +`validate_legacy`é–¢ę•°ćÆć€ćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ćƒ¦ćƒ¼ć‚¶ć®ä½æē”Øć—ć¦ć„ć‚‹ę©Ÿčƒ½ć‚’äø­ę–­ć•ć›ćšć«ć€ Puppet 3å½¢å¼ć®ē¢ŗčŖć‹ć‚‰Puppet 4å½¢å¼ć®ē¢ŗčŖć«ē§»č”Œć™ć‚‹ć®ć«å½¹ē«‹ć”ć¾ć™ć€‚ + +Puppet 4å½¢å¼ć®ē¢ŗčŖć«ē§»č”Œć™ć‚Œć°ć€[ćƒ‡ćƒ¼ć‚æć‚æć‚¤ćƒ—](https://puppet.com/docs/puppet/latest/lang_data.html)ć‚’ē”Øć„ćŸć€ć‚ˆć‚Šę˜Žē¢ŗćŖćƒ¦ćƒ¼ć‚¶å®šē¾©ć‚æć‚¤ćƒ—ć®ćƒć‚§ćƒƒć‚ÆćŒåÆčƒ½ć«ćŖć‚Šć¾ć™ć€‚Puppet 3恮`validate_*` é–¢ę•°ć®å¤šććÆć€ē¢ŗčŖćØć„ć†ē‚¹ć§é©šćć»ć©å¤šćć®ē©“ćŒć‚ć‚Šć¾ć™ć€‚ä¾‹ćˆć°ć€[validate_numeric](#validate_numeric)ć§ćÆć€ē“°éƒØć‚’ć‚³ćƒ³ćƒˆćƒ­ćƒ¼ćƒ«ć§ććŖć„ćŸć‚ć€ę•°å­—ć ć‘ć§ćŖćć€ę•°å­—ć®é…åˆ—ć‚„ę•°å­—ć®ć‚ˆć†ć«č¦‹ćˆć‚‹ę–‡å­—åˆ—ć‚‚čØ±åÆć•ć‚Œć¾ć™ć€‚ + +ć‚Æćƒ©ć‚¹ćŠć‚ˆć³å®šē¾©ć‚æć‚¤ćƒ—ć®å„ćƒ‘ćƒ©ćƒ”ćƒ¼ć‚æć«ć¤ć„ć¦ć€ä½æē”Øć™ć‚‹ę–°ć—ć„Puppet 4ćƒ‡ćƒ¼ć‚æć‚æć‚¤ćƒ—ć‚’éøęŠžć—ć¦ćć ć•ć„ć€‚ćŸć„ć¦ć„ć®å “åˆć€ę–°ć—ć„ćƒ‡ćƒ¼ć‚æć‚æć‚¤ćƒ—ć«ć‚ˆć‚Šć€å…ƒć®`validate_*`é–¢ę•°ćØćÆē•°ćŖć‚‹å€¤ć®ć‚»ćƒƒćƒˆć‚’ä½æē”Øć§ćć‚‹ć‚ˆć†ć«ćŖć‚Šć¾ć™ć€‚ä»„äø‹ć®ć‚ˆć†ćŖēŠ¶ę³ć«ćŖć‚Šć¾ć™: + +| | `validate_` pass | `validate_` fail | +| ------------ | ---------------- | ---------------- | +| ć‚æć‚¤ćƒ—ć«äø€č‡“ć—ć¾ć™ | 成功 | ęˆåŠŸć€é€šēŸ„ | +| ć‚æć‚¤ćƒ—ć®å¤±ę•— | ęˆåŠŸć€å»ƒę­¢äŗˆå®š | 失敗 | + +ē¾åœØć®ćØć“ć‚ć€ē¢ŗčŖå¾Œć®ć‚³ćƒ¼ćƒ‰ć§ć‚‚ć€ć™ć¹ć¦ć®åÆčƒ½ćŖå€¤ć«åÆ¾å‡¦ć™ć‚‹åæ…č¦ćŒć‚ć‚Šć¾ć™ćŒć€ę–°å½¢å¼ć«ćƒžćƒƒćƒć™ć‚‹å€¤ć®ćæć‚’ęø”ć™ć‚ˆć†ć«ć€ć‚³ćƒ¼ćƒ‰ć®ćƒ¦ćƒ¼ć‚¶ćŒćƒžćƒ‹ćƒ•ć‚§ć‚¹ćƒˆć‚’å¤‰ę›“ć™ć‚‹ć“ćØćŒć§ćć¾ć™ć€‚ + +stdlib恮`validate_*`é–¢ę•°ćć‚Œćžć‚Œć«ć¤ć„ć¦ć€ćƒžćƒƒćƒć™ć‚‹`Stdlib::Compat::*`ć‚æć‚¤ćƒ—ćŒć‚ć‚Šć€é©åˆ‡ćŖå€¤ć®ć‚»ćƒƒćƒˆćŒčØ±åÆć•ć‚Œć¾ć™ć€‚ę³Øę„äŗ‹é …ć«ć¤ć„ć¦ćÆć€stdlibć‚½ćƒ¼ć‚¹ć‚³ćƒ¼ćƒ‰ć® `types/`ćƒ‡ć‚£ćƒ¬ć‚ÆćƒˆćƒŖć«ć‚ć‚‹ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +ćŸćØćˆć°ć€ę•°å­—ć®ćæćŒčØ±åÆć•ć‚Œć‚‹ć‚Æćƒ©ć‚¹ć‚’äøŽćˆć‚‹ćØć€ä»„äø‹ć®ć‚ˆć†ć«ćŖć‚Šć¾ć™: + +```puppet +class example($value) { + validate_numeric($value) +``` + +å¾—ć‚‰ć‚Œć‚‹ē¢ŗčŖć‚³ćƒ¼ćƒ‰ćÆć€ä»„äø‹ć®ć‚ˆć†ć«ćŖć‚Šć¾ć™: + +```puppet +ć‚Æćƒ©ć‚¹ć®ä¾‹( + Variant[Stdlib::Compat::Numeric, Numeric] $value +) { + validate_legacy(Numeric, 'validate_numeric', $value) +``` + +ここでは、`$value`ć®ć‚æć‚¤ćƒ—ćŒ`Variant[Stdlib::Compat::Numeric, Numeric]`ćØå®šē¾©ć•ć‚Œć¦ć„ć¾ć™ć€‚ć“ć‚Œć«ć‚ˆć‚Šć€ä»»ę„ć®`Numeric` (ę–°å½¢å¼)恮恻恋态`validate_numeric`恧(`Stdlib::Compat::Numeric`ć‚’é€šć˜ć¦)ć“ć‚Œć¾ć§čØ±åÆć•ć‚Œć¦ć„ćŸć™ć¹ć¦ć®å€¤ć‚’ä½æē”Øć§ćć¾ć™ć€‚ + +`validate_legacy`ć‚’å‘¼ć³å‡ŗć™ćØć€é©åˆ‡ćŖćƒ­ć‚°ć¾ćŸćÆå¤±ę•—ćƒ”ćƒƒć‚»ćƒ¼ć‚øć®ćƒˆćƒŖć‚¬ćƒ¼ćŒå‡¦ē†ć•ć‚Œć¾ć™ć€‚ć“ć‚Œć«ćÆć€ę–°å½¢å¼ć€ä»„å‰ć®ē¢ŗčŖé–¢ę•°ć®åē§°ć€ćŠć‚ˆć³ćć®é–¢ę•°ć®ć™ć¹ć¦ć®å¼•ę•°ćŒåæ…č¦ć§ć™ć€‚ + +ćŠä½æć„ć®ćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ćŒć¾ć Puppet 3ć‚’ć‚µćƒćƒ¼ćƒˆć—ć¦ć„ć‚‹å “åˆćÆć€ć“ć‚ŒćÆäŗ’ę›ę€§ć‚’ē “ć‚‹å¤‰ę›“ć«ćŖć‚Šć¾ć™ć€‚`metadata.json`č¦ä»¶ć‚»ć‚Æć‚·ćƒ§ćƒ³ć‚’ć‚¢ćƒƒćƒ—ćƒ‡ćƒ¼ćƒˆć—ć¦ćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ćŒć‚‚ć†Puppet 3ć‚’ć‚µćƒćƒ¼ćƒˆć—ć¦ć„ćŖć„ć“ćØć‚’ē¤ŗć—ć€ćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ć®ćƒ”ć‚øćƒ£ćƒ¼ćƒćƒ¼ć‚øćƒ§ćƒ³ć‚’ę”¾ę£„ć—ć¦ćć ć•ć„ć€‚ć“ć®å¤‰ę›“ć‚’åŠ ćˆć¦ć‚‚ć€ćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ć«é–¢ć™ć‚‹ę—¢å­˜ć®ć™ć¹ć¦ć®ćƒ†ć‚¹ćƒˆć«ćƒ‘ć‚¹ć™ć‚‹ćÆćšć§ć™ć€‚ę–°ćŸć«åÆčƒ½ć«ćŖć£ćŸå€¤ć«ć¤ć„ć¦ć€čæ½åŠ ć®ćƒ†ć‚¹ćƒˆć‚’ä½œęˆć—ć¦ćć ć•ć„ć€‚ + +ć“ć‚ŒćÆäŗ’ę›ę€§ć‚’ē “ć‚‹å¤‰ę›“ć§ć‚ć‚‹ć“ćØć‹ć‚‰ć€å–ć‚Šé™¤ććŸć„ć™ć¹ć¦ć®ćƒ‘ćƒ©ćƒ”ćƒ¼ć‚æć«ć¤ć„ć¦ [`deprecation`](#deprecation)ć‚’ć‚³ćƒ¼ćƒ«ć—ćŸć‚Šć€ćƒ‘ćƒ©ćƒ”ćƒ¼ć‚æć«ć•ć‚‰ćŖć‚‹åˆ¶ē“„ć‚’čæ½åŠ ć—ćŸć‚Šć™ć‚‹č‰Æć„ę©Ÿä¼šć§ć‚‚ć‚ć‚Šć¾ć™ć€‚ + +ć“ć®ćƒćƒ¼ć‚øćƒ§ćƒ³ć®ćƒŖćƒŖćƒ¼ć‚¹å¾Œć€äŗ’ę›ę€§ć‚’ē “ć‚‹å¤‰ę›“ć‚’åŠ ćˆćŸåˆ„ć®ćƒŖćƒŖćƒ¼ć‚¹ć‚’å…¬é–‹ć—ć€ć™ć¹ć¦ć®äŗ’ę›ę€§ć‚æć‚¤ćƒ—ćŠć‚ˆć³ `validate_legacy`ć®ć‚³ćƒ¼ćƒ«ć‚’å‰Šé™¤ć™ć‚‹ć“ćØćŒć§ćć¾ć™ć€‚ćć®ę™‚ē‚¹ć§ć€ć‚³ćƒ¼ćƒ‰ć‚’å®Ÿč”Œć—ć€éŽåŽ»ć«åÆčƒ½ć ć£ćŸå€¤ć«é–¢ć™ć‚‹ę®‹ä½™č¦ē“ ć‚’å–ć‚Šé™¤ćć“ćØć‚‚ć§ćć¾ć™ć€‚ + +ćć†ć—ćŸå¤‰ę›“ć«ć¤ć„ć¦ćÆć€åæ…ćšCHANGELOGćŠć‚ˆć³READMEć§é€šå‘Šć—ć¦ćć ć•ć„ć€‚ + +#### `validate_numeric` + +**éžęŽØå„Ø:**ä»Šå¾Œć®ćƒćƒ¼ć‚øćƒ§ćƒ³ć®stdlibć§ćÆå‰Šé™¤ć•ć‚Œć¾ć™ć€‚[`validate_legacy`](#validate_legacy)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +ę•°å€¤ć¾ćŸćÆę•°å€¤ć®é…åˆ—ć‚„ę–‡å­—åˆ—ć‚’ē¢ŗčŖć—ć¾ć™ć€‚ć„ćšć‚Œć‹ćŒćƒć‚§ćƒƒć‚Æć«å¤±ę•—ć—ćŸå “åˆć«ćÆć€ć‚«ć‚æćƒ­ć‚°ć‚³ćƒ³ćƒ‘ć‚¤ćƒ«ćŒäø­ę­¢ć•ć‚Œć¾ć™ć€‚ + +引数: + +* ę•°å€¤ć€ć¾ćŸćÆę•°å€¤ć®é…åˆ—ć‹ę–‡å­—åˆ—ć€‚ +* ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć§ć€ęœ€å¤§å€¤ć€‚ē¬¬1の引数(のすべての要瓠) ćÆć€ć“ć®ęœ€å¤§å€¤ä»„äø‹ć§ćŖć‘ć‚Œć°ćŖć‚Šć¾ć›ć‚“ć€‚ +* ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć§ć€ęœ€å°å€¤ć€‚ē¬¬1の引数(のすべての要瓠)ćÆć€ć“ć®ęœ€å°å€¤ä»„äøŠć§ćŖć‘ć‚Œć°ćŖć‚Šć¾ć›ć‚“ć€‚ + +第1ć®å¼•ę•°ćŒę•°å€¤(ę•“ę•°ć¾ćŸćÆćƒ•ćƒ­ćƒ¼ćƒˆ)ć¾ćŸćÆę•°å€¤ć®é…åˆ—ćŒę–‡å­—åˆ—ć§ćŖć„å “åˆć‚„ć€ē¬¬2ćŠć‚ˆć³ē¬¬3ć®å¼•ę•°ćŒę•°å€¤ć«å¤‰ę›ć§ććŖć„å “åˆćÆć€ć“ć®é–¢ę•°ćÆå¤±ę•—ć«ćŖć‚Šć¾ć™ć€‚ęœ€å°å€¤ćŒäøŽćˆć‚‰ć‚Œć¦ć„ć‚‹å “åˆćÆ(ć“ć®å “åˆć«é™ć‚‰ć‚Œć¾ć™)、第2ć®å¼•ę•°ć‚’ē©ŗę–‡å­—åˆ—ć¾ćŸćÆ`undef`ć«ć™ć‚‹ć“ćØćŒåÆčƒ½ć§ć™ć€‚ć“ć‚ŒćÆć€ęœ€å°ćƒć‚§ćƒƒć‚Æć‚’ē¢ŗå®Ÿć«č”Œć†ćŸć‚ć®ćƒ—ćƒ¬ćƒ¼ć‚¹ćƒ›ćƒ«ćƒ€ćƒ¼ćØć—ć¦ę©Ÿčƒ½ć—ć¾ć™ć€‚ + +ćƒ‘ć‚¹ćŠć‚ˆć³å¤±ę•—ć®ä½æē”Øć«ć¤ć„ć¦ćÆć€[`validate_integer`](#validate-integer)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚åŒć˜å€¤ćŒćƒ‘ć‚¹ćŠć‚ˆć³å¤±ę•—ć—ć¾ć™ć€‚ćŸć ć—ć€`validate_numeric`ć§ćÆć€ęµ®å‹•å°ę•°ē‚¹å€¤ć‚‚čØ±åÆć•ć‚Œć¾ć™ć€‚ + +*ć‚æć‚¤ćƒ—*: ć‚¹ćƒ†ćƒ¼ćƒˆćƒ”ćƒ³ćƒˆ + +#### `validate_re` + +**éžęŽØå„Ø:**ä»Šå¾Œć®ćƒćƒ¼ć‚øćƒ§ćƒ³ć®stdlibć§ćÆå‰Šé™¤ć•ć‚Œć¾ć™ć€‚[`validate_legacy`](#validate_legacy)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +1ć¤ć¾ćŸćÆč¤‡ę•°ć®ę­£č¦č”Øē¾ć«ē…§ć‚‰ć—ć¦ć€ę–‡å­—åˆ—ć®ē°”å˜ćŖē¢ŗčŖć‚’č”Œć„ć¾ć™ć€‚ + +引数: + +* 第1ć®å¼•ę•°ćØć—ć¦ć€ćƒ†ć‚¹ćƒˆć™ć‚‹ę–‡å­—åˆ—ć€‚ć“ć®å¼•ę•°ćŒę–‡å­—åˆ—ć§ćŖć„å “åˆć€ć‚³ćƒ³ćƒ‘ć‚¤ćƒ«ćŒäø­ę­¢ć•ć‚Œć¾ć™ć€‚ć‚Æć‚©ćƒ¼ćƒˆć‚’ē”Øć„ć¦å¼·åˆ¶ēš„ć«ę–‡å­—åˆ—åŒ–ć—ć¦ćć ć•ć„ć€‚ +* 第2ć®å¼•ę•°ćØć—ć¦ć€ę–‡å­—åˆ—åŒ–ć—ćŸę­£č¦č”Øē¾(åŒŗåˆ‡ć‚Šę–‡å­—//なし)ć¾ćŸćÆę­£č¦č”Øē¾ć®é…åˆ—ć€‚ +* ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć®ē¬¬3ć®å¼•ę•°ćØć—ć¦ć€ćƒ¦ćƒ¼ć‚¶ć«č”Øē¤ŗć™ć‚‹ć‚Øćƒ©ćƒ¼ćƒ”ćƒƒć‚»ćƒ¼ć‚øć€‚ + +第2ć®å¼•ę•°ć®ę­£č¦č”Øē¾ćŒē¬¬1ć®å¼•ę•°ć§ęø”ć—ćŸę–‡å­—åˆ—ć«ćƒžćƒƒćƒć—ćŖć„å “åˆćÆć€ę§‹ę–‡ć‚Øćƒ©ćƒ¼ć«ć‚ˆć‚Šć‚³ćƒ³ćƒ‘ć‚¤ćƒ«ćŒäø­ę­¢ć•ć‚Œć¾ć™ć€‚ + +ä»„äø‹ć®ę–‡å­—åˆ—ć«ć‚ˆć‚Šć€ę­£č¦č”Øē¾ć«ē…§ć‚‰ć—ć¦ē¢ŗčŖćŒč”Œć‚ć‚Œć¾ć™: + +```puppet +validate_re('one', '^one$') +validate_re('one', [ '^one', '^two' ]) +``` + +ä»„äø‹ć®ę–‡å­—åˆ—ć§ćÆć€ē¢ŗčŖć«å¤±ę•—ć—ć€ć‚³ćƒ³ćƒ‘ć‚¤ćƒ«ćŒäø­ę­¢ć•ć‚Œć¾ć™: + +```puppet +validate_re('one', [ '^two', '^three' ]) +``` + +ć‚Øćƒ©ćƒ¼ćƒ”ćƒƒć‚»ćƒ¼ć‚øć®čØ­å®šę–¹ę³•: + +```puppet +validate_re($::puppetversion, '^2.7', 'The $puppetversion fact value does not match 2.7') +``` + +å¼·åˆ¶ēš„ć«ę–‡å­—åˆ—åŒ–ć™ć‚‹ć«ćÆć€ć‚Æć‚©ćƒ¼ćƒˆć‚’ä½æē”Øć—ć¦ćć ć•ć„: + + ``` + validate_re("${::operatingsystemmajrelease}", '^[57]$') + ``` + +*ć‚æć‚¤ćƒ—*: ć‚¹ćƒ†ćƒ¼ćƒˆćƒ”ćƒ³ćƒˆ + +#### `validate_slength` + +**éžęŽØå„Ø:**ä»Šå¾Œć®ćƒćƒ¼ć‚øćƒ§ćƒ³ć®stdlibć§ćÆå‰Šé™¤ć•ć‚Œć¾ć™ć€‚[`validate_legacy`](#validate_legacy)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +ę–‡å­—åˆ—(ć¾ćŸćÆę–‡å­—åˆ—ć®é…åˆ—)ćŒęŒ‡å®šć—ćŸé•·ć•ä»„äø‹ć§ć‚ć‚‹ć“ćØć‚’ē¢ŗčŖć—ć¾ć™ć€‚ + +引数: + +* 第1ć®å¼•ę•°ćØć—ć¦ć€ę–‡å­—åˆ—ć¾ćŸćÆę–‡å­—åˆ—ć®é…åˆ—ć€‚ +* 第2ć®å¼•ę•°ćØć—ć¦ć€é•·ć•ć®ęœ€å¤§å€¤ć‚’ē¤ŗć™ę•°å€¤ć€‚ +* ć‚Ŗćƒ—ć‚·ćƒ§ćƒ³ć®ē¬¬3ć®å¼•ę•°ćØć—ć¦ć€é•·ć•ć®ęœ€å°å€¤ć‚’ē¤ŗć™ę•°å€¤ć€‚ + + ä»„äø‹ć®å€¤ćŒęø”ć•ć‚Œć¾ć™: + +```puppet +validate_slength("discombobulate",17) +validate_slength(["discombobulate","moo"],17) +validate_slength(["discombobulate","moo"],17,3) +``` + +ä»„äø‹ć®å€¤ćÆå¤±ę•—ć«ćŖć‚Šć¾ć™: + +```puppet +validate_slength("discombobulate",1) +validate_slength(["discombobulate","thermometer"],5) +validate_slength(["discombobulate","moo"],17,10) +``` + +*ć‚æć‚¤ćƒ—*: ć‚¹ćƒ†ćƒ¼ćƒˆćƒ”ćƒ³ćƒˆ + +#### `validate_string` + +**éžęŽØå„Ø:**ä»Šå¾Œć®ćƒćƒ¼ć‚øćƒ§ćƒ³ć®stdlibć§ćÆå‰Šé™¤ć•ć‚Œć¾ć™ć€‚[`validate_legacy`](#validate_legacy)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +ęø”ć—ćŸć™ć¹ć¦ć®å€¤ćŒę–‡å­—åˆ—ćƒ‡ćƒ¼ć‚æę§‹é€ ć§ć‚ć‚‹ć“ćØć‚’ē¢ŗčŖć—ć¾ć™ć€‚ć“ć®ćƒć‚§ćƒƒć‚Æć«å¤±ę•—ć—ćŸå€¤ćŒć‚ć‚‹å “åˆćÆć€ć‚«ć‚æćƒ­ć‚°ć‚³ćƒ³ćƒ‘ć‚¤ćƒ«ćŒäø­ę­¢ć•ć‚Œć¾ć™ć€‚ + +ä»„äø‹ć®å€¤ćŒęø”ć•ć‚Œć¾ć™: + +```puppet +$my_string = "one two" +validate_string($my_string, 'three') +``` + +ä»„äø‹ć®å€¤ćÆå¤±ę•—ć«ćŖć‚Šć€ć‚³ćƒ³ćƒ‘ć‚¤ćƒ«ćŒäø­ę­¢ć•ć‚Œć¾ć™: + +```puppet +validate_string(true) +validate_string([ 'some', 'array' ]) +``` + +注:* validate_string(`undef`)ćÆć€ć“ć®ćƒćƒ¼ć‚øćƒ§ćƒ³ć®é–¢ę•°APIでは失敗しません。 + +ä»£ć‚ć‚Šć«ć€ä»„äø‹ć‚’ä½æē”Øć—ć¦ćć ć•ć„: + + ``` + if $var == `undef` { + fail('...') + } + ``` + +*ć‚æć‚¤ćƒ—*: ć‚¹ćƒ†ćƒ¼ćƒˆćƒ”ćƒ³ćƒˆ + +#### `validate_x509_rsa_key_pair` + +OpenSSLć«ć‚ˆć‚Šć€PEMćƒ•ć‚©ćƒ¼ćƒžćƒƒćƒˆć•ć‚ŒćŸX.509čŖčØ¼ćŠć‚ˆć³ē§˜åÆ†éµć‚’ē¢ŗčŖć—ć¾ć™ć€‚čŖčØ¼ć®ē½²åćŒęä¾›ć•ć‚ŒćŸéµć‹ć‚‰ä½œęˆć•ć‚ŒćŸć‚‚ć®ć§ć‚ć‚‹ć“ćØć‚’ē¢ŗčŖć—ć¾ć™ć€‚ + +ć“ć®ćƒć‚§ćƒƒć‚Æć«å¤±ę•—ć—ćŸå€¤ćŒć‚ć‚‹å “åˆćÆć€ć‚«ć‚æćƒ­ć‚°ć‚³ćƒ³ćƒ‘ć‚¤ćƒ«ćŒäø­ę­¢ć•ć‚Œć¾ć™ć€‚ + +引数: + +* 第1の引数として、X.509čŖčØ¼ć€‚ +* 第2の引数として、RSAćƒ—ćƒ©ć‚¤ćƒ™ćƒ¼ćƒˆć‚­ćƒ¼ć€‚ + +```puppet +validate_x509_rsa_key_pair($cert, $key) +``` + +*ć‚æć‚¤ćƒ—*: ć‚¹ćƒ†ćƒ¼ćƒˆćƒ”ćƒ³ćƒˆ + +#### `values` + +**éžęŽØå„Ø:**この関数は、Puppet 5.5.0で、内蔵の[`values`](https://puppet.com/docs/puppet/latest/function.html#values)é–¢ę•°ć«ē½®ćę›ćˆć‚‰ć‚Œć¾ć—ćŸć€‚ + +äøŽćˆć‚‰ć‚ŒćŸćƒćƒƒć‚·ćƒ„ć®å€¤ć‚’čæ”ć—ć¾ć™ć€‚ + +ćŸćØćˆć°ć€`$hash = {'a'=1, 'b'=2, 'c'=3} values($hash)`ć‚’äøŽćˆć‚‹ćØć€[1,2,3]を返します。 + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `values_at` + +ćƒ­ć‚±ćƒ¼ć‚·ćƒ§ćƒ³ć‚’ć‚‚ćØć«ć€é…åˆ—å†…ć®å€¤ć‚’ęŽ¢ć—ć¾ć™ć€‚ + +引数: + +* 第1ć®å¼•ę•°ćØć—ć¦ć€č§£ęžć—ćŸć„é…åˆ—ć€‚ +* 第2ć®å¼•ę•°ćØć—ć¦ć€ä»„äø‹ć®å€¤ć®ä»»ę„ć®ēµ„ćæåˆć‚ć›: + * å˜äø€ć®ę•°å€¤ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ć€‚ + * 'start-stop'ć®å½¢å¼ć§ć®ēÆ„å›²(4-9など)怂 + * äøŠčØ˜ć‚’ēµ„ćæåˆć‚ć›ćŸé…åˆ—ć€‚ + +例:怀 + +* `values_at(['a','b','c'], 2)`は['c']を返します。 +* `values_at(['a','b','c'], ["0-1"])`は['a','b']を返します。 +* `values_at(['a','b','c','d','e'], [0, "2-3"])`は['a','c','d']を返します。 + +Puppet 4.0.0ä»„é™ć§ćÆć€ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ć§é…åˆ—ć‚’ć‚¹ćƒ©ć‚¤ć‚¹ć—ć€čØ€čŖžć§ē›“ęŽ„ć‚«ć‚¦ćƒ³ćƒˆć™ć‚‹ć“ćØćŒć§ćć¾ć™ć€‚ +č² ć®å€¤ćÆć€é…åˆ—ć®"ęœ€å¾Œć‹ć‚‰"ćØč§£é‡ˆć•ć‚Œć¾ć™ć€‚ä¾‹ćˆć°ć€ę¬”ć®ć‚ˆć†ć«ćŖć‚Šć¾ć™ć€‚ + +```puppet +['a', 'b', 'c', 'd'][1, 2] # results in ['b', 'c'] +['a', 'b', 'c', 'd'][2, -1] # results in ['c', 'd'] +['a', 'b', 'c', 'd'][1, -2] # results in ['b', 'c'] +``` + +*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ + +#### `zip` + +äøŽćˆć‚‰ć‚ŒćŸē¬¬1ć®é…åˆ—ć‹ć‚‰1ć¤ć®č¦ē“ ć‚’ćØć‚Šć€äøŽćˆć‚‰ć‚ŒćŸē¬¬2ć®é…åˆ—ć®åÆ¾åæœć™ć‚‹č¦ē“ ćØēµåˆć—ć¾ć™ć€‚ć“ć‚Œć«ć‚ˆć‚Šć€n-č¦ē“ é…åˆ—ć®ć‚·ćƒ¼ć‚±ćƒ³ć‚¹ćŒē”Ÿęˆć•ć‚Œć¾ć™ć€‚*n*ćÆć€å¼•ę•°ć®ę•°ć‚ˆć‚Š1å¤§ćććŖć‚Šć¾ć™ć€‚ćŸćØćˆć°ć€`zip(['1','2','3'],['4','5','6'])`は["1", "4"], ["2", "5"], ["3", "6"]を返します。*ć‚æć‚¤ćƒ—*: å³č¾ŗå€¤ć€‚ + +## åˆ¶ē“„äŗ‹é … + +Puppet Enterprise 3.7では、stdlibćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ćŒPEć«å«ć¾ć‚Œć¦ć„ć¾ć›ć‚“ć€‚PEćƒ¦ćƒ¼ć‚¶ćÆć€PuppetćØäŗ’ę›ę€§ć®ć‚ć‚‹stdlibć®ęœ€ę–°ćƒŖćƒŖćƒ¼ć‚¹ć‚’ć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ«ć™ć‚‹åæ…č¦ćŒć‚ć‚Šć¾ć™ć€‚ + +ć‚µćƒćƒ¼ćƒˆć•ć‚Œć¦ć„ć‚‹ć‚Ŗćƒšćƒ¬ćƒ¼ćƒ†ć‚£ćƒ³ć‚°ć‚·ć‚¹ćƒ†ćƒ ć®äø€č¦§ć«ć¤ć„ć¦ćÆć€[metadata.json](https://github.com/puppetlabs/puppetlabs-stdlib/blob/main/metadata.json)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +### ćƒćƒ¼ć‚øćƒ§ćƒ³äŗ’ę›ę€§ + +ćƒćƒ¼ć‚øćƒ§ćƒ³ | Puppet 2.6 | Puppet 2.7 | Puppet 3.x | Puppet 4.x | +:---------------|:-----:|:---:|:---:|:----: +**stdlib 2.x** | **yes** | **yes** | 恄恄恈 | 恄恄恈 +**stdlib 3.x** | 恄恄恈 | **yes** | **yes** | 恄恄恈 +**stdlib 4.x** | 恄恄恈 | **yes** | **yes** | 恄恄恈 +**stdlib 4.6+** | 恄恄恈 | **yes** | **yes** | **yes** +**stdlib 5.x** | 恄恄恈 | 恄恄恈 | **yes** | **yes** + +**stdlib 5.x**: stdlib 5.xć®ćƒŖćƒŖćƒ¼ć‚¹ę™‚ć«ćÆć€Puppet 2.7.xć®ć‚µćƒćƒ¼ćƒˆćŒå»ƒę­¢ć•ć‚Œć¾ć™ć€‚[ć“ć®čŖ¬ę˜Ž](https://github.com/puppetlabs/puppetlabs-stdlib/pull/176#issuecomment-30251414)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +## 開発 + +Puppet Forge恮Puppet Labsćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ćÆć‚Ŗćƒ¼ćƒ—ćƒ³ćƒ—ćƒ­ć‚øć‚§ć‚Æćƒˆć§ć€č‰Æć„ēŠ¶ę…‹ć«äæć¤ćŸć‚ć«ćÆć€ć‚³ćƒŸćƒ„ćƒ‹ćƒ†ć‚£ć®č²¢ēŒ®ćŒåæ…č¦äøåÆę¬ ć§ć™ć€‚PuppetćŒå½¹ć«ē«‹ć¤ćÆćšć§ć‚ć‚ŠćŖćŒć‚‰ć€ē§ćŸć”ćŒć‚¢ć‚Æć‚»ć‚¹ć§ććŖć„ćƒ—ćƒ©ćƒƒćƒˆćƒ•ć‚©ćƒ¼ćƒ ć‚„ćƒćƒ¼ćƒ‰ć‚¦ć‚§ć‚¢ć€ć‚½ćƒ•ćƒˆć‚¦ć‚§ć‚¢ć€ćƒ‡ćƒ—ćƒ­ć‚¤ę§‹ęˆćÆē„”ę•°ć«ć‚ć‚Šć¾ć™ć€‚ē§ćŸć”ć®ē›®ęØ™ćÆć€ć§ćć‚‹é™ć‚Šē°”å˜ć«å¤‰ę›“ć«č²¢ēŒ®ć—ć€ćæćŖć•ć¾ć®ē’°å¢ƒć§ē§ćŸć”ć®ćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ćŒę©Ÿčƒ½ć§ćć‚‹ć‚ˆć†ć«ć™ć‚‹ć“ćØć«ć‚ć‚Šć¾ć™ć€‚ęœ€é«˜ć®ēŠ¶ę…‹ć‚’ē¶­ęŒć§ćć‚‹ć‚ˆć†ć«ć™ć‚‹ćŸć‚ć«ć€ć‚³ćƒ³ćƒˆćƒŖćƒ“ćƒ„ćƒ¼ć‚æćŒå¾“ć†åæ…č¦ć®ć‚ć‚‹ć„ćć¤ć‹ć®ć‚¬ć‚¤ćƒ‰ćƒ©ć‚¤ćƒ³ćŒå­˜åœØć—ć¾ć™ć€‚č©³ē“°ć«ć¤ć„ć¦ćÆć€[ćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ć‚³ćƒ³ćƒˆćƒŖćƒ“ćƒ„ćƒ¼ć‚·ćƒ§ćƒ³ć‚¬ć‚¤ćƒ‰](https://docs.puppetlabs.com/forge/contributing.html)ć‚’å‚ē…§ć—ć¦ćć ć•ć„ć€‚ + +ć“ć®ćƒ¢ć‚øćƒ„ćƒ¼ćƒ«ć®äø€éƒØć«é–¢ć™ć‚‹ćƒć‚°ć®å ±å‘Šć¾ćŸćÆčŖæęŸ»ćÆć€ +[https://github.com/puppetlabs/puppetlabs-stdlib/issues](https://github.com/puppetlabs/puppetlabs-stdlib/issues)ć‹ć‚‰ćŠé”˜ć„ć—ć¾ć™ć€‚ + +## ć‚³ćƒ³ćƒˆćƒŖćƒ“ćƒ„ćƒ¼ć‚æ + +ć‚³ćƒ³ćƒˆćƒŖćƒ“ćƒ„ćƒ¼ć‚æć®ćƒŖć‚¹ćƒˆćÆć€[https://github.com/puppetlabs/puppetlabs-stdlib/graphs/contributors](https://github.com/puppetlabs/puppetlabs-stdlib/graphs/contributors)ć§č¦‹ć‚‹ć“ćØćŒć§ćć¾ć™ć€‚ diff --git a/spec/acceptance/abs_spec.rb b/spec/acceptance/abs_spec.rb deleted file mode 100755 index 6e41e2fde..000000000 --- a/spec/acceptance/abs_spec.rb +++ /dev/null @@ -1,30 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'abs function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'should accept a string' do - pp = <<-EOS - $input = '-34.56' - $output = abs($input) - notify { "$output": } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: 34.56/) - end - end - - it 'should accept a float' do - pp = <<-EOS - $input = -34.56 - $output = abs($input) - notify { "$output": } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: 34.56/) - end - end - end -end diff --git a/spec/acceptance/anchor_spec.rb b/spec/acceptance/anchor_spec.rb old mode 100755 new mode 100644 index 5bc2bbb3b..9136b6623 --- a/spec/acceptance/anchor_spec.rb +++ b/spec/acceptance/anchor_spec.rb @@ -1,9 +1,10 @@ +# frozen_string_literal: true + require 'spec_helper_acceptance' -describe 'anchor type', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'should effect proper chaining of resources' do - pp = <<-EOS +describe 'anchor type' do + let(:pp) do + <<-MANIFEST class anchored { anchor { 'anchored::begin': } ~> anchor { 'anchored::end': } @@ -16,11 +17,12 @@ class anchorrefresh { } include anchorrefresh - EOS + MANIFEST + end - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Anchor\[final\]: Triggered 'refresh'/) - end + it 'applies manifest, anchors resources in correct order' do + apply_manifest(pp) do |r| + expect(r.stdout).to match(%r{Anchor\[final\]: Triggered 'refresh'}) end end end diff --git a/spec/acceptance/any2array_spec.rb b/spec/acceptance/any2array_spec.rb deleted file mode 100755 index 18ea4cd9b..000000000 --- a/spec/acceptance/any2array_spec.rb +++ /dev/null @@ -1,49 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'any2array function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'should create an empty array' do - pp = <<-EOS - $input = '' - $output = any2array($input) - validate_array($output) - notify { "Output: ${output}": } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: Output: /) - end - end - - it 'should leave arrays modified' do - pp = <<-EOS - $input = ['test', 'array'] - $output = any2array($input) - validate_array($output) - notify { "Output: ${output}": } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: Output: (\[|)test(,\s|)array(\]|)/) - end - end - - it 'should turn a hash into an array' do - pp = <<-EOS - $input = {'test' => 'array'} - $output = any2array($input) - - validate_array($output) - # Check each element of the array is a plain string. - validate_string($output[0]) - validate_string($output[1]) - notify { "Output: ${output}": } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: Output: (\[|)test(,\s|)array(\]|)/) - end - end - end -end diff --git a/spec/acceptance/base64_spec.rb b/spec/acceptance/base64_spec.rb deleted file mode 100755 index 97e1738ef..000000000 --- a/spec/acceptance/base64_spec.rb +++ /dev/null @@ -1,18 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'base64 function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'should encode then decode a string' do - pp = <<-EOS - $encodestring = base64('encode', 'thestring') - $decodestring = base64('decode', $encodestring) - notify { $decodestring: } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/thestring/) - end - end - end -end diff --git a/spec/acceptance/bool2num_spec.rb b/spec/acceptance/bool2num_spec.rb deleted file mode 100755 index 52ff75bcf..000000000 --- a/spec/acceptance/bool2num_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'bool2num function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - ['false', 'f', '0', 'n', 'no'].each do |bool| - it "should convert a given boolean, #{bool}, to 0" do - pp = <<-EOS - $input = "#{bool}" - $output = bool2num($input) - notify { "$output": } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: 0/) - end - end - end - - ['true', 't', '1', 'y', 'yes'].each do |bool| - it "should convert a given boolean, #{bool}, to 1" do - pp = <<-EOS - $input = "#{bool}" - $output = bool2num($input) - notify { "$output": } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: 1/) - end - end - end - end -end diff --git a/spec/acceptance/build_csv.rb b/spec/acceptance/build_csv.rb deleted file mode 100755 index 62ecbf13a..000000000 --- a/spec/acceptance/build_csv.rb +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env ruby -# vim: set sw=2 sts=2 et tw=80 : -require 'rspec' - -#XXX Super ugly hack to keep from starting beaker nodes -module Kernel - # make an alias of the original require - alias_method :original_require, :require - # rewrite require - def require name - original_require name if name != 'spec_helper_acceptance' - end -end -UNSUPPORTED_PLATFORMS = [] -def fact(*args) [] end -#XXX End hax - -# Get a list of functions for test coverage -function_list = Dir[File.join(File.dirname(__FILE__),"..","..","lib","puppet","parser","functions","*.rb")].collect do |function_rb| - File.basename(function_rb,".rb") -end - -## Configure rspec to parse tests -options = RSpec::Core::ConfigurationOptions.new(['spec/acceptance']) -configuration = RSpec::configuration -world = RSpec::world -options.parse_options -options.configure(configuration) -configuration.load_spec_files - -## Collect up tests and example groups into a hash -def get_tests(children) - children.inject({}) do |memo,c| - memo[c.description] = Hash.new - memo[c.description]["groups"] = get_tests(c.children) unless c.children.empty? - memo[c.description]["tests"] = c.examples.collect { |e| - e.description unless e.pending? - }.compact unless c.examples.empty? - memo[c.description]["pending_tests"] = c.examples.collect { |e| - e.description if e.pending? - }.compact unless c.examples.empty? - memo - end -end - -def count_test_types_in(type,group) - return 0 if group.nil? - group.inject(0) do |m,(k,v)| - m += v.length if k == type - m += count_tests_in(v) if v.is_a?(Hash) - m - end -end -def count_tests_in(group) - count_test_types_in('tests',group) -end -def count_pending_tests_in(group) - count_test_types_in('pending_tests',group) -end - -# Convert tests hash to csv format -def to_csv(function_list,tests) - function_list.collect do |function_name| - if v = tests["#{function_name} function"] - positive_tests = count_tests_in(v["groups"]["success"]) - negative_tests = count_tests_in(v["groups"]["failure"]) - pending_tests = - count_pending_tests_in(v["groups"]["failure"]) + - count_pending_tests_in(v["groups"]["failure"]) - else - positive_tests = 0 - negative_tests = 0 - pending_tests = 0 - end - sprintf("%-25s, %-9d, %-9d, %-9d", function_name,positive_tests,negative_tests,pending_tests) - end.compact -end - -tests = get_tests(world.example_groups) -csv = to_csv(function_list,tests) -percentage_tested = "#{tests.count*100/function_list.count}%" -printf("%-25s, %-9s, %-9s, %-9s\n","#{percentage_tested} have tests.","Positive","Negative","Pending") -puts csv diff --git a/spec/acceptance/capitalize_spec.rb b/spec/acceptance/capitalize_spec.rb deleted file mode 100755 index e5e7b7bf8..000000000 --- a/spec/acceptance/capitalize_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'capitalize function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'should capitalize the first letter of a string' do - pp = <<-EOS - $input = 'this is a string' - $output = capitalize($input) - notify { $output: } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: This is a string/) - end - end - - it 'should capitalize the first letter of an array of strings' do - pp = <<-EOS - $input = ['this', 'is', 'a', 'string'] - $output = capitalize($input) - notify { $output: } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: This/) - expect(r.stdout).to match(/Notice: Is/) - expect(r.stdout).to match(/Notice: A/) - expect(r.stdout).to match(/Notice: String/) - end - end - end -end diff --git a/spec/acceptance/ceiling_spec.rb b/spec/acceptance/ceiling_spec.rb deleted file mode 100755 index 557986eb8..000000000 --- a/spec/acceptance/ceiling_spec.rb +++ /dev/null @@ -1,39 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'ceiling function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'ceilings floats' do - pp = <<-EOS - $a = 12.8 - $b = 13 - $o = ceiling($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'ceilings integers' do - pp = <<-EOS - $a = 7 - $b = 7 - $o = ceiling($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - end - describe 'failure' do - it 'handles improper argument counts' - it 'handles non-numbers' - end -end diff --git a/spec/acceptance/chomp_spec.rb b/spec/acceptance/chomp_spec.rb deleted file mode 100755 index f6c15956e..000000000 --- a/spec/acceptance/chomp_spec.rb +++ /dev/null @@ -1,21 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'chomp function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'should eat the newline' do - pp = <<-EOS - $input = "test\n" - if size($input) != 5 { - fail("Size of ${input} is not 5.") - } - $output = chomp($input) - if size($output) != 4 { - fail("Size of ${input} is not 4.") - } - EOS - - apply_manifest(pp, :catch_failures => true) - end - end -end diff --git a/spec/acceptance/chop_spec.rb b/spec/acceptance/chop_spec.rb deleted file mode 100755 index a16a71026..000000000 --- a/spec/acceptance/chop_spec.rb +++ /dev/null @@ -1,45 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'chop function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'should eat the last character' do - pp = <<-EOS - $input = "test" - if size($input) != 4 { - fail("Size of ${input} is not 4.") - } - $output = chop($input) - if size($output) != 3 { - fail("Size of ${input} is not 3.") - } - EOS - - apply_manifest(pp, :catch_failures => true) - end - - it 'should eat the last two characters of \r\n' do - pp = <<-'EOS' - $input = "test\r\n" - if size($input) != 6 { - fail("Size of ${input} is not 6.") - } - $output = chop($input) - if size($output) != 4 { - fail("Size of ${input} is not 4.") - } - EOS - - apply_manifest(pp, :catch_failures => true) - end - - it 'should not fail on empty strings' do - pp = <<-EOS - $input = "" - $output = chop($input) - EOS - - apply_manifest(pp, :catch_failures => true) - end - end -end diff --git a/spec/acceptance/concat_spec.rb b/spec/acceptance/concat_spec.rb deleted file mode 100755 index 06b649f19..000000000 --- a/spec/acceptance/concat_spec.rb +++ /dev/null @@ -1,40 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'concat function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'should concat one array to another' do - pp = <<-EOS - $output = concat(['1','2','3'],['4','5','6']) - validate_array($output) - if size($output) != 6 { - fail("${output} should have 6 elements.") - } - EOS - - apply_manifest(pp, :catch_failures => true) - end - it 'should concat arrays and primitives to array' do - pp = <<-EOS - $output = concat(['1','2','3'],'4','5','6',['7','8','9']) - validate_array($output) - if size($output) != 9 { - fail("${output} should have 9 elements.") - } - EOS - - apply_manifest(pp, :catch_failures => true) - end - it 'should concat multiple arrays to one' do - pp = <<-EOS - $output = concat(['1','2','3'],['4','5','6'],['7','8','9']) - validate_array($output) - if size($output) != 9 { - fail("${output} should have 9 elements.") - } - EOS - - apply_manifest(pp, :catch_failures => true) - end - end -end diff --git a/spec/acceptance/count_spec.rb b/spec/acceptance/count_spec.rb deleted file mode 100755 index fe7ca9dcf..000000000 --- a/spec/acceptance/count_spec.rb +++ /dev/null @@ -1,30 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'count function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'should count elements in an array' do - pp = <<-EOS - $input = [1,2,3,4] - $output = count($input) - notify { "$output": } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: 4/) - end - end - - it 'should count elements in an array that match a second argument' do - pp = <<-EOS - $input = [1,1,1,2] - $output = count($input, 1) - notify { "$output": } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: 3/) - end - end - end -end diff --git a/spec/acceptance/deep_merge_spec.rb b/spec/acceptance/deep_merge_spec.rb deleted file mode 100755 index c0f9b126d..000000000 --- a/spec/acceptance/deep_merge_spec.rb +++ /dev/null @@ -1,20 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'deep_merge function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'should deep merge two hashes' do - pp = <<-EOS - $hash1 = {'one' => 1, 'two' => 2, 'three' => { 'four' => 4 } } - $hash2 = {'two' => 'dos', 'three' => { 'five' => 5 } } - $merged_hash = deep_merge($hash1, $hash2) - - if $merged_hash != { 'one' => 1, 'two' => 'dos', 'three' => { 'four' => 4, 'five' => 5 } } { - fail("Hash was incorrectly merged.") - } - EOS - - apply_manifest(pp, :catch_failures => true) - end - end -end diff --git a/spec/acceptance/defined_with_params_spec.rb b/spec/acceptance/defined_with_params_spec.rb deleted file mode 100755 index fc544508b..000000000 --- a/spec/acceptance/defined_with_params_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'defined_with_params function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'should successfully notify' do - pp = <<-EOS - user { 'dan': - ensure => present, - } - - if defined_with_params(User[dan], {'ensure' => 'present' }) { - notify { 'User defined with ensure=>present': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: User defined with ensure=>present/) - end - end - end -end diff --git a/spec/acceptance/delete_at_spec.rb b/spec/acceptance/delete_at_spec.rb deleted file mode 100755 index db0c01f74..000000000 --- a/spec/acceptance/delete_at_spec.rb +++ /dev/null @@ -1,19 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'delete_at function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'should delete elements of the array' do - pp = <<-EOS - $output = delete_at(['a','b','c','b'], 1) - if $output == ['a','c','b'] { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - end -end diff --git a/spec/acceptance/delete_spec.rb b/spec/acceptance/delete_spec.rb deleted file mode 100755 index a28604cea..000000000 --- a/spec/acceptance/delete_spec.rb +++ /dev/null @@ -1,19 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'delete function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'should delete elements of the array' do - pp = <<-EOS - $output = delete(['a','b','c','b'], 'b') - if $output == ['a','c'] { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - end -end diff --git a/spec/acceptance/delete_undef_values_spec.rb b/spec/acceptance/delete_undef_values_spec.rb deleted file mode 100755 index b7eda1926..000000000 --- a/spec/acceptance/delete_undef_values_spec.rb +++ /dev/null @@ -1,19 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'delete_undef_values function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'should delete elements of the array' do - pp = <<-EOS - $output = delete_undef_values({a=>'A', b=>'', c=>undef, d => false}) - if $output == { a => 'A', b => '', d => false } { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - end -end diff --git a/spec/acceptance/delete_values_spec.rb b/spec/acceptance/delete_values_spec.rb deleted file mode 100755 index 6d2369c3e..000000000 --- a/spec/acceptance/delete_values_spec.rb +++ /dev/null @@ -1,25 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'delete_values function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'should delete elements of the hash' do - pp = <<-EOS - $a = { 'a' => 'A', 'b' => 'B', 'B' => 'C', 'd' => 'B' } - $b = { 'a' => 'A', 'B' => 'C' } - $o = delete_values($a, 'B') - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - end - describe 'failure' do - it 'handles non-hash arguments' - it 'handles improper argument counts' - end -end diff --git a/spec/acceptance/difference_spec.rb b/spec/acceptance/difference_spec.rb deleted file mode 100755 index 2fae5c432..000000000 --- a/spec/acceptance/difference_spec.rb +++ /dev/null @@ -1,26 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'difference function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'returns non-duplicates in the first array' do - pp = <<-EOS - $a = ['a','b','c'] - $b = ['b','c','d'] - $c = ['a'] - $o = difference($a, $b) - if $o == $c { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - end - describe 'failure' do - it 'handles non-array arguments' - it 'handles improper argument counts' - end -end diff --git a/spec/acceptance/dirname_spec.rb b/spec/acceptance/dirname_spec.rb deleted file mode 100755 index 97913ddb0..000000000 --- a/spec/acceptance/dirname_spec.rb +++ /dev/null @@ -1,42 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'dirname function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - context 'absolute path' do - it 'returns the dirname' do - pp = <<-EOS - $a = '/path/to/a/file.txt' - $b = '/path/to/a' - $o = dirname($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - end - context 'relative path' do - it 'returns the dirname' do - pp = <<-EOS - $a = 'path/to/a/file.txt' - $b = 'path/to/a' - $o = dirname($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - end - end - describe 'failure' do - it 'handles improper argument counts' - end -end diff --git a/spec/acceptance/downcase_spec.rb b/spec/acceptance/downcase_spec.rb deleted file mode 100755 index bc4e70692..000000000 --- a/spec/acceptance/downcase_spec.rb +++ /dev/null @@ -1,39 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'downcase function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'returns the downcase' do - pp = <<-EOS - $a = 'AOEU' - $b = 'aoeu' - $o = downcase($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'doesn\'t affect lowercase words' do - pp = <<-EOS - $a = 'aoeu aoeu' - $b = 'aoeu aoeu' - $o = downcase($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - end - describe 'failure' do - it 'handles improper argument counts' - it 'handles non-strings' - end -end diff --git a/spec/acceptance/empty_spec.rb b/spec/acceptance/empty_spec.rb deleted file mode 100755 index 2d4df901b..000000000 --- a/spec/acceptance/empty_spec.rb +++ /dev/null @@ -1,53 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'empty function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'recognizes empty strings' do - pp = <<-EOS - $a = '' - $b = true - $o = empty($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'recognizes non-empty strings' do - pp = <<-EOS - $a = 'aoeu' - $b = false - $o = empty($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'handles numerical values' do - pp = <<-EOS - $a = 7 - $b = false - $o = empty($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - end - describe 'failure' do - it 'handles improper argument counts' - it 'handles non-strings' - end -end diff --git a/spec/acceptance/ensure_resource_spec.rb b/spec/acceptance/ensure_resource_spec.rb deleted file mode 100755 index fe619a9e5..000000000 --- a/spec/acceptance/ensure_resource_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'ensure_resource function', :unless => fact('osfamily') =~ /(windows|Suse)/i do - describe 'success' do - it 'ensure_resource a package' do - apply_manifest('package { "rake": ensure => absent, provider => "gem", }') - pp = <<-EOS - $a = "rake" - ensure_resource('package', $a, {'provider' => 'gem'}) - EOS - - apply_manifest(pp, :expect_changes => true) - end - it 'ensures a resource already declared' - it 'takes defaults arguments' - end - describe 'failure' do - it 'handles no arguments' - it 'handles non strings' - end -end diff --git a/spec/acceptance/file_line_spec.rb b/spec/acceptance/file_line_spec.rb new file mode 100644 index 000000000..6971c2eff --- /dev/null +++ b/spec/acceptance/file_line_spec.rb @@ -0,0 +1,154 @@ +# frozen_string_literal: true + +require 'spec_helper_acceptance' + +describe 'file_line type' do + let(:test_file) { (os[:family] == 'windows') ? 'C:\test\file_line_test.txt' : '/tmp/test/testfile_line_test.txt' } + + before(:all) do + apply_manifest(<<-MANIFEST) + case($facts['os']['family']) { + windows: { file { 'C:\\test': ensure => directory } } + default: { file { '/tmp/test': ensure => directory } } + } + MANIFEST + end + + before(:each) do + pp_test_file = <<-MANIFEST + file { '#{test_file}': + ensure => present, + content => 'a wild test file has appeared!', + } + file { '#{test_file}.does_not_exist': + ensure => absent, + } + MANIFEST + apply_manifest(pp_test_file) + end + + context 'ensure line' do + let(:pp) do + <<-MANIFEST + file_line { 'test_ensure': + path => '#{test_file}', + line => 'test file uses attack!', + } + MANIFEST + end + + it 'applies manifest, adds line' do + idempotent_apply(pp) + expect(file(test_file)).to be_file + expect(file(test_file).content).to match(%r{test file uses attack!}) + end + end + + context 'matches and replaces line' do + let(:pp) do + <<-MANIFEST + file_line { 'test_match': + path => '#{test_file}', + line => 'a tame test file has appeared!', + match => '^a wild', + } + MANIFEST + end + + it 'applies manifest, replaces line' do + idempotent_apply(pp) + expect(file(test_file)).to be_file + expect(file(test_file).content).to match(%r{a tame test file has appeared!}) + end + end + + context 'remove line' do + context 'using match' do + let(:pp) do + <<-MANIFEST + file_line { 'test_absent_match': + ensure => absent, + path => '#{test_file}', + match => '^a wild', + match_for_absence => true, + } + MANIFEST + end + + it 'applies manifest, removes line' do + idempotent_apply(pp) + expect(file(test_file)).to be_file + expect(file(test_file).content).to be_empty + end + end + + context 'using line' do + let(:pp) do + <<-MANIFEST + file_line { 'test_absent_line': + ensure => absent, + path => '#{test_file}', + line => 'a wild test file has appeared!', + } + MANIFEST + end + + it 'applies manifest, removes line' do + idempotent_apply(pp) + expect(file(test_file)).to be_file + expect(file(test_file).content).to be_empty + end + end + end + + context 'when file does not exist' do + context 'with ensure => present' do + let(:pp) do + <<~MANIFEST + file_line { 'test_absent_file': + ensure => present, + path => '#{test_file}.does_not_exist', + line => 'this file does not exist', + } + MANIFEST + end + + it 'fails to apply manifest' do + apply_manifest(pp, expect_failures: true) + end + end + + context 'with ensure => present and noop => true' do + let(:pp) do + <<~MANIFEST + file_line { 'test_absent_file': + ensure => present, + path => '#{test_file}.does_not_exist', + line => 'this file does not exist', + noop => true, + } + MANIFEST + end + + it 'would apply manifest' do + apply_manifest(pp, catch_failures: true) + end + end + + context 'with ensure => present, in noop mode' do + let(:pp) do + <<~MANIFEST + file_line { 'test_absent_file': + ensure => present, + path => '#{test_file}.does_not_exist', + line => 'this file does not exist', + } + MANIFEST + end + + it 'would apply manifest' do + apply_manifest(pp, catch_failures: true, noop: true) + end + end + end +end diff --git a/spec/acceptance/flatten_spec.rb b/spec/acceptance/flatten_spec.rb deleted file mode 100755 index c4d66e046..000000000 --- a/spec/acceptance/flatten_spec.rb +++ /dev/null @@ -1,39 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'flatten function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'flattens arrays' do - pp = <<-EOS - $a = ["a","b",["c",["d","e"],"f","g"]] - $b = ["a","b","c","d","e","f","g"] - $o = flatten($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'does not affect flat arrays' do - pp = <<-EOS - $a = ["a","b","c","d","e","f","g"] - $b = ["a","b","c","d","e","f","g"] - $o = flatten($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - end - describe 'failure' do - it 'handles improper argument counts' - it 'handles non-strings' - end -end diff --git a/spec/acceptance/floor_spec.rb b/spec/acceptance/floor_spec.rb deleted file mode 100755 index 0dcdad9c2..000000000 --- a/spec/acceptance/floor_spec.rb +++ /dev/null @@ -1,39 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'floor function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'floors floats' do - pp = <<-EOS - $a = 12.8 - $b = 12 - $o = floor($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'floors integers' do - pp = <<-EOS - $a = 7 - $b = 7 - $o = floor($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - end - describe 'failure' do - it 'handles improper argument counts' - it 'handles non-numbers' - end -end diff --git a/spec/acceptance/fqdn_rand_string_spec.rb b/spec/acceptance/fqdn_rand_string_spec.rb deleted file mode 100644 index 9c6d701c9..000000000 --- a/spec/acceptance/fqdn_rand_string_spec.rb +++ /dev/null @@ -1,66 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'fqdn_rand_string function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - include_context "with faked facts" - context "when the FQDN is 'fakehost.localdomain'" do - before :each do - fake_fact("fqdn", "fakehost.localdomain") - end - - it 'generates random alphanumeric strings' do - pp = <<-eos - $l = 10 - $o = fqdn_rand_string($l) - notice(inline_template('fqdn_rand_string is <%= @o.inspect %>')) - eos - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/fqdn_rand_string is "7oDp0KOr1b"/) - end - end - it 'generates random alphanumeric strings with custom charsets' do - pp = <<-eos - $l = 10 - $c = '0123456789' - $o = fqdn_rand_string($l, $c) - notice(inline_template('fqdn_rand_string is <%= @o.inspect %>')) - eos - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/fqdn_rand_string is "7203048515"/) - end - end - it 'generates random alphanumeric strings with custom seeds' do - pp = <<-eos - $l = 10 - $s = 'seed' - $o = fqdn_rand_string($l, undef, $s) - notice(inline_template('fqdn_rand_string is <%= @o.inspect %>')) - eos - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/fqdn_rand_string is "3HS4mbuI3E"/) - end - end - it 'generates random alphanumeric strings with custom charsets and seeds' do - pp = <<-eos - $l = 10 - $c = '0123456789' - $s = 'seed' - $o = fqdn_rand_string($l, $c, $s) - notice(inline_template('fqdn_rand_string is <%= @o.inspect %>')) - eos - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/fqdn_rand_string is "3104058232"/) - end - end - end - end - describe 'failure' do - it 'handles improper argument counts' - it 'handles non-numbers for length argument' - end -end diff --git a/spec/acceptance/fqdn_rotate_spec.rb b/spec/acceptance/fqdn_rotate_spec.rb deleted file mode 100755 index 404351f6f..000000000 --- a/spec/acceptance/fqdn_rotate_spec.rb +++ /dev/null @@ -1,64 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'fqdn_rotate function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - include_context "with faked facts" - context "when the FQDN is 'fakehost.localdomain'" do - before :each do - fake_fact("fqdn", "fakehost.localdomain") - end - - it 'rotates arrays' do - pp = <<-EOS - $a = ['a','b','c','d'] - $o = fqdn_rotate($a) - notice(inline_template('fqdn_rotate is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/fqdn_rotate is \["d", "a", "b", "c"\]/) - end - end - it 'rotates arrays with custom seeds' do - pp = <<-EOS - $a = ['a','b','c','d'] - $s = 'seed' - $o = fqdn_rotate($a, $s) - notice(inline_template('fqdn_rotate is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/fqdn_rotate is \["c", "d", "a", "b"\]/) - end - end - it 'rotates strings' do - pp = <<-EOS - $a = 'abcd' - $o = fqdn_rotate($a) - notice(inline_template('fqdn_rotate is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/fqdn_rotate is "dabc"/) - end - end - it 'rotates strings with custom seeds' do - pp = <<-EOS - $a = 'abcd' - $s = 'seed' - $o = fqdn_rotate($a, $s) - notice(inline_template('fqdn_rotate is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/fqdn_rotate is "cdab"/) - end - end - end - end - describe 'failure' do - it 'handles improper argument counts' - it 'handles invalid arguments' - end -end diff --git a/spec/acceptance/get_module_path_spec.rb b/spec/acceptance/get_module_path_spec.rb deleted file mode 100755 index 6ac690c16..000000000 --- a/spec/acceptance/get_module_path_spec.rb +++ /dev/null @@ -1,27 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'get_module_path function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'get_module_paths dne' do - pp = <<-EOS - $a = $::is_pe ? { - 'true' => '/etc/puppetlabs/puppet/modules/dne', - 'false' => '/etc/puppet/modules/dne', - } - $o = get_module_path('dne') - if $o == $a { - notify { 'output correct': } - } else { - notify { "failed; module path is '$o'": } - } - EOS - - apply_manifest(pp, :expect_failures => true) - end - end - describe 'failure' do - it 'handles improper argument counts' - it 'handles non-numbers' - end -end diff --git a/spec/acceptance/getparam_spec.rb b/spec/acceptance/getparam_spec.rb deleted file mode 100755 index b1a677eca..000000000 --- a/spec/acceptance/getparam_spec.rb +++ /dev/null @@ -1,24 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'getparam function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'getparam a notify' do - pp = <<-EOS - notify { 'rspec': - message => 'custom rspec message', - } - $o = getparam(Notify['rspec'], 'message') - notice(inline_template('getparam is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/getparam is "custom rspec message"/) - end - end - end - describe 'failure' do - it 'handles no arguments' - it 'handles non strings' - end -end diff --git a/spec/acceptance/getvar_spec.rb b/spec/acceptance/getvar_spec.rb deleted file mode 100755 index 333c467f6..000000000 --- a/spec/acceptance/getvar_spec.rb +++ /dev/null @@ -1,26 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'getvar function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'getvars from classes' do - pp = <<-EOS - class a::data { $foo = 'aoeu' } - include a::data - $b = 'aoeu' - $o = getvar("a::data::foo") - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - end - describe 'failure' do - it 'handles improper argument counts' - it 'handles non-numbers' - end -end diff --git a/spec/acceptance/grep_spec.rb b/spec/acceptance/grep_spec.rb deleted file mode 100755 index b39d48ecb..000000000 --- a/spec/acceptance/grep_spec.rb +++ /dev/null @@ -1,26 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'grep function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'greps arrays' do - pp = <<-EOS - $a = ['aaabbb','bbbccc','dddeee'] - $b = 'bbb' - $c = ['aaabbb','bbbccc'] - $o = grep($a,$b) - if $o == $c { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - end - describe 'failure' do - it 'handles improper argument counts' - it 'handles non-arrays' - end -end diff --git a/spec/acceptance/has_interface_with_spec.rb b/spec/acceptance/has_interface_with_spec.rb deleted file mode 100755 index 959019304..000000000 --- a/spec/acceptance/has_interface_with_spec.rb +++ /dev/null @@ -1,54 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'has_interface_with function', :unless => ((UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem'))) or (fact('osfamily') == 'windows') or (fact('osfamily') == 'AIX')) do - describe 'success' do - it 'has_interface_with existing ipaddress' do - pp = <<-EOS - $a = $::ipaddress - $o = has_interface_with('ipaddress', $a) - notice(inline_template('has_interface_with is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/has_interface_with is true/) - end - end - it 'has_interface_with absent ipaddress' do - pp = <<-EOS - $a = '128.0.0.1' - $o = has_interface_with('ipaddress', $a) - notice(inline_template('has_interface_with is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/has_interface_with is false/) - end - end - it 'has_interface_with existing interface' do - pp = <<-EOS - if $osfamily == 'Solaris' or $osfamily == 'Darwin' { - $a = 'lo0' - }elsif $osfamily == 'windows' { - $a = $::kernelmajversion ? { - /6\.(2|3|4)/ => 'Ethernet0', - /6\.(0|1)/ => 'Local_Area_Connection', - /5\.(1|2)/ => undef, #Broken current in facter - } - }else { - $a = 'lo' - } - $o = has_interface_with($a) - notice(inline_template('has_interface_with is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/has_interface_with is true/) - end - end - end - describe 'failure' do - it 'handles no arguments' - it 'handles non strings' - end -end diff --git a/spec/acceptance/has_ip_address_spec.rb b/spec/acceptance/has_ip_address_spec.rb deleted file mode 100755 index 149a10dc9..000000000 --- a/spec/acceptance/has_ip_address_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'has_ip_address function', :unless => ((UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem'))) or (fact('osfamily') == 'windows') or (fact('osfamily') == 'AIX')) do - describe 'success' do - it 'has_ip_address existing ipaddress' do - pp = <<-EOS - $a = '127.0.0.1' - $o = has_ip_address($a) - notice(inline_template('has_ip_address is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/has_ip_address is true/) - end - end - it 'has_ip_address absent ipaddress' do - pp = <<-EOS - $a = '128.0.0.1' - $o = has_ip_address($a) - notice(inline_template('has_ip_address is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/has_ip_address is false/) - end - end - end - describe 'failure' do - it 'handles no arguments' - it 'handles non strings' - end -end diff --git a/spec/acceptance/has_ip_network_spec.rb b/spec/acceptance/has_ip_network_spec.rb deleted file mode 100755 index 7d2f34ed5..000000000 --- a/spec/acceptance/has_ip_network_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'has_ip_network function', :unless => ((UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem'))) or (fact('osfamily') == 'windows') or (fact('osfamily') == 'AIX')) do - describe 'success' do - it 'has_ip_network existing ipaddress' do - pp = <<-EOS - $a = '127.0.0.0' - $o = has_ip_network($a) - notice(inline_template('has_ip_network is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/has_ip_network is true/) - end - end - it 'has_ip_network absent ipaddress' do - pp = <<-EOS - $a = '128.0.0.0' - $o = has_ip_network($a) - notice(inline_template('has_ip_network is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/has_ip_network is false/) - end - end - end - describe 'failure' do - it 'handles no arguments' - it 'handles non strings' - end -end diff --git a/spec/acceptance/has_key_spec.rb b/spec/acceptance/has_key_spec.rb deleted file mode 100755 index c8557cbeb..000000000 --- a/spec/acceptance/has_key_spec.rb +++ /dev/null @@ -1,41 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'has_key function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'has_keys in hashes' do - pp = <<-EOS - $a = { 'aaa' => 'bbb','bbb' => 'ccc','ddd' => 'eee' } - $b = 'bbb' - $c = true - $o = has_key($a,$b) - if $o == $c { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'has_keys not in hashes' do - pp = <<-EOS - $a = { 'aaa' => 'bbb','bbb' => 'ccc','ddd' => 'eee' } - $b = 'ccc' - $c = false - $o = has_key($a,$b) - if $o == $c { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - end - describe 'failure' do - it 'handles improper argument counts' - it 'handles non-hashes' - end -end diff --git a/spec/acceptance/hash_spec.rb b/spec/acceptance/hash_spec.rb deleted file mode 100755 index ed53834be..000000000 --- a/spec/acceptance/hash_spec.rb +++ /dev/null @@ -1,26 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'hash function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'hashs arrays' do - pp = <<-EOS - $a = ['aaa','bbb','bbb','ccc','ddd','eee'] - $b = { 'aaa' => 'bbb', 'bbb' => 'ccc', 'ddd' => 'eee' } - $o = hash($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'handles odd-length arrays' - end - describe 'failure' do - it 'handles improper argument counts' - it 'handles non-arrays' - end -end diff --git a/spec/acceptance/intersection_spec.rb b/spec/acceptance/intersection_spec.rb deleted file mode 100755 index 66b865297..000000000 --- a/spec/acceptance/intersection_spec.rb +++ /dev/null @@ -1,27 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'intersection function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'intersections arrays' do - pp = <<-EOS - $a = ['aaa','bbb','ccc'] - $b = ['bbb','ccc','ddd','eee'] - $c = ['bbb','ccc'] - $o = intersection($a,$b) - if $o == $c { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'intersections empty arrays' - end - describe 'failure' do - it 'handles improper argument counts' - it 'handles non-arrays' - end -end diff --git a/spec/acceptance/is_a_spec.rb b/spec/acceptance/is_a_spec.rb deleted file mode 100644 index 355fd8379..000000000 --- a/spec/acceptance/is_a_spec.rb +++ /dev/null @@ -1,30 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -if get_puppet_version =~ /^4/ - describe 'is_a function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - it 'should match a string' do - pp = <<-EOS - if 'hello world'.is_a(String) { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - - it 'should not match a integer as string' do - pp = <<-EOS - if 5.is_a(String) { - notify { 'output wrong': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).not_to match(/Notice: output wrong/) - end - end - end -end diff --git a/spec/acceptance/is_array_spec.rb b/spec/acceptance/is_array_spec.rb deleted file mode 100755 index 9c6bad735..000000000 --- a/spec/acceptance/is_array_spec.rb +++ /dev/null @@ -1,67 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'is_array function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'is_arrays arrays' do - pp = <<-EOS - $a = ['aaa','bbb','ccc'] - $b = true - $o = is_array($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_arrays empty arrays' do - pp = <<-EOS - $a = [] - $b = true - $o = is_array($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_arrays strings' do - pp = <<-EOS - $a = "aoeu" - $b = false - $o = is_array($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_arrays hashes' do - pp = <<-EOS - $a = {'aaa'=>'bbb'} - $b = false - $o = is_array($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - end - describe 'failure' do - it 'handles improper argument counts' - it 'handles non-arrays' - end -end diff --git a/spec/acceptance/is_bool_spec.rb b/spec/acceptance/is_bool_spec.rb deleted file mode 100755 index 60079f95e..000000000 --- a/spec/acceptance/is_bool_spec.rb +++ /dev/null @@ -1,81 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'is_bool function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'is_bools arrays' do - pp = <<-EOS - $a = ['aaa','bbb','ccc'] - $b = false - $o = is_bool($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_bools true' do - pp = <<-EOS - $a = true - $b = true - $o = is_bool($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_bools false' do - pp = <<-EOS - $a = false - $b = true - $o = is_bool($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_bools strings' do - pp = <<-EOS - $a = "true" - $b = false - $o = is_bool($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_bools hashes' do - pp = <<-EOS - $a = {'aaa'=>'bbb'} - $b = false - $o = is_bool($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - end - describe 'failure' do - it 'handles improper argument counts' - it 'handles non-arrays' - end -end diff --git a/spec/acceptance/is_domain_name_spec.rb b/spec/acceptance/is_domain_name_spec.rb deleted file mode 100755 index e0f03fa87..000000000 --- a/spec/acceptance/is_domain_name_spec.rb +++ /dev/null @@ -1,83 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'is_domain_name function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'is_domain_names arrays' do - pp = <<-EOS - $a = ['aaa.com','bbb','ccc'] - $o = is_domain_name($a) - notice(inline_template('is_domain_name is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/is_domain_name is false/) - end - end - it 'is_domain_names true' do - pp = <<-EOS - $a = true - $o = is_domain_name($a) - notice(inline_template('is_domain_name is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/is_domain_name is false/) - end - end - it 'is_domain_names false' do - pp = <<-EOS - $a = false - $o = is_domain_name($a) - notice(inline_template('is_domain_name is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/is_domain_name is false/) - end - end - it 'is_domain_names strings with hyphens' do - pp = <<-EOS - $a = "3foo-bar.2bar-fuzz.com" - $b = true - $o = is_domain_name($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_domain_names strings beginning with hyphens' do - pp = <<-EOS - $a = "-bar.2bar-fuzz.com" - $b = false - $o = is_domain_name($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_domain_names hashes' do - pp = <<-EOS - $a = {'aaa'=>'www.com'} - $o = is_domain_name($a) - notice(inline_template('is_domain_name is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/is_domain_name is false/) - end - end - end - describe 'failure' do - it 'handles improper argument counts' - it 'handles non-arrays' - end -end diff --git a/spec/acceptance/is_float_spec.rb b/spec/acceptance/is_float_spec.rb deleted file mode 100755 index 338ba58d4..000000000 --- a/spec/acceptance/is_float_spec.rb +++ /dev/null @@ -1,86 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'is_float function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'is_floats arrays' do - pp = <<-EOS - $a = ['aaa.com','bbb','ccc'] - $o = is_float($a) - notice(inline_template('is_float is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/is_float is false/) - end - end - it 'is_floats true' do - pp = <<-EOS - $a = true - $o = is_float($a) - notice(inline_template('is_float is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/is_float is false/) - end - end - it 'is_floats strings' do - pp = <<-EOS - $a = "3.5" - $b = true - $o = is_float($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_floats floats' do - pp = <<-EOS - $a = 3.5 - $b = true - $o = is_float($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_floats integers' do - pp = <<-EOS - $a = 3 - $b = false - $o = is_float($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_floats hashes' do - pp = <<-EOS - $a = {'aaa'=>'www.com'} - $o = is_float($a) - notice(inline_template('is_float is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/is_float is false/) - end - end - end - describe 'failure' do - it 'handles improper argument counts' - it 'handles non-arrays' - end -end diff --git a/spec/acceptance/is_function_available_spec.rb b/spec/acceptance/is_function_available_spec.rb deleted file mode 100755 index 2b5dd6d17..000000000 --- a/spec/acceptance/is_function_available_spec.rb +++ /dev/null @@ -1,58 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'is_function_available function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'is_function_availables arrays' do - pp = <<-EOS - $a = ['fail','include','require'] - $o = is_function_available($a) - notice(inline_template('is_function_available is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/is_function_available is false/) - end - end - it 'is_function_availables true' do - pp = <<-EOS - $a = true - $o = is_function_available($a) - notice(inline_template('is_function_available is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/is_function_available is false/) - end - end - it 'is_function_availables strings' do - pp = <<-EOS - $a = "fail" - $b = true - $o = is_function_available($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_function_availables function_availables' do - pp = <<-EOS - $a = "is_function_available" - $o = is_function_available($a) - notice(inline_template('is_function_available is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/is_function_available is true/) - end - end - end - describe 'failure' do - it 'handles improper argument counts' - it 'handles non-arrays' - end -end diff --git a/spec/acceptance/is_hash_spec.rb b/spec/acceptance/is_hash_spec.rb deleted file mode 100755 index 2ef310abc..000000000 --- a/spec/acceptance/is_hash_spec.rb +++ /dev/null @@ -1,63 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'is_hash function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'is_hashs arrays' do - pp = <<-EOS - $a = ['aaa','bbb','ccc'] - $o = is_hash($a) - notice(inline_template('is_hash is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/is_hash is false/) - end - end - it 'is_hashs empty hashs' do - pp = <<-EOS - $a = {} - $b = true - $o = is_hash($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_hashs strings' do - pp = <<-EOS - $a = "aoeu" - $b = false - $o = is_hash($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_hashs hashes' do - pp = <<-EOS - $a = {'aaa'=>'bbb'} - $b = true - $o = is_hash($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - end - describe 'failure' do - it 'handles improper argument counts' - end -end diff --git a/spec/acceptance/is_integer_spec.rb b/spec/acceptance/is_integer_spec.rb deleted file mode 100755 index bf6902b90..000000000 --- a/spec/acceptance/is_integer_spec.rb +++ /dev/null @@ -1,95 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'is_integer function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'is_integers arrays' do - pp = <<-EOS - $a = ['aaa.com','bbb','ccc'] - $b = false - $o = is_integer($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_integers true' do - pp = <<-EOS - $a = true - $b = false - $o = is_integer($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_integers strings' do - pp = <<-EOS - $a = "3" - $b = true - $o = is_integer($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_integers floats' do - pp = <<-EOS - $a = 3.5 - $b = false - $o = is_integer($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_integers integers' do - pp = <<-EOS - $a = 3 - $b = true - $o = is_integer($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_integers hashes' do - pp = <<-EOS - $a = {'aaa'=>'www.com'} - $b = false - $o = is_integer($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - end - describe 'failure' do - it 'handles improper argument counts' - it 'handles non-arrays' - end -end diff --git a/spec/acceptance/is_ip_address_spec.rb b/spec/acceptance/is_ip_address_spec.rb deleted file mode 100755 index ed7a85439..000000000 --- a/spec/acceptance/is_ip_address_spec.rb +++ /dev/null @@ -1,80 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'is_ip_address function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'is_ip_addresss ipv4' do - pp = <<-EOS - $a = '1.2.3.4' - $b = true - $o = is_ip_address($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_ip_addresss ipv6' do - pp = <<-EOS - $a = "fe80:0000:cd12:d123:e2f8:47ff:fe09:dd74" - $b = true - $o = is_ip_address($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_ip_addresss ipv6 compressed' do - pp = <<-EOS - $a = "fe00::1" - $b = true - $o = is_ip_address($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_ip_addresss strings' do - pp = <<-EOS - $a = "aoeu" - $b = false - $o = is_ip_address($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_ip_addresss ipv4 out of range' do - pp = <<-EOS - $a = '1.2.3.400' - $b = false - $o = is_ip_address($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - end - describe 'failure' do - it 'handles improper argument counts' - end -end diff --git a/spec/acceptance/is_mac_address_spec.rb b/spec/acceptance/is_mac_address_spec.rb deleted file mode 100755 index a2c892f43..000000000 --- a/spec/acceptance/is_mac_address_spec.rb +++ /dev/null @@ -1,38 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'is_mac_address function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'is_mac_addresss a mac' do - pp = <<-EOS - $a = '00:a0:1f:12:7f:a0' - $b = true - $o = is_mac_address($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_mac_addresss a mac out of range' do - pp = <<-EOS - $a = '00:a0:1f:12:7f:g0' - $b = false - $o = is_mac_address($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - end - describe 'failure' do - it 'handles improper argument counts' - end -end diff --git a/spec/acceptance/is_numeric_spec.rb b/spec/acceptance/is_numeric_spec.rb deleted file mode 100755 index 21c898841..000000000 --- a/spec/acceptance/is_numeric_spec.rb +++ /dev/null @@ -1,95 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'is_numeric function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'is_numerics arrays' do - pp = <<-EOS - $a = ['aaa.com','bbb','ccc'] - $b = false - $o = is_numeric($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_numerics true' do - pp = <<-EOS - $a = true - $b = false - $o = is_numeric($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_numerics strings' do - pp = <<-EOS - $a = "3" - $b = true - $o = is_numeric($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_numerics floats' do - pp = <<-EOS - $a = 3.5 - $b = true - $o = is_numeric($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_numerics integers' do - pp = <<-EOS - $a = 3 - $b = true - $o = is_numeric($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_numerics hashes' do - pp = <<-EOS - $a = {'aaa'=>'www.com'} - $b = false - $o = is_numeric($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - end - describe 'failure' do - it 'handles improper argument counts' - it 'handles non-arrays' - end -end diff --git a/spec/acceptance/is_string_spec.rb b/spec/acceptance/is_string_spec.rb deleted file mode 100755 index 94d8e9678..000000000 --- a/spec/acceptance/is_string_spec.rb +++ /dev/null @@ -1,102 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'is_string function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'is_strings arrays' do - pp = <<-EOS - $a = ['aaa.com','bbb','ccc'] - $b = false - $o = is_string($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_strings true' do - pp = <<-EOS - $a = true - $b = false - $o = is_string($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_strings strings' do - pp = <<-EOS - $a = "aoeu" - $o = is_string($a) - notice(inline_template('is_string is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/is_string is true/) - end - end - it 'is_strings number strings' do - pp = <<-EOS - $a = "3" - $o = is_string($a) - notice(inline_template('is_string is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/is_string is false/) - end - end - it 'is_strings floats' do - pp = <<-EOS - $a = 3.5 - $b = false - $o = is_string($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_strings integers' do - pp = <<-EOS - $a = 3 - $b = false - $o = is_string($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'is_strings hashes' do - pp = <<-EOS - $a = {'aaa'=>'www.com'} - $b = false - $o = is_string($a) - if $o == $b { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - end - describe 'failure' do - it 'handles improper argument counts' - end -end diff --git a/spec/acceptance/join_keys_to_values_spec.rb b/spec/acceptance/join_keys_to_values_spec.rb deleted file mode 100755 index 70493fd5a..000000000 --- a/spec/acceptance/join_keys_to_values_spec.rb +++ /dev/null @@ -1,24 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'join_keys_to_values function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'join_keys_to_valuess hashes' do - pp = <<-EOS - $a = {'aaa'=>'bbb','ccc'=>'ddd'} - $b = ':' - $o = join_keys_to_values($a,$b) - notice(inline_template('join_keys_to_values is <%= @o.sort.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/join_keys_to_values is \["aaa:bbb", "ccc:ddd"\]/) - end - end - it 'handles non hashes' - it 'handles empty hashes' - end - describe 'failure' do - it 'handles improper argument counts' - end -end diff --git a/spec/acceptance/join_spec.rb b/spec/acceptance/join_spec.rb deleted file mode 100755 index 5397ce2c8..000000000 --- a/spec/acceptance/join_spec.rb +++ /dev/null @@ -1,26 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'join function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'joins arrays' do - pp = <<-EOS - $a = ['aaa','bbb','ccc'] - $b = ':' - $c = 'aaa:bbb:ccc' - $o = join($a,$b) - if $o == $c { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - it 'handles non arrays' - end - describe 'failure' do - it 'handles improper argument counts' - end -end diff --git a/spec/acceptance/keys_spec.rb b/spec/acceptance/keys_spec.rb deleted file mode 100755 index 176918e91..000000000 --- a/spec/acceptance/keys_spec.rb +++ /dev/null @@ -1,23 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'keys function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'keyss hashes' do - pp = <<-EOS - $a = {'aaa'=>'bbb','ccc'=>'ddd'} - $o = keys($a) - notice(inline_template('keys is <%= @o.sort.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/keys is \["aaa", "ccc"\]/) - end - end - it 'handles non hashes' - it 'handles empty hashes' - end - describe 'failure' do - it 'handles improper argument counts' - end -end diff --git a/spec/acceptance/loadyaml_spec.rb b/spec/acceptance/loadyaml_spec.rb deleted file mode 100644 index 1e910a978..000000000 --- a/spec/acceptance/loadyaml_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -tmpdir = default.tmpdir('stdlib') - -describe 'loadyaml function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'loadyamls array of values' do - shell("echo '--- - aaa: 1 - bbb: 2 - ccc: 3 - ddd: 4' > #{tmpdir}/testyaml.yaml") - pp = <<-EOS - $o = loadyaml('#{tmpdir}/testyaml.yaml') - notice(inline_template('loadyaml[aaa] is <%= @o["aaa"].inspect %>')) - notice(inline_template('loadyaml[bbb] is <%= @o["bbb"].inspect %>')) - notice(inline_template('loadyaml[ccc] is <%= @o["ccc"].inspect %>')) - notice(inline_template('loadyaml[ddd] is <%= @o["ddd"].inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/loadyaml\[aaa\] is 1/) - expect(r.stdout).to match(/loadyaml\[bbb\] is 2/) - expect(r.stdout).to match(/loadyaml\[ccc\] is 3/) - expect(r.stdout).to match(/loadyaml\[ddd\] is 4/) - end - end - end - describe 'failure' do - it 'fails with no arguments' - end -end diff --git a/spec/acceptance/lstrip_spec.rb b/spec/acceptance/lstrip_spec.rb deleted file mode 100755 index 3dc952fbc..000000000 --- a/spec/acceptance/lstrip_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'lstrip function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'lstrips arrays' do - pp = <<-EOS - $a = [" the "," public "," art","galleries "] - # Anagram: Large picture halls, I bet - $o = lstrip($a) - notice(inline_template('lstrip is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/lstrip is \["the ", "public ", "art", "galleries "\]/) - end - end - it 'lstrips strings' do - pp = <<-EOS - $a = " blowzy night-frumps vex'd jack q " - $o = lstrip($a) - notice(inline_template('lstrip is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/lstrip is "blowzy night-frumps vex'd jack q "/) - end - end - end - describe 'failure' do - it 'handles no arguments' - it 'handles non strings or arrays' - end -end diff --git a/spec/acceptance/max_spec.rb b/spec/acceptance/max_spec.rb deleted file mode 100755 index f04e3d283..000000000 --- a/spec/acceptance/max_spec.rb +++ /dev/null @@ -1,20 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'max function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'maxs arrays' do - pp = <<-EOS - $o = max("the","public","art","galleries") - notice(inline_template('max is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/max is "the"/) - end - end - end - describe 'failure' do - it 'handles no arguments' - end -end diff --git a/spec/acceptance/member_spec.rb b/spec/acceptance/member_spec.rb deleted file mode 100755 index fe75a0782..000000000 --- a/spec/acceptance/member_spec.rb +++ /dev/null @@ -1,54 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'member function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - shared_examples 'item found' do - it 'should output correctly' do - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - end - describe 'success' do - it 'members arrays' do - pp = <<-EOS - $a = ['aaa','bbb','ccc'] - $b = 'ccc' - $c = true - $o = member($a,$b) - if $o == $c { - notify { 'output correct': } - } - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/Notice: output correct/) - end - end - describe 'members array of integers' do - it_should_behave_like 'item found' do - let(:pp) { <<-EOS - if member( [1,2,3,4], 4 ){ - notify { 'output correct': } - } - EOS - } - end - end - describe 'members of mixed array' do - it_should_behave_like 'item found' do - let(:pp) { <<-EOS - if member( ['a','4',3], 'a' ){ - notify { 'output correct': } -} - EOS - } - end - end - it 'members arrays without members' - end - - describe 'failure' do - it 'handles improper argument counts' - end -end diff --git a/spec/acceptance/merge_spec.rb b/spec/acceptance/merge_spec.rb deleted file mode 100755 index 227b99429..000000000 --- a/spec/acceptance/merge_spec.rb +++ /dev/null @@ -1,23 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'merge function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'should merge two hashes' do - pp = <<-EOS - $a = {'one' => 1, 'two' => 2, 'three' => { 'four' => 4 } } - $b = {'two' => 'dos', 'three' => { 'five' => 5 } } - $o = merge($a, $b) - notice(inline_template('merge[one] is <%= @o["one"].inspect %>')) - notice(inline_template('merge[two] is <%= @o["two"].inspect %>')) - notice(inline_template('merge[three] is <%= @o["three"].inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/merge\[one\] is ("1"|1)/) - expect(r.stdout).to match(/merge\[two\] is "dos"/) - expect(r.stdout).to match(/merge\[three\] is {"five"=>("5"|5)}/) - end - end - end -end diff --git a/spec/acceptance/min_spec.rb b/spec/acceptance/min_spec.rb deleted file mode 100755 index 509092d3c..000000000 --- a/spec/acceptance/min_spec.rb +++ /dev/null @@ -1,20 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'min function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'mins arrays' do - pp = <<-EOS - $o = min("the","public","art","galleries") - notice(inline_template('min is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/min is "art"/) - end - end - end - describe 'failure' do - it 'handles no arguments' - end -end diff --git a/spec/acceptance/nodesets/centos-59-x64.yml b/spec/acceptance/nodesets/centos-59-x64.yml deleted file mode 100644 index 2ad90b86a..000000000 --- a/spec/acceptance/nodesets/centos-59-x64.yml +++ /dev/null @@ -1,10 +0,0 @@ -HOSTS: - centos-59-x64: - roles: - - master - platform: el-5-x86_64 - box : centos-59-x64-vbox4210-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-59-x64-vbox4210-nocm.box - hypervisor : vagrant -CONFIG: - type: git diff --git a/spec/acceptance/nodesets/centos-6-vcloud.yml b/spec/acceptance/nodesets/centos-6-vcloud.yml deleted file mode 100644 index ca9c1d329..000000000 --- a/spec/acceptance/nodesets/centos-6-vcloud.yml +++ /dev/null @@ -1,15 +0,0 @@ -HOSTS: - 'centos-6-vcloud': - roles: - - master - platform: el-6-x86_64 - hypervisor: vcloud - template: centos-6-x86_64 -CONFIG: - type: foss - ssh: - keys: "~/.ssh/id_rsa-acceptance" - datastore: instance0 - folder: Delivery/Quality Assurance/Enterprise/Dynamic - resourcepool: delivery/Quality Assurance/Enterprise/Dynamic - pooling_api: http://vcloud.delivery.puppetlabs.net/ diff --git a/spec/acceptance/nodesets/centos-64-x64-pe.yml b/spec/acceptance/nodesets/centos-64-x64-pe.yml deleted file mode 100644 index 7d9242f1b..000000000 --- a/spec/acceptance/nodesets/centos-64-x64-pe.yml +++ /dev/null @@ -1,12 +0,0 @@ -HOSTS: - centos-64-x64: - roles: - - master - - database - - dashboard - platform: el-6-x86_64 - box : centos-64-x64-vbox4210-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210-nocm.box - hypervisor : vagrant -CONFIG: - type: pe diff --git a/spec/acceptance/nodesets/centos-64-x64.yml b/spec/acceptance/nodesets/centos-64-x64.yml deleted file mode 100644 index 05540ed8c..000000000 --- a/spec/acceptance/nodesets/centos-64-x64.yml +++ /dev/null @@ -1,10 +0,0 @@ -HOSTS: - centos-64-x64: - roles: - - master - platform: el-6-x86_64 - box : centos-64-x64-vbox4210-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210-nocm.box - hypervisor : vagrant -CONFIG: - type: foss diff --git a/spec/acceptance/nodesets/centos-65-x64.yml b/spec/acceptance/nodesets/centos-65-x64.yml deleted file mode 100644 index 4e2cb809e..000000000 --- a/spec/acceptance/nodesets/centos-65-x64.yml +++ /dev/null @@ -1,10 +0,0 @@ -HOSTS: - centos-65-x64: - roles: - - master - platform: el-6-x86_64 - box : centos-65-x64-vbox436-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-65-x64-virtualbox-nocm.box - hypervisor : vagrant -CONFIG: - type: foss diff --git a/spec/acceptance/nodesets/default.yml b/spec/acceptance/nodesets/default.yml deleted file mode 100644 index 4e2cb809e..000000000 --- a/spec/acceptance/nodesets/default.yml +++ /dev/null @@ -1,10 +0,0 @@ -HOSTS: - centos-65-x64: - roles: - - master - platform: el-6-x86_64 - box : centos-65-x64-vbox436-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-65-x64-virtualbox-nocm.box - hypervisor : vagrant -CONFIG: - type: foss diff --git a/spec/acceptance/nodesets/fedora-18-x64.yml b/spec/acceptance/nodesets/fedora-18-x64.yml deleted file mode 100644 index 136164983..000000000 --- a/spec/acceptance/nodesets/fedora-18-x64.yml +++ /dev/null @@ -1,10 +0,0 @@ -HOSTS: - fedora-18-x64: - roles: - - master - platform: fedora-18-x86_64 - box : fedora-18-x64-vbox4210-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/fedora-18-x64-vbox4210-nocm.box - hypervisor : vagrant -CONFIG: - type: foss diff --git a/spec/acceptance/nodesets/sles-11-x64.yml b/spec/acceptance/nodesets/sles-11-x64.yml deleted file mode 100644 index 41abe2135..000000000 --- a/spec/acceptance/nodesets/sles-11-x64.yml +++ /dev/null @@ -1,10 +0,0 @@ -HOSTS: - sles-11-x64.local: - roles: - - master - platform: sles-11-x64 - box : sles-11sp1-x64-vbox4210-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/sles-11sp1-x64-vbox4210-nocm.box - hypervisor : vagrant -CONFIG: - type: foss diff --git a/spec/acceptance/nodesets/ubuntu-server-10044-x64.yml b/spec/acceptance/nodesets/ubuntu-server-10044-x64.yml deleted file mode 100644 index 5ca1514e4..000000000 --- a/spec/acceptance/nodesets/ubuntu-server-10044-x64.yml +++ /dev/null @@ -1,10 +0,0 @@ -HOSTS: - ubuntu-server-10044-x64: - roles: - - master - platform: ubuntu-10.04-amd64 - box : ubuntu-server-10044-x64-vbox4210-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/ubuntu-server-10044-x64-vbox4210-nocm.box - hypervisor : vagrant -CONFIG: - type: foss diff --git a/spec/acceptance/nodesets/ubuntu-server-12042-x64.yml b/spec/acceptance/nodesets/ubuntu-server-12042-x64.yml deleted file mode 100644 index d065b304f..000000000 --- a/spec/acceptance/nodesets/ubuntu-server-12042-x64.yml +++ /dev/null @@ -1,10 +0,0 @@ -HOSTS: - ubuntu-server-12042-x64: - roles: - - master - platform: ubuntu-12.04-amd64 - box : ubuntu-server-12042-x64-vbox4210-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/ubuntu-server-12042-x64-vbox4210-nocm.box - hypervisor : vagrant -CONFIG: - type: foss diff --git a/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml b/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml deleted file mode 100644 index cba1cd04c..000000000 --- a/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml +++ /dev/null @@ -1,11 +0,0 @@ -HOSTS: - ubuntu-server-1404-x64: - roles: - - master - platform: ubuntu-14.04-amd64 - box : puppetlabs/ubuntu-14.04-64-nocm - box_url : https://vagrantcloud.com/puppetlabs/ubuntu-14.04-64-nocm - hypervisor : vagrant -CONFIG: - log_level : debug - type: git diff --git a/spec/acceptance/nodesets/windows-2003-i386.yml b/spec/acceptance/nodesets/windows-2003-i386.yml deleted file mode 100644 index 47dadbd52..000000000 --- a/spec/acceptance/nodesets/windows-2003-i386.yml +++ /dev/null @@ -1,26 +0,0 @@ -HOSTS: - ubuntu1204: - roles: - - master - - database - - dashboard - platform: ubuntu-12.04-amd64 - template: ubuntu-1204-x86_64 - hypervisor: vcloud - win2003_i386: - roles: - - agent - - default - platform: windows-2003-i386 - template: win-2003-i386 - hypervisor: vcloud -CONFIG: - nfs_server: none - ssh: - keys: "~/.ssh/id_rsa-acceptance" - consoleport: 443 - datastore: instance0 - folder: Delivery/Quality Assurance/Enterprise/Dynamic - resourcepool: delivery/Quality Assurance/Enterprise/Dynamic - pooling_api: http://vcloud.delivery.puppetlabs.net/ - pe_dir: http://neptune.puppetlabs.lan/3.2/ci-ready/ diff --git a/spec/acceptance/nodesets/windows-2003-x86_64.yml b/spec/acceptance/nodesets/windows-2003-x86_64.yml deleted file mode 100644 index 6a884bc9f..000000000 --- a/spec/acceptance/nodesets/windows-2003-x86_64.yml +++ /dev/null @@ -1,26 +0,0 @@ -HOSTS: - ubuntu1204: - roles: - - master - - database - - dashboard - platform: ubuntu-12.04-amd64 - template: ubuntu-1204-x86_64 - hypervisor: vcloud - win2003_x86_64: - roles: - - agent - - default - platform: windows-2003-x86_64 - template: win-2003-x86_64 - hypervisor: vcloud -CONFIG: - nfs_server: none - ssh: - keys: "~/.ssh/id_rsa-acceptance" - consoleport: 443 - datastore: instance0 - folder: Delivery/Quality Assurance/Enterprise/Dynamic - resourcepool: delivery/Quality Assurance/Enterprise/Dynamic - pooling_api: http://vcloud.delivery.puppetlabs.net/ - pe_dir: http://neptune.puppetlabs.lan/3.2/ci-ready/ diff --git a/spec/acceptance/nodesets/windows-2008-x86_64.yml b/spec/acceptance/nodesets/windows-2008-x86_64.yml deleted file mode 100644 index ae3c11dd1..000000000 --- a/spec/acceptance/nodesets/windows-2008-x86_64.yml +++ /dev/null @@ -1,26 +0,0 @@ -HOSTS: - ubuntu1204: - roles: - - master - - database - - dashboard - platform: ubuntu-12.04-amd64 - template: ubuntu-1204-x86_64 - hypervisor: vcloud - win2008_x86_64: - roles: - - agent - - default - platform: windows-2008-x86_64 - template: win-2008-x86_64 - hypervisor: vcloud -CONFIG: - nfs_server: none - ssh: - keys: "~/.ssh/id_rsa-acceptance" - consoleport: 443 - datastore: instance0 - folder: Delivery/Quality Assurance/Enterprise/Dynamic - resourcepool: delivery/Quality Assurance/Enterprise/Dynamic - pooling_api: http://vcloud.delivery.puppetlabs.net/ - pe_dir: http://neptune.puppetlabs.lan/3.2/ci-ready/ diff --git a/spec/acceptance/nodesets/windows-2008r2-x86_64.yml b/spec/acceptance/nodesets/windows-2008r2-x86_64.yml deleted file mode 100644 index 63923ac10..000000000 --- a/spec/acceptance/nodesets/windows-2008r2-x86_64.yml +++ /dev/null @@ -1,26 +0,0 @@ -HOSTS: - ubuntu1204: - roles: - - master - - database - - dashboard - platform: ubuntu-12.04-amd64 - template: ubuntu-1204-x86_64 - hypervisor: vcloud - win2008r2: - roles: - - agent - - default - platform: windows-2008r2-x86_64 - template: win-2008r2-x86_64 - hypervisor: vcloud -CONFIG: - nfs_server: none - ssh: - keys: "~/.ssh/id_rsa-acceptance" - consoleport: 443 - datastore: instance0 - folder: Delivery/Quality Assurance/Enterprise/Dynamic - resourcepool: delivery/Quality Assurance/Enterprise/Dynamic - pooling_api: http://vcloud.delivery.puppetlabs.net/ - pe_dir: http://neptune.puppetlabs.lan/3.2/ci-ready/ diff --git a/spec/acceptance/nodesets/windows-2012-x86_64.yml b/spec/acceptance/nodesets/windows-2012-x86_64.yml deleted file mode 100644 index eaa4eca90..000000000 --- a/spec/acceptance/nodesets/windows-2012-x86_64.yml +++ /dev/null @@ -1,26 +0,0 @@ -HOSTS: - ubuntu1204: - roles: - - master - - database - - dashboard - platform: ubuntu-12.04-amd64 - template: ubuntu-1204-x86_64 - hypervisor: vcloud - win2012: - roles: - - agent - - default - platform: windows-2012-x86_64 - template: win-2012-x86_64 - hypervisor: vcloud -CONFIG: - nfs_server: none - ssh: - keys: "~/.ssh/id_rsa-acceptance" - consoleport: 443 - datastore: instance0 - folder: Delivery/Quality Assurance/Enterprise/Dynamic - resourcepool: delivery/Quality Assurance/Enterprise/Dynamic - pooling_api: http://vcloud.delivery.puppetlabs.net/ - pe_dir: http://neptune.puppetlabs.lan/3.2/ci-ready/ diff --git a/spec/acceptance/nodesets/windows-2012r2-x86_64.yml b/spec/acceptance/nodesets/windows-2012r2-x86_64.yml deleted file mode 100644 index 1f0ea97c7..000000000 --- a/spec/acceptance/nodesets/windows-2012r2-x86_64.yml +++ /dev/null @@ -1,26 +0,0 @@ -HOSTS: - ubuntu1204: - roles: - - master - - database - - dashboard - platform: ubuntu-12.04-amd64 - template: ubuntu-1204-x86_64 - hypervisor: vcloud - win2012r2: - roles: - - agent - - default - platform: windows-2012r2-x86_64 - template: win-2012r2-x86_64 - hypervisor: vcloud -CONFIG: - nfs_server: none - ssh: - keys: "~/.ssh/id_rsa-acceptance" - consoleport: 443 - datastore: instance0 - folder: Delivery/Quality Assurance/Enterprise/Dynamic - resourcepool: delivery/Quality Assurance/Enterprise/Dynamic - pooling_api: http://vcloud.delivery.puppetlabs.net/ - pe_dir: http://neptune.puppetlabs.lan/3.2/ci-ready/ diff --git a/spec/acceptance/num2bool_spec.rb b/spec/acceptance/num2bool_spec.rb deleted file mode 100755 index 1d99ba025..000000000 --- a/spec/acceptance/num2bool_spec.rb +++ /dev/null @@ -1,76 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'num2bool function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'bools positive numbers and numeric strings as true' do - pp = <<-EOS - $a = 1 - $b = "1" - $c = "50" - $ao = num2bool($a) - $bo = num2bool($b) - $co = num2bool($c) - notice(inline_template('a is <%= @ao.inspect %>')) - notice(inline_template('b is <%= @bo.inspect %>')) - notice(inline_template('c is <%= @co.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/a is true/) - expect(r.stdout).to match(/b is true/) - expect(r.stdout).to match(/c is true/) - end - end - it 'bools negative numbers as false' do - pp = <<-EOS - $a = 0 - $b = -0.1 - $c = ["-50","1"] - $ao = num2bool($a) - $bo = num2bool($b) - $co = num2bool($c) - notice(inline_template('a is <%= @ao.inspect %>')) - notice(inline_template('b is <%= @bo.inspect %>')) - notice(inline_template('c is <%= @co.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/a is false/) - expect(r.stdout).to match(/b is false/) - expect(r.stdout).to match(/c is false/) - end - end - end - describe 'failure' do - it 'fails on words' do - pp = <<-EOS - $a = "a" - $ao = num2bool($a) - notice(inline_template('a is <%= @ao.inspect %>')) - EOS - expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/not look like a number/) - end - - it 'fails on numberwords' do - pp = <<-EOS - $b = "1b" - $bo = num2bool($b) - notice(inline_template('b is <%= @bo.inspect %>')) - EOS - expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/not look like a number/) - - end - - it 'fails on non-numeric/strings' do - pending "The function will call .to_s.to_i on anything not a Numeric or - String, and results in 0. Is this intended?" - pp = <<-EOS - $c = {"c" => "-50"} - $co = num2bool($c) - notice(inline_template('c is <%= @co.inspect %>')) - EOS - expect(apply_manifest(ppc :expect_failures => true).stderr).to match(/Unable to parse/) - end - end -end diff --git a/spec/acceptance/parsejson_spec.rb b/spec/acceptance/parsejson_spec.rb deleted file mode 100755 index d0e3de847..000000000 --- a/spec/acceptance/parsejson_spec.rb +++ /dev/null @@ -1,55 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'parsejson function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'parses valid json' do - pp = <<-EOS - $a = '{"hunter": "washere", "tests": "passing"}' - $ao = parsejson($a) - $tests = $ao['tests'] - notice(inline_template('tests are <%= @tests.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/tests are "passing"/) - end - end - end - - describe 'failure' do - it 'raises error on incorrect json' do - pp = <<-EOS - $a = '{"hunter": "washere", "tests": "passing",}' - $ao = parsejson($a, 'tests are using the default value') - notice(inline_template('a is <%= @ao.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/tests are using the default value/) - end - end - - it 'raises error on incorrect json' do - pp = <<-EOS - $a = '{"hunter": "washere", "tests": "passing",}' - $ao = parsejson($a) - notice(inline_template('a is <%= @ao.inspect %>')) - EOS - - apply_manifest(pp, :expect_failures => true) do |r| - expect(r.stderr).to match(/expected next name/) - end - end - - it 'raises error on incorrect number of arguments' do - pp = <<-EOS - $o = parsejson() - EOS - - apply_manifest(pp, :expect_failures => true) do |r| - expect(r.stderr).to match(/wrong number of arguments/i) - end - end - end -end diff --git a/spec/acceptance/parseyaml_spec.rb b/spec/acceptance/parseyaml_spec.rb deleted file mode 100755 index 64511f13e..000000000 --- a/spec/acceptance/parseyaml_spec.rb +++ /dev/null @@ -1,58 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'parseyaml function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'parses valid yaml' do - pp = <<-EOS - $a = "---\nhunter: washere\ntests: passing\n" - $o = parseyaml($a) - $tests = $o['tests'] - notice(inline_template('tests are <%= @tests.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/tests are "passing"/) - end - end - end - - describe 'failure' do - it 'returns the default value on incorrect yaml' do - pp = <<-EOS - $a = "---\nhunter: washere\ntests: passing\n:" - $o = parseyaml($a, {'tests' => 'using the default value'}) - $tests = $o['tests'] - notice(inline_template('tests are <%= @tests.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/tests are "using the default value"/) - end - end - - it 'raises error on incorrect yaml' do - pp = <<-EOS - $a = "---\nhunter: washere\ntests: passing\n:" - $o = parseyaml($a) - $tests = $o['tests'] - notice(inline_template('tests are <%= @tests.inspect %>')) - EOS - - apply_manifest(pp, :expect_failures => true) do |r| - expect(r.stderr).to match(/(syntax error|did not find expected key)/) - end - end - - - it 'raises error on incorrect number of arguments' do - pp = <<-EOS - $o = parseyaml() - EOS - - apply_manifest(pp, :expect_failures => true) do |r| - expect(r.stderr).to match(/wrong number of arguments/i) - end - end - end -end diff --git a/spec/acceptance/pick_default_spec.rb b/spec/acceptance/pick_default_spec.rb deleted file mode 100755 index a663f54e8..000000000 --- a/spec/acceptance/pick_default_spec.rb +++ /dev/null @@ -1,54 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'pick_default function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'pick_defaults a default value' do - pp = <<-EOS - $a = undef - $o = pick_default($a, 'default') - notice(inline_template('picked is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/picked is "default"/) - end - end - it 'pick_defaults with no value' do - pp = <<-EOS - $a = undef - $b = undef - $o = pick_default($a,$b) - notice(inline_template('picked is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/picked is ""/) - end - end - it 'pick_defaults the first set value' do - pp = <<-EOS - $a = "something" - $b = "long" - $o = pick_default($a, $b, 'default') - notice(inline_template('picked is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/picked is "something"/) - end - end - end - describe 'failure' do - it 'raises error with no values' do - pp = <<-EOS - $o = pick_default() - notice(inline_template('picked is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :expect_failures => true) do |r| - expect(r.stderr).to match(/Must receive at least one argument/) - end - end - end -end diff --git a/spec/acceptance/pick_spec.rb b/spec/acceptance/pick_spec.rb deleted file mode 100755 index 46cf63f28..000000000 --- a/spec/acceptance/pick_spec.rb +++ /dev/null @@ -1,44 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'pick function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'picks a default value' do - pp = <<-EOS - $a = undef - $o = pick($a, 'default') - notice(inline_template('picked is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/picked is "default"/) - end - end - it 'picks the first set value' do - pp = <<-EOS - $a = "something" - $b = "long" - $o = pick($a, $b, 'default') - notice(inline_template('picked is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/picked is "something"/) - end - end - end - describe 'failure' do - it 'raises error with all undef values' do - pp = <<-EOS - $a = undef - $b = undef - $o = pick($a, $b) - notice(inline_template('picked is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :expect_failures => true) do |r| - expect(r.stderr).to match(/must receive at least one non empty value/) - end - end - end -end diff --git a/spec/acceptance/prefix_spec.rb b/spec/acceptance/prefix_spec.rb deleted file mode 100755 index de55530eb..000000000 --- a/spec/acceptance/prefix_spec.rb +++ /dev/null @@ -1,42 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'prefix function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'prefixes array of values' do - pp = <<-EOS - $o = prefix(['a','b','c'],'p') - notice(inline_template('prefix is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/prefix is \["pa", "pb", "pc"\]/) - end - end - it 'prefixs with empty array' do - pp = <<-EOS - $o = prefix([],'p') - notice(inline_template('prefix is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/prefix is \[\]/) - end - end - it 'prefixs array of values with undef' do - pp = <<-EOS - $o = prefix(['a','b','c'], undef) - notice(inline_template('prefix is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/prefix is \["a", "b", "c"\]/) - end - end - end - describe 'failure' do - it 'fails with no arguments' - it 'fails when first argument is not array' - it 'fails when second argument is not string' - end -end diff --git a/spec/acceptance/pw_hash_spec.rb b/spec/acceptance/pw_hash_spec.rb deleted file mode 100644 index cd4cb87c5..000000000 --- a/spec/acceptance/pw_hash_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -# Windows and OS X do not have useful implementations of crypt(3) -describe 'pw_hash function', :unless => (UNSUPPORTED_PLATFORMS + ['windows', 'Darwin', 'SLES']).include?(fact('operatingsystem')) do - describe 'success' do - it 'hashes passwords' do - pp = <<-EOS - $o = pw_hash('password', 'sha-512', 'salt') - notice(inline_template('pw_hash is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/pw_hash is "\$6\$salt\$IxDD3jeSOb5eB1CX5LBsqZFVkJdido3OUILO5Ifz5iwMuTS4XMS130MTSuDDl3aCI6WouIL9AjRbLCelDCy\.g\."/) - end - end - - it 'returns nil if no password is provided' do - pp = <<-EOS - $o = pw_hash('', 'sha-512', 'salt') - notice(inline_template('pw_hash is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/pw_hash is nil/) - end - end - end - describe 'failure' do - it 'handles less than three arguments' - it 'handles more than three arguments' - it 'handles non strings' - end -end diff --git a/spec/acceptance/range_spec.rb b/spec/acceptance/range_spec.rb deleted file mode 100755 index a3ccd3396..000000000 --- a/spec/acceptance/range_spec.rb +++ /dev/null @@ -1,36 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'range function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'ranges letters' do - pp = <<-EOS - $o = range('a','d') - notice(inline_template('range is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/range is \["a", "b", "c", "d"\]/) - end - end - it 'ranges letters with a step' do - pp = <<-EOS - $o = range('a','d', '2') - notice(inline_template('range is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/range is \["a", "c"\]/) - end - end - it 'ranges letters with a negative step' - it 'ranges numbers' - it 'ranges numbers with a step' - it 'ranges numbers with a negative step' - it 'ranges numeric strings' - it 'ranges zero padded numbers' - end - describe 'failure' do - it 'fails with no arguments' - end -end diff --git a/spec/acceptance/reject_spec.rb b/spec/acceptance/reject_spec.rb deleted file mode 100755 index 7f16a008d..000000000 --- a/spec/acceptance/reject_spec.rb +++ /dev/null @@ -1,42 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'reject function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'rejects array of values' do - pp = <<-EOS - $o = reject(['aaa','bbb','ccc','aaaddd'], 'aaa') - notice(inline_template('reject is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/reject is \["bbb", "ccc"\]/) - end - end - it 'rejects with empty array' do - pp = <<-EOS - $o = reject([],'aaa') - notice(inline_template('reject is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/reject is \[\]/) - end - end - it 'rejects array of values with undef' do - pp = <<-EOS - $o = reject(['aaa','bbb','ccc','aaaddd'], undef) - notice(inline_template('reject is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/reject is \[\]/) - end - end - end - describe 'failure' do - it 'fails with no arguments' - it 'fails when first argument is not array' - it 'fails when second argument is not string' - end -end diff --git a/spec/acceptance/reverse_spec.rb b/spec/acceptance/reverse_spec.rb deleted file mode 100755 index c3f01567a..000000000 --- a/spec/acceptance/reverse_spec.rb +++ /dev/null @@ -1,23 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'reverse function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'reverses strings' do - pp = <<-EOS - $a = "the public art galleries" - # Anagram: Large picture halls, I bet - $o = reverse($a) - notice(inline_template('reverse is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/reverse is "seirellag tra cilbup eht"/) - end - end - end - describe 'failure' do - it 'handles no arguments' - it 'handles non strings or arrays' - end -end diff --git a/spec/acceptance/rstrip_spec.rb b/spec/acceptance/rstrip_spec.rb deleted file mode 100755 index b57a8b045..000000000 --- a/spec/acceptance/rstrip_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'rstrip function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'rstrips arrays' do - pp = <<-EOS - $a = [" the "," public "," art","galleries "] - # Anagram: Large picture halls, I bet - $o = rstrip($a) - notice(inline_template('rstrip is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/rstrip is \[" the", " public", " art", "galleries"\]/) - end - end - it 'rstrips strings' do - pp = <<-EOS - $a = " blowzy night-frumps vex'd jack q " - $o = rstrip($a) - notice(inline_template('rstrip is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/rstrip is " blowzy night-frumps vex'd jack q"/) - end - end - end - describe 'failure' do - it 'handles no arguments' - it 'handles non strings or arrays' - end -end diff --git a/spec/acceptance/shuffle_spec.rb b/spec/acceptance/shuffle_spec.rb deleted file mode 100755 index b840d1f1b..000000000 --- a/spec/acceptance/shuffle_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'shuffle function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'shuffles arrays' do - pp = <<-EOS - $a = ["1", "2", "3", "4", "5", "6", "7", "8", "the","public","art","galleries"] - # Anagram: Large picture halls, I bet - $o = shuffle($a) - notice(inline_template('shuffle is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to_not match(/shuffle is \["1", "2", "3", "4", "5", "6", "7", "8", "the", "public", "art", "galleries"\]/) - end - end - it 'shuffles strings' do - pp = <<-EOS - $a = "blowzy night-frumps vex'd jack q" - $o = shuffle($a) - notice(inline_template('shuffle is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to_not match(/shuffle is "blowzy night-frumps vex'd jack q"/) - end - end - end - describe 'failure' do - it 'handles no arguments' - it 'handles non strings or arrays' - end -end diff --git a/spec/acceptance/size_spec.rb b/spec/acceptance/size_spec.rb deleted file mode 100755 index a52b778bd..000000000 --- a/spec/acceptance/size_spec.rb +++ /dev/null @@ -1,55 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'size function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'single string size' do - pp = <<-EOS - $a = 'discombobulate' - $o = size($a) - notice(inline_template('size is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/size is 14/) - end - end - it 'with empty string' do - pp = <<-EOS - $a = '' - $o = size($a) - notice(inline_template('size is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/size is 0/) - end - end - it 'with undef' do - pp = <<-EOS - $a = undef - $o = size($a) - notice(inline_template('size is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/size is 0/) - end - end - it 'strings in array' do - pp = <<-EOS - $a = ['discombobulate', 'moo'] - $o = size($a) - notice(inline_template('size is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/size is 2/) - end - end - end - describe 'failure' do - it 'handles no arguments' - it 'handles non strings or arrays' - end -end diff --git a/spec/acceptance/sort_spec.rb b/spec/acceptance/sort_spec.rb deleted file mode 100755 index c85bfabd5..000000000 --- a/spec/acceptance/sort_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'sort function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'sorts arrays' do - pp = <<-EOS - $a = ["the","public","art","galleries"] - # Anagram: Large picture halls, I bet - $o = sort($a) - notice(inline_template('sort is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/sort is \["art", "galleries", "public", "the"\]/) - end - end - it 'sorts strings' do - pp = <<-EOS - $a = "blowzy night-frumps vex'd jack q" - $o = sort($a) - notice(inline_template('sort is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/sort is " '-abcdefghijklmnopqrstuvwxyz"/) - end - end - end - describe 'failure' do - it 'handles no arguments' - it 'handles non strings or arrays' - end -end diff --git a/spec/acceptance/squeeze_spec.rb b/spec/acceptance/squeeze_spec.rb deleted file mode 100755 index 400a458c9..000000000 --- a/spec/acceptance/squeeze_spec.rb +++ /dev/null @@ -1,47 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'squeeze function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'squeezes arrays' do - pp = <<-EOS - # Real words! - $a = ["wallless", "laparohysterosalpingooophorectomy", "brrr", "goddessship"] - $o = squeeze($a) - notice(inline_template('squeeze is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/squeeze is \["wales", "laparohysterosalpingophorectomy", "br", "godeship"\]/) - end - end - it 'squeezez arrays with an argument' - it 'squeezes strings' do - pp = <<-EOS - $a = "wallless laparohysterosalpingooophorectomy brrr goddessship" - $o = squeeze($a) - notice(inline_template('squeeze is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/squeeze is "wales laparohysterosalpingophorectomy br godeship"/) - end - end - - it 'squeezes strings with an argument' do - pp = <<-EOS - $a = "countessship duchessship governessship hostessship" - $o = squeeze($a, 's') - notice(inline_template('squeeze is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/squeeze is "counteship ducheship governeship hosteship"/) - end - end - end - describe 'failure' do - it 'handles no arguments' - it 'handles non strings or arrays' - end -end diff --git a/spec/acceptance/str2bool_spec.rb b/spec/acceptance/str2bool_spec.rb deleted file mode 100755 index cf549dab8..000000000 --- a/spec/acceptance/str2bool_spec.rb +++ /dev/null @@ -1,31 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'str2bool function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'works with "y"' do - pp = <<-EOS - $o = str2bool('y') - notice(inline_template('str2bool is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/str2bool is true/) - end - end - it 'works with "Y"' - it 'works with "yes"' - it 'works with "1"' - it 'works with "true"' - it 'works with "n"' - it 'works with "N"' - it 'works with "no"' - it 'works with "0"' - it 'works with "false"' - it 'works with undef' - end - describe 'failure' do - it 'handles no arguments' - it 'handles non arrays or strings' - end -end diff --git a/spec/acceptance/str2saltedsha512_spec.rb b/spec/acceptance/str2saltedsha512_spec.rb deleted file mode 100755 index 993e63bac..000000000 --- a/spec/acceptance/str2saltedsha512_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'str2saltedsha512 function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'works with "y"' do - pp = <<-EOS - $o = str2saltedsha512('password') - notice(inline_template('str2saltedsha512 is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/str2saltedsha512 is "[a-f0-9]{136}"/) - end - end - end - describe 'failure' do - it 'handles no arguments' - it 'handles more than one argument' - it 'handles non strings' - end -end diff --git a/spec/acceptance/strftime_spec.rb b/spec/acceptance/strftime_spec.rb deleted file mode 100755 index 53b7f903b..000000000 --- a/spec/acceptance/strftime_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'strftime function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'gives the Century' do - pp = <<-EOS - $o = strftime('%C') - notice(inline_template('strftime is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/strftime is "20"/) - end - end - it 'takes a timezone argument' - end - describe 'failure' do - it 'handles no arguments' - it 'handles invalid format strings' - end -end diff --git a/spec/acceptance/strip_spec.rb b/spec/acceptance/strip_spec.rb deleted file mode 100755 index 906fd7abe..000000000 --- a/spec/acceptance/strip_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'strip function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'strips arrays' do - pp = <<-EOS - $a = [" the "," public "," art","galleries "] - # Anagram: Large picture halls, I bet - $o = strip($a) - notice(inline_template('strip is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/strip is \["the", "public", "art", "galleries"\]/) - end - end - it 'strips strings' do - pp = <<-EOS - $a = " blowzy night-frumps vex'd jack q " - $o = strip($a) - notice(inline_template('strip is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/strip is "blowzy night-frumps vex'd jack q"/) - end - end - end - describe 'failure' do - it 'handles no arguments' - it 'handles non strings or arrays' - end -end diff --git a/spec/acceptance/suffix_spec.rb b/spec/acceptance/suffix_spec.rb deleted file mode 100755 index 630f866d7..000000000 --- a/spec/acceptance/suffix_spec.rb +++ /dev/null @@ -1,42 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'suffix function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'suffixes array of values' do - pp = <<-EOS - $o = suffix(['a','b','c'],'p') - notice(inline_template('suffix is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/suffix is \["ap", "bp", "cp"\]/) - end - end - it 'suffixs with empty array' do - pp = <<-EOS - $o = suffix([],'p') - notice(inline_template('suffix is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/suffix is \[\]/) - end - end - it 'suffixs array of values with undef' do - pp = <<-EOS - $o = suffix(['a','b','c'], undef) - notice(inline_template('suffix is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/suffix is \["a", "b", "c"\]/) - end - end - end - describe 'failure' do - it 'fails with no arguments' - it 'fails when first argument is not array' - it 'fails when second argument is not string' - end -end diff --git a/spec/acceptance/swapcase_spec.rb b/spec/acceptance/swapcase_spec.rb deleted file mode 100755 index b7894fbe2..000000000 --- a/spec/acceptance/swapcase_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'swapcase function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'works with strings' do - pp = <<-EOS - $o = swapcase('aBcD') - notice(inline_template('swapcase is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/swapcase is "AbCd"/) - end - end - it 'works with arrays' - end - describe 'failure' do - it 'handles no arguments' - it 'handles non arrays or strings' - end -end diff --git a/spec/acceptance/time_spec.rb b/spec/acceptance/time_spec.rb deleted file mode 100755 index cdb296070..000000000 --- a/spec/acceptance/time_spec.rb +++ /dev/null @@ -1,36 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'time function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'gives the time' do - pp = <<-EOS - $o = time() - notice(inline_template('time is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - m = r.stdout.match(/time is (\d+)\D/) - - # When I wrote this test - expect(Integer(m[1])).to be > 1398894170 - end - end - it 'takes a timezone argument' do - pp = <<-EOS - $o = time('UTC') - notice(inline_template('time is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - m = r.stdout.match(/time is (\d+)\D/) - - expect(Integer(m[1])).to be > 1398894170 - end - end - end - describe 'failure' do - it 'handles more arguments' - it 'handles invalid timezones' - end -end diff --git a/spec/acceptance/to_bytes_spec.rb b/spec/acceptance/to_bytes_spec.rb deleted file mode 100755 index 2b4c61f48..000000000 --- a/spec/acceptance/to_bytes_spec.rb +++ /dev/null @@ -1,27 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'to_bytes function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'converts kB to B' do - pp = <<-EOS - $o = to_bytes('4 kB') - notice(inline_template('to_bytes is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - m = r.stdout.match(/to_bytes is (\d+)\D/) - expect(m[1]).to eq("4096") - end - end - it 'works without the B in unit' - it 'works without a space before unit' - it 'works without a unit' - it 'converts fractions' - end - describe 'failure' do - it 'handles no arguments' - it 'handles non integer arguments' - it 'handles unknown units like uB' - end -end diff --git a/spec/acceptance/try_get_value_spec.rb b/spec/acceptance/try_get_value_spec.rb deleted file mode 100755 index c0bf38ae3..000000000 --- a/spec/acceptance/try_get_value_spec.rb +++ /dev/null @@ -1,47 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'try_get_value function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'gets a value' do - pp = <<-EOS - $data = { - 'a' => { 'b' => 'passing'} - } - - $tests = try_get_value($data, 'a/b') - notice(inline_template('tests are <%= @tests.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/tests are "passing"/) - end - end - end - describe 'failure' do - it 'uses a default value' do - pp = <<-EOS - $data = { - 'a' => { 'b' => 'passing'} - } - - $tests = try_get_value($data, 'c/d', 'using the default value') - notice(inline_template('tests are <%= @tests.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/using the default value/) - end - end - - it 'raises error on incorrect number of arguments' do - pp = <<-EOS - $o = try_get_value() - EOS - - apply_manifest(pp, :expect_failures => true) do |r| - expect(r.stderr).to match(/wrong number of arguments/i) - end - end - end -end diff --git a/spec/acceptance/type_spec.rb b/spec/acceptance/type_spec.rb deleted file mode 100755 index 67e324803..000000000 --- a/spec/acceptance/type_spec.rb +++ /dev/null @@ -1,37 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'type function', :unless => (UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) || is_future_parser_enabled?) do - describe 'success' do - it 'types arrays' do - pp = <<-EOS - $a = ["the","public","art","galleries"] - # Anagram: Large picture halls, I bet - $o = type($a) - notice(inline_template('type is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/type is "array"/) - end - end - it 'types strings' do - pp = <<-EOS - $a = "blowzy night-frumps vex'd jack q" - $o = type($a) - notice(inline_template('type is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/type is "string"/) - end - end - it 'types hashes' - it 'types integers' - it 'types floats' - it 'types booleans' - end - describe 'failure' do - it 'handles no arguments' - end -end diff --git a/spec/acceptance/union_spec.rb b/spec/acceptance/union_spec.rb deleted file mode 100755 index 160fd7b09..000000000 --- a/spec/acceptance/union_spec.rb +++ /dev/null @@ -1,25 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'union function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'unions arrays' do - pp = <<-EOS - $a = ["the","public"] - $b = ["art"] - $c = ["galleries"] - # Anagram: Large picture halls, I bet - $o = union($a,$b,$c) - notice(inline_template('union is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/union is \["the", "public", "art", "galleries"\]/) - end - end - end - describe 'failure' do - it 'handles no arguments' - it 'handles non arrays' - end -end diff --git a/spec/acceptance/unique_spec.rb b/spec/acceptance/unique_spec.rb deleted file mode 100755 index bfadad19b..000000000 --- a/spec/acceptance/unique_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'unique function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'uniques arrays' do - pp = <<-EOS - $a = ["wallless", "wallless", "brrr", "goddessship"] - $o = unique($a) - notice(inline_template('unique is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/unique is \["wallless", "brrr", "goddessship"\]/) - end - end - it 'uniques strings' do - pp = <<-EOS - $a = "wallless laparohysterosalpingooophorectomy brrr goddessship" - $o = unique($a) - notice(inline_template('unique is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/unique is "wales prohytingcmbd"/) - end - end - end - describe 'failure' do - it 'handles no arguments' - it 'handles non strings or arrays' - end -end diff --git a/spec/acceptance/unsupported_spec.rb b/spec/acceptance/unsupported_spec.rb deleted file mode 100755 index 1c559f67e..000000000 --- a/spec/acceptance/unsupported_spec.rb +++ /dev/null @@ -1,11 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'unsupported distributions and OSes', :if => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - it 'should fail' do - pp = <<-EOS - class { 'mysql::server': } - EOS - expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/unsupported osfamily/i) - end -end diff --git a/spec/acceptance/upcase_spec.rb b/spec/acceptance/upcase_spec.rb deleted file mode 100755 index 3d2906d72..000000000 --- a/spec/acceptance/upcase_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'upcase function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'upcases arrays' do - pp = <<-EOS - $a = ["wallless", "laparohysterosalpingooophorectomy", "brrr", "goddessship"] - $o = upcase($a) - notice(inline_template('upcase is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/upcase is \["WALLLESS", "LAPAROHYSTEROSALPINGOOOPHORECTOMY", "BRRR", "GODDESSSHIP"\]/) - end - end - it 'upcases strings' do - pp = <<-EOS - $a = "wallless laparohysterosalpingooophorectomy brrr goddessship" - $o = upcase($a) - notice(inline_template('upcase is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/upcase is "WALLLESS LAPAROHYSTEROSALPINGOOOPHORECTOMY BRRR GODDESSSHIP"/) - end - end - end - describe 'failure' do - it 'handles no arguments' - it 'handles non strings or arrays' - end -end diff --git a/spec/acceptance/uriescape_spec.rb b/spec/acceptance/uriescape_spec.rb deleted file mode 100755 index 7e30205e8..000000000 --- a/spec/acceptance/uriescape_spec.rb +++ /dev/null @@ -1,23 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'uriescape function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'uriescape strings' do - pp = <<-EOS - $a = ":/?#[]@!$&'()*+,;= \\\"{}" - $o = uriescape($a) - notice(inline_template('uriescape is <%= @o.inspect %>')) - EOS - - apply_manifest(pp, :catch_failures => true) do |r| - expect(r.stdout).to match(/uriescape is ":\/\?%23\[\]@!\$&'\(\)\*\+,;=%20%22%7B%7D"/) - end - end - it 'does nothing if a string is already safe' - end - describe 'failure' do - it 'handles no arguments' - it 'handles non strings or arrays' - end -end diff --git a/spec/acceptance/validate_absolute_path_spec.rb b/spec/acceptance/validate_absolute_path_spec.rb deleted file mode 100755 index 7082e848e..000000000 --- a/spec/acceptance/validate_absolute_path_spec.rb +++ /dev/null @@ -1,31 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'validate_absolute_path function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - %w{ - C:/ - C:\\\\ - C:\\\\WINDOWS\\\\System32 - C:/windows/system32 - X:/foo/bar - X:\\\\foo\\\\bar - /var/tmp - /var/lib/puppet - /var/opt/../lib/puppet - }.each do |path| - it "validates a single argument #{path}" do - pp = <<-EOS - $one = '#{path}' - validate_absolute_path($one) - EOS - - apply_manifest(pp, :catch_failures => true) - end - end - end - describe 'failure' do - it 'handles improper number of arguments' - it 'handles relative paths' - end -end diff --git a/spec/acceptance/validate_array_spec.rb b/spec/acceptance/validate_array_spec.rb deleted file mode 100755 index b53e98c27..000000000 --- a/spec/acceptance/validate_array_spec.rb +++ /dev/null @@ -1,37 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'validate_array function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'validates a single argument' do - pp = <<-EOS - $one = ['a', 'b'] - validate_array($one) - EOS - - apply_manifest(pp, :catch_failures => true) - end - it 'validates an multiple arguments' do - pp = <<-EOS - $one = ['a', 'b'] - $two = [['c'], 'd'] - validate_array($one,$two) - EOS - - apply_manifest(pp, :catch_failures => true) - end - it 'validates a non-array' do - { - %{validate_array({'a' => 'hash' })} => "Hash", - %{validate_array('string')} => "String", - %{validate_array(false)} => "FalseClass", - %{validate_array(undef)} => "String" - }.each do |pp,type| - expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/a #{type}/) - end - end - end - describe 'failure' do - it 'handles improper number of arguments' - end -end diff --git a/spec/acceptance/validate_augeas_spec.rb b/spec/acceptance/validate_augeas_spec.rb deleted file mode 100755 index 71a4c8425..000000000 --- a/spec/acceptance/validate_augeas_spec.rb +++ /dev/null @@ -1,63 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'validate_augeas function', :unless => ((UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem'))) or (fact('osfamily') == 'windows')) do - describe 'prep' do - it 'installs augeas for tests' - end - describe 'success' do - context 'valid inputs with no 3rd argument' do - { - 'root:x:0:0:root:/root:/bin/bash\n' => 'Passwd.lns', - 'proc /proc proc nodev,noexec,nosuid 0 0\n' => 'Fstab.lns' - }.each do |line,lens| - it "validates a single argument for #{lens}" do - pp = <<-EOS - $line = "#{line}" - $lens = "#{lens}" - validate_augeas($line, $lens) - EOS - - apply_manifest(pp, :catch_failures => true) - end - end - end - context 'valid inputs with 3rd and 4th arguments' do - it "validates a restricted value" do - line = 'root:x:0:0:root:/root:/bin/barsh\n' - lens = 'Passwd.lns' - restriction = '$file/*[shell="/bin/barsh"]' - pp = <<-EOS - $line = "#{line}" - $lens = "#{lens}" - $restriction = ['#{restriction}'] - validate_augeas($line, $lens, $restriction, "my custom failure message") - EOS - - expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/my custom failure message/) - end - end - context 'invalid inputs' do - { - 'root:x:0:0:root' => 'Passwd.lns', - '127.0.1.1' => 'Hosts.lns' - }.each do |line,lens| - it "validates a single argument for #{lens}" do - pp = <<-EOS - $line = "#{line}" - $lens = "#{lens}" - validate_augeas($line, $lens) - EOS - - apply_manifest(pp, :expect_failures => true) - end - end - end - context 'garbage inputs' do - it 'raises an error on invalid inputs' - end - end - describe 'failure' do - it 'handles improper number of arguments' - end -end diff --git a/spec/acceptance/validate_bool_spec.rb b/spec/acceptance/validate_bool_spec.rb deleted file mode 100755 index c837f089f..000000000 --- a/spec/acceptance/validate_bool_spec.rb +++ /dev/null @@ -1,37 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'validate_bool function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'validates a single argument' do - pp = <<-EOS - $one = true - validate_bool($one) - EOS - - apply_manifest(pp, :catch_failures => true) - end - it 'validates an multiple arguments' do - pp = <<-EOS - $one = true - $two = false - validate_bool($one,$two) - EOS - - apply_manifest(pp, :catch_failures => true) - end - it 'validates a non-bool' do - { - %{validate_bool('true')} => "String", - %{validate_bool('false')} => "String", - %{validate_bool([true])} => "Array", - %{validate_bool(undef)} => "String", - }.each do |pp,type| - expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/a #{type}/) - end - end - end - describe 'failure' do - it 'handles improper number of arguments' - end -end diff --git a/spec/acceptance/validate_cmd_spec.rb b/spec/acceptance/validate_cmd_spec.rb deleted file mode 100755 index 5ac66fdbf..000000000 --- a/spec/acceptance/validate_cmd_spec.rb +++ /dev/null @@ -1,52 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'validate_cmd function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'validates a true command' do - pp = <<-EOS - $one = 'foo' - if $::osfamily == 'windows' { - $two = 'echo' #shell built-in - } else { - $two = '/bin/echo' - } - validate_cmd($one,$two) - EOS - - apply_manifest(pp, :catch_failures => true) - end - it 'validates a fail command' do - pp = <<-EOS - $one = 'foo' - if $::osfamily == 'windows' { - $two = 'C:/aoeu' - } else { - $two = '/bin/aoeu' - } - validate_cmd($one,$two) - EOS - - apply_manifest(pp, :expect_failures => true) - end - it 'validates a fail command with a custom error message' do - pp = <<-EOS - $one = 'foo' - if $::osfamily == 'windows' { - $two = 'C:/aoeu' - } else { - $two = '/bin/aoeu' - } - validate_cmd($one,$two,"aoeu is dvorak") - EOS - - apply_manifest(pp, :expect_failures => true) do |output| - expect(output.stderr).to match(/aoeu is dvorak/) - end - end - end - describe 'failure' do - it 'handles improper number of arguments' - it 'handles improper argument types' - end -end diff --git a/spec/acceptance/validate_hash_spec.rb b/spec/acceptance/validate_hash_spec.rb deleted file mode 100755 index 52fb615bd..000000000 --- a/spec/acceptance/validate_hash_spec.rb +++ /dev/null @@ -1,37 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'validate_hash function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'validates a single argument' do - pp = <<-EOS - $one = { 'a' => 1 } - validate_hash($one) - EOS - - apply_manifest(pp, :catch_failures => true) - end - it 'validates an multiple arguments' do - pp = <<-EOS - $one = { 'a' => 1 } - $two = { 'b' => 2 } - validate_hash($one,$two) - EOS - - apply_manifest(pp, :catch_failures => true) - end - it 'validates a non-hash' do - { - %{validate_hash('{ "not" => "hash" }')} => "String", - %{validate_hash('string')} => "String", - %{validate_hash(["array"])} => "Array", - %{validate_hash(undef)} => "String", - }.each do |pp,type| - expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/a #{type}/) - end - end - end - describe 'failure' do - it 'handles improper number of arguments' - end -end diff --git a/spec/acceptance/validate_ipv4_address_spec.rb b/spec/acceptance/validate_ipv4_address_spec.rb deleted file mode 100755 index 64841c371..000000000 --- a/spec/acceptance/validate_ipv4_address_spec.rb +++ /dev/null @@ -1,31 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'validate_ipv4_address function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'validates a single argument' do - pp = <<-EOS - $one = '1.2.3.4' - validate_ipv4_address($one) - EOS - - apply_manifest(pp, :catch_failures => true) - end - it 'validates an multiple arguments' do - pp = <<-EOS - $one = '1.2.3.4' - $two = '5.6.7.8' - validate_ipv4_address($one,$two) - EOS - - apply_manifest(pp, :catch_failures => true) - end - end - describe 'failure' do - it 'handles improper number of arguments' - it 'handles ipv6 addresses' - it 'handles non-ipv4 strings' - it 'handles numbers' - it 'handles no arguments' - end -end diff --git a/spec/acceptance/validate_ipv6_address_spec.rb b/spec/acceptance/validate_ipv6_address_spec.rb deleted file mode 100755 index 6426d1a52..000000000 --- a/spec/acceptance/validate_ipv6_address_spec.rb +++ /dev/null @@ -1,31 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'validate_ipv6_address function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'validates a single argument' do - pp = <<-EOS - $one = '3ffe:0505:0002::' - validate_ipv6_address($one) - EOS - - apply_manifest(pp, :catch_failures => true) - end - it 'validates an multiple arguments' do - pp = <<-EOS - $one = '3ffe:0505:0002::' - $two = '3ffe:0505:0001::' - validate_ipv6_address($one,$two) - EOS - - apply_manifest(pp, :catch_failures => true) - end - end - describe 'failure' do - it 'handles improper number of arguments' - it 'handles ipv6 addresses' - it 'handles non-ipv6 strings' - it 'handles numbers' - it 'handles no arguments' - end -end diff --git a/spec/acceptance/validate_re_spec.rb b/spec/acceptance/validate_re_spec.rb deleted file mode 100755 index 22f6d47d1..000000000 --- a/spec/acceptance/validate_re_spec.rb +++ /dev/null @@ -1,47 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'validate_re function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'validates a string' do - pp = <<-EOS - $one = 'one' - $two = '^one$' - validate_re($one,$two) - EOS - - apply_manifest(pp, :catch_failures => true) - end - it 'validates an array' do - pp = <<-EOS - $one = 'one' - $two = ['^one$', '^two'] - validate_re($one,$two) - EOS - - apply_manifest(pp, :catch_failures => true) - end - it 'validates a failed array' do - pp = <<-EOS - $one = 'one' - $two = ['^two$', '^three'] - validate_re($one,$two) - EOS - - apply_manifest(pp, :expect_failures => true) - end - it 'validates a failed array with a custom error message' do - pp = <<-EOS - $one = '3.4.3' - $two = '^2.7' - validate_re($one,$two,"The $puppetversion fact does not match 2.7") - EOS - - expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/does not match/) - end - end - describe 'failure' do - it 'handles improper number of arguments' - it 'handles improper argument types' - end -end diff --git a/spec/acceptance/validate_slength_spec.rb b/spec/acceptance/validate_slength_spec.rb deleted file mode 100755 index 1ab2bb986..000000000 --- a/spec/acceptance/validate_slength_spec.rb +++ /dev/null @@ -1,72 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'validate_slength function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'validates a single string max' do - pp = <<-EOS - $one = 'discombobulate' - $two = 17 - validate_slength($one,$two) - EOS - - apply_manifest(pp, :catch_failures => true) - end - it 'validates multiple string maxes' do - pp = <<-EOS - $one = ['discombobulate', 'moo'] - $two = 17 - validate_slength($one,$two) - EOS - - apply_manifest(pp, :catch_failures => true) - end - it 'validates min/max of strings in array' do - pp = <<-EOS - $one = ['discombobulate', 'moo'] - $two = 17 - $three = 3 - validate_slength($one,$two,$three) - EOS - - apply_manifest(pp, :catch_failures => true) - end - it 'validates a single string max of incorrect length' do - pp = <<-EOS - $one = 'discombobulate' - $two = 1 - validate_slength($one,$two) - EOS - - apply_manifest(pp, :expect_failures => true) - end - it 'validates multiple string maxes of incorrect length' do - pp = <<-EOS - $one = ['discombobulate', 'moo'] - $two = 3 - validate_slength($one,$two) - EOS - - apply_manifest(pp, :expect_failures => true) - end - it 'validates multiple strings min/maxes of incorrect length' do - pp = <<-EOS - $one = ['discombobulate', 'moo'] - $two = 17 - $three = 10 - validate_slength($one,$two,$three) - EOS - - apply_manifest(pp, :expect_failures => true) - end - end - describe 'failure' do - it 'handles improper number of arguments' - it 'handles improper first argument type' - it 'handles non-strings in array of first argument' - it 'handles improper second argument type' - it 'handles improper third argument type' - it 'handles negative ranges' - it 'handles improper ranges' - end -end diff --git a/spec/acceptance/validate_string_spec.rb b/spec/acceptance/validate_string_spec.rb deleted file mode 100755 index 8956f48c9..000000000 --- a/spec/acceptance/validate_string_spec.rb +++ /dev/null @@ -1,36 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'validate_string function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'validates a single argument' do - pp = <<-EOS - $one = 'string' - validate_string($one) - EOS - - apply_manifest(pp, :catch_failures => true) - end - it 'validates an multiple arguments' do - pp = <<-EOS - $one = 'string' - $two = 'also string' - validate_string($one,$two) - EOS - - apply_manifest(pp, :catch_failures => true) - end - it 'validates a non-string' do - { - %{validate_string({ 'a' => 'hash' })} => "Hash", - %{validate_string(['array'])} => "Array", - %{validate_string(false)} => "FalseClass", - }.each do |pp,type| - expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/a #{type}/) - end - end - end - describe 'failure' do - it 'handles improper number of arguments' - end -end diff --git a/spec/acceptance/values_at_spec.rb b/spec/acceptance/values_at_spec.rb deleted file mode 100755 index da63cf307..000000000 --- a/spec/acceptance/values_at_spec.rb +++ /dev/null @@ -1,73 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'values_at function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'returns a specific value' do - pp = <<-EOS - $one = ['a','b','c','d','e'] - $two = 1 - $output = values_at($one,$two) - notice(inline_template('<%= @output.inspect %>')) - EOS - - expect(apply_manifest(pp, :catch_failures => true).stdout).to match(/\["b"\]/) - end - it 'returns a specific negative index value' do - pending("negative numbers don't work") - pp = <<-EOS - $one = ['a','b','c','d','e'] - $two = -1 - $output = values_at($one,$two) - notice(inline_template('<%= @output.inspect %>')) - EOS - - expect(apply_manifest(pp, :catch_failures => true).stdout).to match(/\["e"\]/) - end - it 'returns a range of values' do - pp = <<-EOS - $one = ['a','b','c','d','e'] - $two = "1-3" - $output = values_at($one,$two) - notice(inline_template('<%= @output.inspect %>')) - EOS - - expect(apply_manifest(pp, :catch_failures => true).stdout).to match(/\["b", "c", "d"\]/) - end - it 'returns a negative specific value and range of values' do - pp = <<-EOS - $one = ['a','b','c','d','e'] - $two = ["1-3",0] - $output = values_at($one,$two) - notice(inline_template('<%= @output.inspect %>')) - EOS - - expect(apply_manifest(pp, :catch_failures => true).stdout).to match(/\["b", "c", "d", "a"\]/) - end - end - describe 'failure' do - it 'handles improper number of arguments' do - pp = <<-EOS - $one = ['a','b','c','d','e'] - $output = values_at($one) - notice(inline_template('<%= @output.inspect %>')) - EOS - - expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/Wrong number of arguments/) - end - it 'handles non-indicies arguments' do - pp = <<-EOS - $one = ['a','b','c','d','e'] - $two = [] - $output = values_at($one,$two) - notice(inline_template('<%= @output.inspect %>')) - EOS - - expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/at least one positive index/) - end - - it 'detects index ranges smaller than the start range' - it 'handles index ranges larger than array' - it 'handles non-integer indicies' - end -end diff --git a/spec/acceptance/values_spec.rb b/spec/acceptance/values_spec.rb deleted file mode 100755 index a2eff329d..000000000 --- a/spec/acceptance/values_spec.rb +++ /dev/null @@ -1,35 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' - -describe 'values function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'returns an array of values' do - pp = <<-EOS - $arg = { - 'a' => 1, - 'b' => 2, - 'c' => 3, - } - $output = values($arg) - notice(inline_template('<%= @output.sort.inspect %>')) - EOS - if is_future_parser_enabled? - expect(apply_manifest(pp, :catch_failures => true).stdout).to match(/\[1, 2, 3\]/) - else - expect(apply_manifest(pp, :catch_failures => true).stdout).to match(/\["1", "2", "3"\]/) - end - - end - end - describe 'failure' do - it 'handles non-hash arguments' do - pp = <<-EOS - $arg = "foo" - $output = values($arg) - notice(inline_template('<%= @output.inspect %>')) - EOS - - expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/Requires hash/) - end - end -end diff --git a/spec/acceptance/zip_spec.rb b/spec/acceptance/zip_spec.rb deleted file mode 100755 index 139079e31..000000000 --- a/spec/acceptance/zip_spec.rb +++ /dev/null @@ -1,86 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper_acceptance' -require 'puppet' - -describe 'zip function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do - describe 'success' do - it 'zips two arrays of numbers together' do - pp = <<-EOS - $one = [1,2,3,4] - $two = [5,6,7,8] - $output = zip($one,$two) - notice(inline_template('<%= @output.inspect %>')) - EOS - if is_future_parser_enabled? - expect(apply_manifest(pp, :catch_failures => true).stdout).to match(/\[\[1, 5\], \[2, 6\], \[3, 7\], \[4, 8\]\]/) - else - expect(apply_manifest(pp, :catch_failures => true).stdout).to match(/\[\["1", "5"\], \["2", "6"\], \["3", "7"\], \["4", "8"\]\]/) - end - end - it 'zips two arrays of numbers & bools together' do - pp = <<-EOS - $one = [1,2,"three",4] - $two = [true,true,false,false] - $output = zip($one,$two) - notice(inline_template('<%= @output.inspect %>')) - EOS - if is_future_parser_enabled? - expect(apply_manifest(pp, :catch_failures => true).stdout).to match(/\[\[1, true\], \[2, true\], \["three", false\], \[4, false\]\]/) - else - expect(apply_manifest(pp, :catch_failures => true).stdout).to match(/\[\["1", true\], \["2", true\], \["three", false\], \["4", false\]\]/) - end - end - it 'zips two arrays of numbers together and flattens them' do - # XXX This only tests the argument `true`, even though the following are valid: - # 1 t y true yes - # 0 f n false no - # undef undefined - pp = <<-EOS - $one = [1,2,3,4] - $two = [5,6,7,8] - $output = zip($one,$two,true) - notice(inline_template('<%= @output.inspect %>')) - EOS - if is_future_parser_enabled? - expect(apply_manifest(pp, :catch_failures => true).stdout).to match(/\[1, 5, 2, 6, 3, 7, 4, 8\]/) - else - expect(apply_manifest(pp, :catch_failures => true).stdout).to match(/\["1", "5", "2", "6", "3", "7", "4", "8"\]/) - end - end - it 'handles unmatched length' do - # XXX Is this expected behavior? - pp = <<-EOS - $one = [1,2] - $two = [5,6,7,8] - $output = zip($one,$two) - notice(inline_template('<%= @output.inspect %>')) - EOS - if is_future_parser_enabled? - expect(apply_manifest(pp, :catch_failures => true).stdout).to match(/\[\[1, 5\], \[2, 6\]\]/) - else - expect(apply_manifest(pp, :catch_failures => true).stdout).to match(/\[\["1", "5"\], \["2", "6"\]\]/) - end - end - end - describe 'failure' do - it 'handles improper number of arguments' do - pp = <<-EOS - $one = [1,2] - $output = zip($one) - notice(inline_template('<%= @output.inspect %>')) - EOS - - expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/Wrong number of arguments/) - end - it 'handles improper argument types' do - pp = <<-EOS - $one = "a string" - $two = [5,6,7,8] - $output = zip($one,$two) - notice(inline_template('<%= @output.inspect %>')) - EOS - - expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/Requires array/) - end - end -end diff --git a/spec/classes/manage_spec.rb b/spec/classes/manage_spec.rb new file mode 100644 index 000000000..ce78ec2f0 --- /dev/null +++ b/spec/classes/manage_spec.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'stdlib::manage' do + on_supported_os.each do |os, os_facts| + context "on #{os}" do + let(:facts) { os_facts } + + it { is_expected.to compile } + end + end + + describe 'with resources to create' do + let :pre_condition do + <<-PRECOND + file { '/etc/motd.d' : } + service { 'sshd' : } + PRECOND + end + let :params do + { + 'create_resources' => { + 'file' => { + '/etc/motd.d/hello' => { + 'content' => 'I say Hi', + 'notify' => 'Service[sshd]' + }, + '/etc/motd' => { + 'epp' => { + 'template' => 'profile/motd.epp' + } + }, + '/etc/information' => { + 'erb' => { + 'template' => 'profile/information.erb' + } + } + }, + 'package' => { + 'example' => { + 'ensure' => 'installed', + 'subscribe' => ['Service[sshd]', 'File[/etc/motd.d]'] + } + } + } + } + end + + Puppet::Functions.create_function(:epp) do + return 'I am an epp template' + end + Puppet::Functions.create_function(:template) do + return 'I am an erb template' + end + + it { is_expected.to compile } + it { is_expected.to contain_file('/etc/motd.d/hello').with_content('I say Hi').with_notify('Service[sshd]') } + it { is_expected.to contain_file('/etc/motd').with_content(%r{I am an epp template}) } + it { is_expected.to contain_file('/etc/information').with_content(%r{I am an erb template}) } + it { is_expected.to contain_package('example').with_ensure('installed').that_subscribes_to(['Service[sshd]', 'File[/etc/motd.d]']) } + end +end diff --git a/spec/default_facts.yml b/spec/default_facts.yml new file mode 100644 index 000000000..3346c394d --- /dev/null +++ b/spec/default_facts.yml @@ -0,0 +1,9 @@ +# Use default_module_facts.yml for module specific facts. +# +# Facts specified here will override the values provided by rspec-puppet-facts. +--- +networking: + ip: "172.16.254.254" + ip6: "FE80:0000:0000:0000:AAAA:AAAA:AAAA" + mac: "AA:AA:AA:AA:AA:AA" +is_pe: false diff --git a/spec/fixtures/modules/stdlib/lib b/spec/fixtures/modules/stdlib/lib deleted file mode 120000 index b6ce6cc06..000000000 --- a/spec/fixtures/modules/stdlib/lib +++ /dev/null @@ -1 +0,0 @@ -../../../../lib/ \ No newline at end of file diff --git a/spec/fixtures/modules/stdlib/manifests b/spec/fixtures/modules/stdlib/manifests deleted file mode 120000 index cdcdae07c..000000000 --- a/spec/fixtures/modules/stdlib/manifests +++ /dev/null @@ -1 +0,0 @@ -../../../../manifests/ \ No newline at end of file diff --git a/spec/fixtures/test/manifests/base32.pp b/spec/fixtures/test/manifests/base32.pp new file mode 100644 index 000000000..3c01b73bc --- /dev/null +++ b/spec/fixtures/test/manifests/base32.pp @@ -0,0 +1,6 @@ +# Class to test the Stdlib::Base32 type alias +class test::base32 ( + Stdlib::Base32 $value, +) { + notice('Success') +} diff --git a/spec/fixtures/test/manifests/base64.pp b/spec/fixtures/test/manifests/base64.pp new file mode 100644 index 000000000..1870c8225 --- /dev/null +++ b/spec/fixtures/test/manifests/base64.pp @@ -0,0 +1,6 @@ +# Class to test the Stdlib::Base64 type alias +class test::base64 ( + Stdlib::Base64 $value, +) { + notice('Success') +} diff --git a/spec/fixtures/test/manifests/deftype.pp b/spec/fixtures/test/manifests/deftype.pp new file mode 100644 index 000000000..dd58aab86 --- /dev/null +++ b/spec/fixtures/test/manifests/deftype.pp @@ -0,0 +1,4 @@ +# Class to test deftype +define test::deftype ( $param = 'foo' ) { + notify { "deftype: ${title}": } +} diff --git a/spec/fixtures/test/manifests/ensure_resources.pp b/spec/fixtures/test/manifests/ensure_resources.pp new file mode 100644 index 000000000..60e7a40d5 --- /dev/null +++ b/spec/fixtures/test/manifests/ensure_resources.pp @@ -0,0 +1,4 @@ +# A helper class to test the ensure_resources function +class test::ensure_resources ( $resource_type, $title_hash, $attributes_hash ) { + ensure_resources($resource_type, $title_hash, $attributes_hash) +} diff --git a/spec/functions/abs_spec.rb b/spec/functions/abs_spec.rb deleted file mode 100755 index 7d2257b02..000000000 --- a/spec/functions/abs_spec.rb +++ /dev/null @@ -1,30 +0,0 @@ -require 'spec_helper' - -describe 'abs' do - it { is_expected.not_to eq(nil) } - - describe 'signature validation in puppet3', :unless => RSpec.configuration.puppet_future do - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { - pending("Current implementation ignores parameters after the first.") - is_expected.to run.with_params(1, 2).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) - } - end - - describe 'signature validation in puppet4', :if => RSpec.configuration.puppet_future do - it { pending "the puppet 4 implementation"; is_expected.to run.with_params().and_raise_error(ArgumentError) } - it { pending "the puppet 4 implementation"; is_expected.to run.with_params(1, 2).and_raise_error(ArgumentError) } - it { pending "the puppet 4 implementation"; is_expected.to run.with_params([]).and_raise_error(ArgumentError) } - it { pending "the puppet 4 implementation"; is_expected.to run.with_params({}).and_raise_error(ArgumentError) } - it { pending "the puppet 4 implementation"; is_expected.to run.with_params(true).and_raise_error(ArgumentError) } - end - - it { is_expected.to run.with_params(-34).and_return(34) } - it { is_expected.to run.with_params("-34").and_return(34) } - it { is_expected.to run.with_params(34).and_return(34) } - it { is_expected.to run.with_params("34").and_return(34) } - it { is_expected.to run.with_params(-34.5).and_return(34.5) } - it { is_expected.to run.with_params("-34.5").and_return(34.5) } - it { is_expected.to run.with_params(34.5).and_return(34.5) } - it { is_expected.to run.with_params("34.5").and_return(34.5) } -end diff --git a/spec/functions/any2array_spec.rb b/spec/functions/any2array_spec.rb old mode 100755 new mode 100644 index 70121f1e3..679ba9ea0 --- a/spec/functions/any2array_spec.rb +++ b/spec/functions/any2array_spec.rb @@ -1,8 +1,11 @@ +# frozen_string_literal: true + require 'spec_helper' -describe "any2array" do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_return([]) } +describe 'any2array' do + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_return([]) } + it { is_expected.to run.with_params('').and_return([]) } it { is_expected.to run.with_params(true).and_return([true]) } it { is_expected.to run.with_params('one').and_return(['one']) } it { is_expected.to run.with_params('one', 'two').and_return(['one', 'two']) } @@ -10,6 +13,11 @@ it { is_expected.to run.with_params(['one']).and_return(['one']) } it { is_expected.to run.with_params(['one', 'two']).and_return(['one', 'two']) } it { is_expected.to run.with_params({}).and_return([]) } - it { is_expected.to run.with_params({ 'key' => 'value' }).and_return(['key', 'value']) } - it { is_expected.to run.with_params({ 'key' => 'value' }).and_return(['key', 'value']) } + it { is_expected.to run.with_params('key' => 'value').and_return(['key', 'value']) } + + it { is_expected.to run.with_params('‰').and_return(['‰']) } + it { is_expected.to run.with_params('竹').and_return(['竹']) } + it { is_expected.to run.with_params('Ü').and_return(['Ü']) } + it { is_expected.to run.with_params('āˆ‡').and_return(['āˆ‡']) } + it { is_expected.to run.with_params('€', 'äø‡', 'Ɩ', '♄', '割').and_return(['€', 'äø‡', 'Ɩ', '♄', '割']) } end diff --git a/spec/functions/any2bool_spec.rb b/spec/functions/any2bool_spec.rb new file mode 100644 index 000000000..03fb21906 --- /dev/null +++ b/spec/functions/any2bool_spec.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'any2bool' do + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + + it { is_expected.to run.with_params(true).and_return(true) } + it { is_expected.to run.with_params(false).and_return(false) } + + it { is_expected.to run.with_params('1.5').and_return(true) } + + describe 'when testing stringy values that mean "true"' do + ['TRUE', '1', 't', 'y', 'true', 'yes'].each do |value| + it { is_expected.to run.with_params(value).and_return(true) } + end + end + + describe 'when testing stringy values that mean "false"' do + ['FALSE', '', '0', 'f', 'n', 'false', 'no', 'undef', 'undefined', nil, :undef].each do |value| + it { is_expected.to run.with_params(value).and_return(false) } + end + end + + describe 'when testing numeric values that mean "true"' do + [1, '1', 1.5, '1.5'].each do |value| + it { is_expected.to run.with_params(value).and_return(true) } + end + end + + describe 'when testing numeric that mean "false"' do + [-1, '-1', -1.5, '-1.5', '0', 0].each do |value| + it { is_expected.to run.with_params(value).and_return(false) } + end + end + + describe 'everything else returns true' do + [[], {}, ['1'], [1], { one: 1 }].each do |value| + it { is_expected.to run.with_params(value).and_return(true) } + end + end +end diff --git a/spec/functions/assert_private_spec.rb b/spec/functions/assert_private_spec.rb old mode 100755 new mode 100644 index 98f2598ea..8edfe4158 --- a/spec/functions/assert_private_spec.rb +++ b/spec/functions/assert_private_spec.rb @@ -1,47 +1,40 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'assert_private' do context 'when called from inside module' do - it "should not fail" do - scope.expects(:lookupvar).with('module_name').returns('foo') - scope.expects(:lookupvar).with('caller_module_name').returns('foo') - expect { - subject.call [] - }.not_to raise_error + it 'does not fail' do + expect(scope).to receive(:lookupvar).with('module_name').and_return('foo') + expect(scope).to receive(:lookupvar).with('caller_module_name').and_return('foo') + + expect(subject).to run.with_params end end - context "with an explicit failure message" do - it "prints the failure message on error" do - scope.expects(:lookupvar).with('module_name').returns('foo') - scope.expects(:lookupvar).with('caller_module_name').returns('bar') - expect { - subject.call ['failure message!'] - }.to raise_error Puppet::ParseError, /failure message!/ + context 'when called from private class' do + it 'fails with a class error message' do + expect(scope).to receive(:lookupvar).with('module_name').and_return('foo') + expect(scope).to receive(:lookupvar).with('caller_module_name').and_return('bar') + expect(scope.source).to receive(:name).and_return('foo::baz') + expect(scope.source).to receive(:type).and_return('hostclass') + + expect(subject).to run.with_params.and_raise_error(Puppet::ParseError, %r{Class foo::baz is private}) end - end - context "when called from private class" do - it "should fail with a class error message" do - scope.expects(:lookupvar).with('module_name').returns('foo') - scope.expects(:lookupvar).with('caller_module_name').returns('bar') - scope.source.expects(:name).returns('foo::baz') - scope.source.expects(:type).returns('hostclass') - expect { - subject.call [] - }.to raise_error Puppet::ParseError, /Class foo::baz is private/ + it 'fails with an explicit failure message' do + expect(subject).to run.with_params('failure message!').and_raise_error(Puppet::ParseError, %r{failure message!}) end end - context "when called from private definition" do - it "should fail with a class error message" do - scope.expects(:lookupvar).with('module_name').returns('foo') - scope.expects(:lookupvar).with('caller_module_name').returns('bar') - scope.source.expects(:name).returns('foo::baz') - scope.source.expects(:type).returns('definition') - expect { - subject.call [] - }.to raise_error Puppet::ParseError, /Definition foo::baz is private/ + context 'when called from private definition' do + it 'fails with a class error message' do + expect(scope).to receive(:lookupvar).with('module_name').and_return('foo') + expect(scope).to receive(:lookupvar).with('caller_module_name').and_return('bar') + expect(scope.source).to receive(:name).and_return('foo::baz') + expect(scope.source).to receive(:type).and_return('definition') + + expect(subject).to run.with_params.and_raise_error(Puppet::ParseError, %r{Definition foo::baz is private}) end end end diff --git a/spec/functions/base64_spec.rb b/spec/functions/base64_spec.rb old mode 100755 new mode 100644 index c529e9ed8..111910faf --- a/spec/functions/base64_spec.rb +++ b/spec/functions/base64_spec.rb @@ -1,16 +1,70 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'base64' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params("one").and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params("one", "two", "three").and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params("one", "two").and_raise_error(Puppet::ParseError, /first argument must be one of/) } - it { is_expected.to run.with_params("encode", ["two"]).and_raise_error(Puppet::ParseError, /second argument must be a string/) } - it { is_expected.to run.with_params("encode", 2).and_raise_error(Puppet::ParseError, /second argument must be a string/) } - - it { is_expected.to run.with_params("encode", "thestring").and_return("dGhlc3RyaW5n\n") } - it { is_expected.to run.with_params("encode", "a very long string that will cause the base64 encoder to produce output with multiple lines").and_return("YSB2ZXJ5IGxvbmcgc3RyaW5nIHRoYXQgd2lsbCBjYXVzZSB0aGUgYmFzZTY0\nIGVuY29kZXIgdG8gcHJvZHVjZSBvdXRwdXQgd2l0aCBtdWx0aXBsZSBsaW5l\ncw==\n") } - it { is_expected.to run.with_params("decode", "dGhlc3RyaW5n").and_return("thestring") } - it { is_expected.to run.with_params("decode", "dGhlc3RyaW5n\n").and_return("thestring") } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params('one', 'two').and_raise_error(Puppet::ParseError, %r{first argument must be one of}) } + it { is_expected.to run.with_params('encode', ['two']).and_raise_error(Puppet::ParseError, %r{second argument must be a string}) } + it { is_expected.to run.with_params('encode', 2).and_raise_error(Puppet::ParseError, %r{second argument must be a string}) } + it { is_expected.to run.with_params('encode', 'thestring', 'three').and_raise_error(Puppet::ParseError, %r{third argument must be one of}) } + it { is_expected.to run.with_params('decode', "dGhlc3RyaW5n\n", 'strict').and_raise_error(ArgumentError) } + + it { is_expected.to run.with_params('encode', 'thestring').and_return("dGhlc3RyaW5n\n") } + it { is_expected.to run.with_params('decode', 'dGhlc3RyaW5n').and_return('thestring') } + it { is_expected.to run.with_params('decode', "dGhlc3RyaW5n\n").and_return('thestring') } + + it { is_expected.to run.with_params('encode', 'thestring', 'default').and_return("dGhlc3RyaW5n\n") } + it { is_expected.to run.with_params('decode', 'dGhlc3RyaW5n', 'default').and_return('thestring') } + it { is_expected.to run.with_params('decode', "dGhlc3RyaW5n\n", 'default').and_return('thestring') } + + it { is_expected.to run.with_params('encode', 'thestring', 'strict').and_return('dGhlc3RyaW5n') } + it { is_expected.to run.with_params('decode', 'dGhlc3RyaW5n', 'strict').and_return('thestring') } + + it { + expect(subject).to run.with_params('encode', 'a very long string that will cause the base64 encoder to produce output with multiple lines') + .and_return("YSB2ZXJ5IGxvbmcgc3RyaW5nIHRoYXQgd2lsbCBjYXVzZSB0aGUgYmFzZTY0\nIGVuY29kZXIgdG8gcHJvZHVjZSBvdXRwdXQgd2l0aCBtdWx0aXBsZSBsaW5l\ncw==\n") + } + + it { + expect(subject).to run.with_params('decode', "YSB2ZXJ5IGxvbmcgc3RyaW5nIHRoYXQgd2lsbCBjYXVzZSB0aGUgYmFzZTY0\nIGVuY29kZXIgdG8gcHJvZHVjZSBvdXRwdXQgd2l0aCBtdWx0aXBsZSBsaW5l\ncw==\n") + .and_return('a very long string that will cause the base64 encoder to produce output with multiple lines') + } + + it { + expect(subject).to run.with_params('decode', 'YSB2ZXJ5IGxvbmcgc3RyaW5nIHRoYXQgd2lsbCBjYXVzZSB0aGUgYmFzZTY0IGVuY29kZXIgdG8gcHJvZHVjZSBvdXRwdXQgd2l0aCBtdWx0aXBsZSBsaW5lcw==') + .and_return('a very long string that will cause the base64 encoder to produce output with multiple lines') + } + + it { + expect(subject).to run.with_params('encode', 'a very long string that will cause the base64 encoder to produce output with multiple lines', 'strict') + .and_return('YSB2ZXJ5IGxvbmcgc3RyaW5nIHRoYXQgd2lsbCBjYXVzZSB0aGUgYmFzZTY0IGVuY29kZXIgdG8gcHJvZHVjZSBvdXRwdXQgd2l0aCBtdWx0aXBsZSBsaW5lcw==') + } + + it { + expect(subject).to run.with_params('decode', 'YSB2ZXJ5IGxvbmcgc3RyaW5nIHRoYXQgd2lsbCBjYXVzZSB0aGUgYmFzZTY0IGVuY29kZXIgdG8gcHJvZHVjZSBvdXRwdXQgd2l0aCBtdWx0aXBsZSBsaW5lcw==', 'strict') + .and_return('a very long string that will cause the base64 encoder to produce output with multiple lines') + } + + it { + expect(subject).to run.with_params('encode', 'https://www.google.com.tw/?gws_rd=ssl#q=hello+world', 'urlsafe') + .and_return('aHR0cHM6Ly93d3cuZ29vZ2xlLmNvbS50dy8_Z3dzX3JkPXNzbCNxPWhlbGxvK3dvcmxk') + } + + it { + expect(subject).to run.with_params('decode', 'aHR0cHM6Ly93d3cuZ29vZ2xlLmNvbS50dy8_Z3dzX3JkPXNzbCNxPWhlbGxvK3dvcmxk', 'urlsafe') + .and_return('https://www.google.com.tw/?gws_rd=ssl#q=hello+world') + } + + it { + expect(subject).to run.with_params('encode', 'https://github.com/puppetlabs/puppetlabs-stdlib/pulls?utf8=%E2%9C%93&q=is%3Apr+is%3Aopen+Add', 'urlsafe') + .and_return('aHR0cHM6Ly9naXRodWIuY29tL3B1cHBldGxhYnMvcHVwcGV0bGFicy1zdGRsaWIvcHVsbHM_dXRmOD0lRTIlOUMlOTMmcT1pcyUzQXByK2lzJTNBb3BlbitBZGQ=') + } + + it { + expect(subject).to run.with_params('decode', 'aHR0cHM6Ly9naXRodWIuY29tL3B1cHBldGxhYnMvcHVwcGV0bGFicy1zdGRsaWIvcHVsbHM_dXRmOD0lRTIlOUMlOTMmcT1pcyUzQXByK2lzJTNBb3BlbitBZGQ=', 'urlsafe') + .and_return('https://github.com/puppetlabs/puppetlabs-stdlib/pulls?utf8=%E2%9C%93&q=is%3Apr+is%3Aopen+Add') + } end diff --git a/spec/functions/basename_spec.rb b/spec/functions/basename_spec.rb old mode 100755 new mode 100644 index 0ea30e7a7..e9934ca13 --- a/spec/functions/basename_spec.rb +++ b/spec/functions/basename_spec.rb @@ -1,13 +1,21 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'basename' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params('one', 'two', 'three').and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params('/path/to/a/file.ext', []).and_raise_error(Puppet::ParseError) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{No arguments given}) } + it { is_expected.to run.with_params('one', 'two', 'three').and_raise_error(Puppet::ParseError, %r{Too many arguments given}) } + it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError, %r{Requires string as first argument}) } + it { is_expected.to run.with_params('/path/to/a/file.ext', []).and_raise_error(Puppet::ParseError, %r{Requires string as second argument}) } it { is_expected.to run.with_params('/path/to/a/file.ext').and_return('file.ext') } it { is_expected.to run.with_params('relative_path/to/a/file.ext').and_return('file.ext') } it { is_expected.to run.with_params('/path/to/a/file.ext', '.ext').and_return('file') } it { is_expected.to run.with_params('relative_path/to/a/file.ext', '.ext').and_return('file') } + it { is_expected.to run.with_params('scheme:///path/to/a/file.ext').and_return('file.ext') } + + context 'with UTF8 and double byte characters' do + it { is_expected.to run.with_params('scheme:///āˆšįŗ”ÄŗÅ±Ä“/竹.ext').and_return('竹.ext') } + it { is_expected.to run.with_params('Ņįŗ½Ī³:/āˆšįŗ”ÄŗÅ±Ä“/竹.愘', '.愘').and_return('竹') } + end end diff --git a/spec/functions/batch_escape_spec.rb b/spec/functions/batch_escape_spec.rb new file mode 100644 index 000000000..623dc92be --- /dev/null +++ b/spec/functions/batch_escape_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'stdlib::batch_escape' do + it { is_expected.not_to be_nil } + + describe 'signature validation' do + it { is_expected.to run.with_params.and_raise_error(ArgumentError, %r{'stdlib::batch_escape' expects 1 argument, got none}) } + it { is_expected.to run.with_params('foo', 'bar').and_raise_error(ArgumentError, %r{'stdlib::batch_escape' expects 1 argument, got 2}) } + end + + describe 'stringification' do + it { is_expected.to run.with_params(10).and_return('"10"') } + it { is_expected.to run.with_params(false).and_return('"false"') } + end + + describe 'escaping' do + it { is_expected.to run.with_params('foo').and_return('"foo"') } + it { is_expected.to run.with_params('foo bar').and_return('"foo bar"') } + + it { + expect(subject).to run.with_params('~`!@#$%^&*()_-=[]\{}|;\':",./<>?') + .and_return('"~`!@#\\$%^&*()_-=[]\\\{}|;\':"",./<>?"') + } + end +end diff --git a/spec/functions/bool2num_spec.rb b/spec/functions/bool2num_spec.rb old mode 100755 new mode 100644 index e5068594b..55e277c0c --- a/spec/functions/bool2num_spec.rb +++ b/spec/functions/bool2num_spec.rb @@ -1,14 +1,20 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'bool2num' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError) } - [ true, 'true', AlsoString.new('true') ].each do |truthy| + [true, 'true', 't', '1', 'y', 'yes', AlsoString.new('true')].each do |truthy| it { is_expected.to run.with_params(truthy).and_return(1) } end - [ false, 'false', AlsoString.new('false') ].each do |falsey| + [false, 'false', 'f', '0', 'n', 'no', AlsoString.new('false')].each do |falsey| it { is_expected.to run.with_params(falsey).and_return(0) } end + + [[], 10, 'invalid', 1.0].each do |falsey| + it { is_expected.to run.with_params(falsey).and_raise_error(Puppet::ParseError) } + end end diff --git a/spec/functions/bool2str_spec.rb b/spec/functions/bool2str_spec.rb old mode 100755 new mode 100644 index 23a754ba4..0e955b964 --- a/spec/functions/bool2str_spec.rb +++ b/spec/functions/bool2str_spec.rb @@ -1,17 +1,19 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'bool2str' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } - [ 'true', 'false', nil, :undef, ''].each do |invalid| + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError) } + + ['true', 'false', nil, :undef, ''].each do |invalid| it { is_expected.to run.with_params(invalid).and_raise_error(Puppet::ParseError) } end it { is_expected.to run.with_params(true, 'yes', 'no', 'maybe').and_raise_error(Puppet::ParseError) } it { is_expected.to run.with_params(true, 'maybe').and_raise_error(Puppet::ParseError) } it { is_expected.to run.with_params(true, 0, 1).and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params(true).and_return("true") } - it { is_expected.to run.with_params(false).and_return("false") } - it { is_expected.to run.with_params(true, 'yes', 'no').and_return("yes") } - it { is_expected.to run.with_params(false, 'yes', 'no').and_return("no") } - + it { is_expected.to run.with_params(true).and_return('true') } + it { is_expected.to run.with_params(false).and_return('false') } + it { is_expected.to run.with_params(true, 'yes', 'no').and_return('yes') } + it { is_expected.to run.with_params(false, 'yes', 'no').and_return('no') } end diff --git a/spec/functions/camelcase_spec.rb b/spec/functions/camelcase_spec.rb deleted file mode 100755 index c78aa62ff..000000000 --- a/spec/functions/camelcase_spec.rb +++ /dev/null @@ -1,17 +0,0 @@ -require 'spec_helper' - -describe 'camelcase' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params(100).and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params("abc").and_return("Abc") } - it { is_expected.to run.with_params("aa_bb_cc").and_return("AaBbCc") } - it { is_expected.to run.with_params("_aa__bb__cc_").and_return("AaBbCc") } - it { is_expected.to run.with_params("100").and_return("100") } - it { is_expected.to run.with_params("1_00").and_return("100") } - it { is_expected.to run.with_params("_").and_return("") } - it { is_expected.to run.with_params("").and_return("") } - it { is_expected.to run.with_params([]).and_return([]) } - it { is_expected.to run.with_params(["abc", "aa_bb_cc"]).and_return(["Abc", "AaBbCc"]) } - it { is_expected.to run.with_params(["abc", 1, "aa_bb_cc"]).and_return(["Abc", 1, "AaBbCc"]) } -end diff --git a/spec/functions/capitalize_spec.rb b/spec/functions/capitalize_spec.rb deleted file mode 100755 index 7ce2e1630..000000000 --- a/spec/functions/capitalize_spec.rb +++ /dev/null @@ -1,15 +0,0 @@ -require 'spec_helper' - -describe 'capitalize' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params(100).and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params("one").and_return("One") } - it { is_expected.to run.with_params("one two").and_return("One two") } - it { is_expected.to run.with_params("ONE TWO").and_return("One two") } - - it { is_expected.to run.with_params(AlsoString.new("one")).and_return("One") } - it { is_expected.to run.with_params([]).and_return([]) } - it { is_expected.to run.with_params(["one", "two"]).and_return(["One", "Two"]) } - it { is_expected.to run.with_params(["one", 1, "two"]).and_return(["One", 1, "Two"]) } -end diff --git a/spec/functions/ceiling_spec.rb b/spec/functions/ceiling_spec.rb deleted file mode 100755 index 567426fd3..000000000 --- a/spec/functions/ceiling_spec.rb +++ /dev/null @@ -1,13 +0,0 @@ -require 'spec_helper' - -describe 'ceiling' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params("foo").and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params(34).and_return(34) } - it { is_expected.to run.with_params(-34).and_return(-34) } - it { is_expected.to run.with_params(33.1).and_return(34) } - it { is_expected.to run.with_params(-33.1).and_return(-33) } -end - diff --git a/spec/functions/chomp_spec.rb b/spec/functions/chomp_spec.rb deleted file mode 100755 index 687874292..000000000 --- a/spec/functions/chomp_spec.rb +++ /dev/null @@ -1,20 +0,0 @@ -require 'spec_helper' - -describe 'chomp' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError) } - it { - pending("Current implementation ignores parameters after the first.") - is_expected.to run.with_params("a", "b").and_raise_error(Puppet::ParseError) - } - it { is_expected.to run.with_params("one").and_return("one") } - it { is_expected.to run.with_params("one\n").and_return("one") } - it { is_expected.to run.with_params("one\n\n").and_return("one\n") } - it { is_expected.to run.with_params(["one\n", "two", "three\n"]).and_return(["one", "two", "three"]) } - - it { is_expected.to run.with_params(AlsoString.new("one")).and_return("one") } - it { is_expected.to run.with_params(AlsoString.new("one\n")).and_return("one") } - it { is_expected.to run.with_params(AlsoString.new("one\n\n")).and_return("one\n") } - it { is_expected.to run.with_params([AlsoString.new("one\n"), AlsoString.new("two"), "three\n"]).and_return(["one", "two", "three"]) } -end diff --git a/spec/functions/chop_spec.rb b/spec/functions/chop_spec.rb deleted file mode 100755 index db7d18b8c..000000000 --- a/spec/functions/chop_spec.rb +++ /dev/null @@ -1,20 +0,0 @@ -require 'spec_helper' - -describe 'chop' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError) } - it { - pending("Current implementation ignores parameters after the first.") - is_expected.to run.with_params("a", "b").and_raise_error(Puppet::ParseError) - } - it { is_expected.to run.with_params("one").and_return("on") } - it { is_expected.to run.with_params("one\n").and_return("one") } - it { is_expected.to run.with_params("one\n\n").and_return("one\n") } - it { is_expected.to run.with_params(["one\n", "two", "three\n"]).and_return(["one", "tw", "three"]) } - - it { is_expected.to run.with_params(AlsoString.new("one")).and_return("on") } - it { is_expected.to run.with_params(AlsoString.new("one\n")).and_return("one") } - it { is_expected.to run.with_params(AlsoString.new("one\n\n")).and_return("one\n") } - it { is_expected.to run.with_params([AlsoString.new("one\n"), AlsoString.new("two"), "three\n"]).and_return(["one", "tw", "three"]) } -end diff --git a/spec/functions/clamp_spec.rb b/spec/functions/clamp_spec.rb new file mode 100644 index 000000000..43c877b7c --- /dev/null +++ b/spec/functions/clamp_spec.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'clamp' do + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(ArgumentError, %r{Wrong number of arguments}) } + it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError, %r{Wrong number of arguments}) } + it { is_expected.to run.with_params(12, 88, 71, 190).and_raise_error(Puppet::ParseError, %r{Wrong number of arguments, need three to clamp}) } + it { is_expected.to run.with_params('12string', 88, 15).and_raise_error(Puppet::ParseError, %r{Required explicit numeric}) } + it { is_expected.to run.with_params(1, 2, 'a' => 55).and_raise_error(Puppet::ParseError, %r{The Hash type is not allowed}) } + + it { is_expected.to run.with_params('24', [575, 187]).and_return(187) } + it { is_expected.to run.with_params([4, 3, '99']).and_return(4) } + it { is_expected.to run.with_params(16, 750, 88).and_return(88) } + it { is_expected.to run.with_params([3, 873], 73).and_return(73) } + it { is_expected.to run.with_params([4], 8, 75).and_return(8) } + it { is_expected.to run.with_params([6], [31], 9911).and_return(31) } +end diff --git a/spec/functions/concat_spec.rb b/spec/functions/concat_spec.rb old mode 100755 new mode 100644 index 1694d5ee5..504259444 --- a/spec/functions/concat_spec.rb +++ b/spec/functions/concat_spec.rb @@ -1,24 +1,30 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'concat' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params([1]).and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params(1, [2]).and_raise_error(Puppet::ParseError) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{Wrong number of arguments}) } + it { is_expected.to run.with_params([1]).and_raise_error(Puppet::ParseError, %r{Wrong number of arguments}) } + it { is_expected.to run.with_params(1, [2]).and_raise_error(Puppet::ParseError, %r{Requires array}) } it { is_expected.to run.with_params([1], [2], [3]).and_return([1, 2, 3]) } - it { is_expected.to run.with_params(['1','2','3'],['4','5','6']).and_return(['1','2','3','4','5','6']) } - it { is_expected.to run.with_params(['1','2','3'],'4').and_return(['1','2','3','4']) } - it { is_expected.to run.with_params(['1','2','3'],[['4','5'],'6']).and_return(['1','2','3',['4','5'],'6']) } - it { is_expected.to run.with_params(['1','2'],['3','4'],['5','6']).and_return(['1','2','3','4','5','6']) } - it { is_expected.to run.with_params(['1','2'],'3','4',['5','6']).and_return(['1','2','3','4','5','6']) } + it { is_expected.to run.with_params(['1', '2', '3'], ['4', '5', '6']).and_return(['1', '2', '3', '4', '5', '6']) } + it { is_expected.to run.with_params(['1', '2', '3'], '4').and_return(['1', '2', '3', '4']) } + it { is_expected.to run.with_params(['1', '2', '3'], [['4', '5'], '6']).and_return(['1', '2', '3', ['4', '5'], '6']) } + it { is_expected.to run.with_params(['1', '2'], ['3', '4'], ['5', '6']).and_return(['1', '2', '3', '4', '5', '6']) } + it { is_expected.to run.with_params(['1', '2'], '3', '4', ['5', '6']).and_return(['1', '2', '3', '4', '5', '6']) } + + context 'with UTF8 and double byte characters' do + it { is_expected.to run.with_params([{ 'a' => 'b' }], 'c' => 'd', 'e' => 'f').and_return([{ 'a' => 'b' }, { 'c' => 'd', 'e' => 'f' }]) } + it { is_expected.to run.with_params(['įŗ„', 'β', 'Ā©'], ['đ', 'ể', 'ę–‡å­—åˆ—']).and_return(['įŗ„', 'β', 'Ā©', 'đ', 'ể', 'ę–‡å­—åˆ—']) } + end - it "should leave the original array intact" do - argument1 = ['1','2','3'] - original1 = argument1.dup - argument2 = ['4','5','6'] - original2 = argument2.dup - result = subject.call([argument1,argument2]) - expect(argument1).to eq(original1) - expect(argument2).to eq(original2) + arguments = [['1', '2', '3'], ['4', '5', '6']] + originals = [arguments[0].dup, arguments[1].dup] + it 'leaves the original array intact' do + _result = subject.execute(arguments[0], arguments[1]) + arguments.each_with_index do |argument, index| + expect(argument).to eq(originals[index]) + end end end diff --git a/spec/functions/convert_base_spec.rb b/spec/functions/convert_base_spec.rb index 8ab228454..3ea7d44e2 100644 --- a/spec/functions/convert_base_spec.rb +++ b/spec/functions/convert_base_spec.rb @@ -1,24 +1,26 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'convert_base' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(ArgumentError) } - it { is_expected.to run.with_params("asdf").and_raise_error(ArgumentError) } - it { is_expected.to run.with_params("asdf","moo","cow").and_raise_error(ArgumentError) } - it { is_expected.to run.with_params(["1"],"2").and_raise_error(Puppet::ParseError, /argument must be either a string or an integer/) } - it { is_expected.to run.with_params("1",["2"]).and_raise_error(Puppet::ParseError, /argument must be either a string or an integer/) } - it { is_expected.to run.with_params("1",1).and_raise_error(Puppet::ParseError, /base must be at least 2 and must not be greater than 36/) } - it { is_expected.to run.with_params("1",37).and_raise_error(Puppet::ParseError, /base must be at least 2 and must not be greater than 36/) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(ArgumentError) } + it { is_expected.to run.with_params('asdf').and_raise_error(ArgumentError) } + it { is_expected.to run.with_params('asdf', 'moo', 'cow').and_raise_error(ArgumentError) } + it { is_expected.to run.with_params(['1'], '2').and_raise_error(Puppet::ParseError, %r{argument must be either a string or an integer}) } + it { is_expected.to run.with_params('1', ['2']).and_raise_error(Puppet::ParseError, %r{argument must be either a string or an integer}) } + it { is_expected.to run.with_params('1', 1).and_raise_error(Puppet::ParseError, %r{base must be at least 2 and must not be greater than 36}) } + it { is_expected.to run.with_params('1', 37).and_raise_error(Puppet::ParseError, %r{base must be at least 2 and must not be greater than 36}) } - it "should raise a ParseError if argument 1 is a string that does not correspond to an integer in base 10" do - is_expected.to run.with_params("ten",6).and_raise_error(Puppet::ParseError, /argument must be an integer or a string corresponding to an integer in base 10/) + it 'raises a ParseError if argument 1 is a string that does not correspond to an integer in base 10' do + expect(subject).to run.with_params('ten', 6).and_raise_error(Puppet::ParseError, %r{argument must be an integer or a string corresponding to an integer in base 10}) end - it "should raise a ParseError if argument 2 is a string and does not correspond to an integer in base 10" do - is_expected.to run.with_params(100,"hex").and_raise_error(Puppet::ParseError, /argument must be an integer or a string corresponding to an integer in base 10/) + it 'raises a ParseError if argument 2 is a string and does not correspond to an integer in base 10' do + expect(subject).to run.with_params(100, 'hex').and_raise_error(Puppet::ParseError, %r{argument must be an integer or a string corresponding to an integer in base 10}) end - it { is_expected.to run.with_params("11",'16').and_return('b') } - it { is_expected.to run.with_params("35",'36').and_return('z') } + it { is_expected.to run.with_params('11', '16').and_return('b') } + it { is_expected.to run.with_params('35', '36').and_return('z') } it { is_expected.to run.with_params(5, 2).and_return('101') } end diff --git a/spec/functions/count_spec.rb b/spec/functions/count_spec.rb old mode 100755 new mode 100644 index c8d19601c..2ce409633 --- a/spec/functions/count_spec.rb +++ b/spec/functions/count_spec.rb @@ -1,18 +1,27 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'count' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(ArgumentError) } - it { is_expected.to run.with_params("one").and_raise_error(ArgumentError) } - it { is_expected.to run.with_params("one", "two").and_return(1) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(ArgumentError) } + it { is_expected.to run.with_params('one').and_raise_error(ArgumentError) } + it { is_expected.to run.with_params('one', 'two').and_return(1) } + it { - pending("should actually be like this, and not like above") - is_expected.to run.with_params("one", "two").and_raise_error(ArgumentError) + pending('should actually be like this, and not like above') + expect(subject).to run.with_params('one', 'two').and_raise_error(ArgumentError) } - it { is_expected.to run.with_params("one", "two", "three").and_raise_error(ArgumentError) } - it { is_expected.to run.with_params(["one", "two", "three"]).and_return(3) } - it { is_expected.to run.with_params(["one", "two", "two"], "two").and_return(2) } - it { is_expected.to run.with_params(["one", nil, "two"]).and_return(2) } - it { is_expected.to run.with_params(["one", "", "two"]).and_return(2) } - it { is_expected.to run.with_params(["one", :undef, "two"]).and_return(2) } + + it { is_expected.to run.with_params('one', 'two', 'three').and_raise_error(ArgumentError) } + it { is_expected.to run.with_params(['one', 'two', 'three']).and_return(3) } + it { is_expected.to run.with_params(['one', 'two', 'two'], 'two').and_return(2) } + it { is_expected.to run.with_params(['one', nil, 'two']).and_return(2) } + it { is_expected.to run.with_params(['one', '', 'two']).and_return(2) } + it { is_expected.to run.with_params(['one', :undef, 'two']).and_return(2) } + + it { is_expected.to run.with_params(['ổņ℮', 'ŧщộ', 'three']).and_return(3) } + it { is_expected.to run.with_params(['ổņ℮', 'ŧщộ', 'ŧщộ'], 'ŧщộ').and_return(2) } + it { is_expected.to run.with_params(['ổņ℮', nil, 'ŧщộ']).and_return(2) } + it { is_expected.to run.with_params(['ổņ℮', :undef, 'ŧщộ']).and_return(2) } end diff --git a/spec/functions/crc32_spec.rb b/spec/functions/crc32_spec.rb new file mode 100644 index 000000000..5519b6841 --- /dev/null +++ b/spec/functions/crc32_spec.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'stdlib::crc32' do + context 'when default' do + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(ArgumentError, %r{stdlib::crc32}) } + end + + context 'when testing a simple string' do + it { is_expected.to run.with_params('abc').and_return('352441c2') } + it { is_expected.to run.with_params('acb').and_return('5b384015') } + it { is_expected.to run.with_params('my string').and_return('18fbd270') } + it { is_expected.to run.with_params('0').and_return('f4dbdf21') } + end + + context 'when testing a sensitive string' do + it { is_expected.to run.with_params(sensitive('my string')).and_return('18fbd270') } + end + + context 'when testing an integer' do + it { is_expected.to run.with_params(0).and_return('f4dbdf21') } + it { is_expected.to run.with_params(100).and_return('237750ea') } + it { is_expected.to run.with_params(sensitive(100)).and_return('237750ea') } + end + + context 'when testing a float' do + it { is_expected.to run.with_params(200.3).and_return('7d5469f0') } + + # .0 isn't always converted into an integer, but should have rational truncation + it { is_expected.to run.with_params(100.0).and_return('a3fd429a') } + it { is_expected.to run.with_params(sensitive(100.0000)).and_return('a3fd429a') } + end + + context 'when testing a bool' do + it { is_expected.to run.with_params(true).and_return('fdfc4c8d') } + it { is_expected.to run.with_params(false).and_return('2bcd6830') } + end + + context 'when testing a binary' do + it { is_expected.to run.with_params("\xFE\xED\xBE\xEF").and_return('ac3481a4') } + end +end diff --git a/spec/functions/deep_merge_spec.rb b/spec/functions/deep_merge_spec.rb old mode 100755 new mode 100644 index 397e048ce..07291f8a1 --- a/spec/functions/deep_merge_spec.rb +++ b/spec/functions/deep_merge_spec.rb @@ -1,55 +1,63 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'deep_merge' do - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params({ 'key' => 'value' }).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params({}, '2').and_raise_error(Puppet::ParseError, /unexpected argument type String/) } - it { is_expected.to run.with_params({}, 2).and_raise_error(Puppet::ParseError, /unexpected argument type Fixnum/) } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params('key' => 'value').and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params({}, '2').and_raise_error(Puppet::ParseError, %r{unexpected argument type String}) } + it { is_expected.to run.with_params({}, 2).and_raise_error(Puppet::ParseError, %r{unexpected argument}) } it { is_expected.to run.with_params({}, '').and_return({}) } it { is_expected.to run.with_params({}, {}).and_return({}) } it { is_expected.to run.with_params({}, {}, {}).and_return({}) } it { is_expected.to run.with_params({}, {}, {}, {}).and_return({}) } - it { is_expected.to run.with_params({'key' => 'value'}, '').and_return({'key' => 'value'}) } - it { is_expected.to run.with_params({'key1' => 'value1'}, {'key2' => 'value2' }).and_return({'key1' => 'value1', 'key2' => 'value2'}) } + it { is_expected.to run.with_params({ 'key' => 'value' }, '').and_return('key' => 'value') } + it { is_expected.to run.with_params({ 'key1' => 'value1' }, 'key2' => 'value2').and_return('key1' => 'value1', 'key2' => 'value2') } describe 'when arguments have key collisions' do - it 'should prefer values from the last hash' do - is_expected.to run \ - .with_params( - {'key1' => 'value1', 'key2' => 'value2' }, - {'key2' => 'replacement_value', 'key3' => 'value3'}) \ - .and_return( - {'key1' => 'value1', 'key2' => 'replacement_value', 'key3' => 'value3'}) + it 'prefers values from the last hash' do + expect(subject).to run \ + .with_params({ 'key1' => 'value1', 'key2' => 'value2' }, 'key2' => 'replacement_value', 'key3' => 'value3') \ + .and_return('key1' => 'value1', 'key2' => 'replacement_value', 'key3' => 'value3') end - it { is_expected.to run \ - .with_params({'key1' => 'value1'}, {'key1' => 'value2'}, {'key1' => 'value3'}) \ - .and_return({'key1' => 'value3' }) + + it { + expect(subject).to run \ + .with_params({ 'key1' => 'value1' }, { 'key1' => 'value2' }, 'key1' => 'value3') \ + .and_return('key1' => 'value3') } end describe 'when arguments have subhashes' do - it { is_expected.to run \ - .with_params({'key1' => 'value1'}, {'key2' => 'value2', 'key3' => {'subkey1' => 'value4'}}) \ - .and_return( {'key1' => 'value1', 'key2' => 'value2', 'key3' => {'subkey1' => 'value4'}}) + it { + expect(subject).to run \ + .with_params({ 'key1' => 'value1' }, 'key2' => 'value2', 'key3' => { 'subkey1' => 'value4' }) \ + .and_return('key1' => 'value1', 'key2' => 'value2', 'key3' => { 'subkey1' => 'value4' }) } - it { is_expected.to run \ - .with_params({'key1' => {'subkey1' => 'value1'}}, {'key1' => {'subkey2' => 'value2'}}) \ - .and_return( {'key1' => {'subkey1' => 'value1', 'subkey2' => 'value2'}}) + + it { + expect(subject).to run \ + .with_params({ 'key1' => { 'subkey1' => 'value1' } }, 'key1' => { 'subkey2' => 'value2' }) \ + .and_return('key1' => { 'subkey1' => 'value1', 'subkey2' => 'value2' }) } - it { is_expected.to run \ - .with_params({'key1' => {'subkey1' => {'subsubkey1' => 'value1'}}}, {'key1' => {'subkey1' => {'subsubkey1' => 'value2'}}}) \ - .and_return( {'key1' => {'subkey1' => {'subsubkey1' => 'value2'}}}) + + it { + expect(subject).to run \ + .with_params({ 'key1' => { 'subkey1' => { 'subsubkey1' => 'value1' } } }, 'key1' => { 'subkey1' => { 'subsubkey1' => 'value2' } }) \ + .and_return('key1' => { 'subkey1' => { 'subsubkey1' => 'value2' } }) } end - it 'should not change the original hashes' do - argument1 = { 'key1' => 'value1' } - original1 = argument1.dup - argument2 = { 'key2' => 'value2' } - original2 = argument2.dup + arguments = { 'key1' => 'value1' }, { 'key2' => 'value2' } + originals = [arguments[0].dup, arguments[1].dup] + it 'does not change the original hashes' do + subject.execute(arguments[0], arguments[1]) + arguments.each_with_index do |argument, index| + expect(argument).to eq(originals[index]) + end + end - subject.call([argument1, argument2]) - expect(argument1).to eq(original1) - expect(argument2).to eq(original2) + context 'with UTF8 and double byte characters' do + it { is_expected.to run.with_params({ 'ĸέỹ1' => 'ϋǻļủë1' }, 'ć“ć®ę–‡å­—åˆ—' => 'äø‡').and_return('ĸέỹ1' => 'ϋǻļủë1', 'ć“ć®ę–‡å­—åˆ—' => 'äø‡') } end end diff --git a/spec/functions/defined_with_params_spec.rb b/spec/functions/defined_with_params_spec.rb old mode 100755 new mode 100644 index 516d986db..6997ba9b9 --- a/spec/functions/defined_with_params_spec.rb +++ b/spec/functions/defined_with_params_spec.rb @@ -1,26 +1,134 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'defined_with_params' do describe 'when no resource is specified' do - it { is_expected.to run.with_params().and_raise_error(ArgumentError) } + it { is_expected.to run.with_params.and_raise_error(ArgumentError) } end + describe 'when compared against a resource with no attributes' do let :pre_condition do 'user { "dan": }' end + it { is_expected.to run.with_params('User[dan]', {}).and_return(true) } it { is_expected.to run.with_params('User[bob]', {}).and_return(false) } - it { is_expected.to run.with_params('User[dan]', {'foo' => 'bar'}).and_return(false) } + it { is_expected.to run.with_params('User[dan]', 'foo' => 'bar').and_return(false) } + + context 'with UTF8 and double byte characters' do + it { is_expected.to run.with_params('User[ÄµÄ­Š¼įƒŅÆ]', {}).and_return(false) } + it { is_expected.to run.with_params('User[ćƒćƒ¼ćƒ©]', {}).and_return(false) } + end end describe 'when compared against a resource with attributes' do let :pre_condition do 'user { "dan": ensure => present, shell => "/bin/csh", managehome => false}' end + it { is_expected.to run.with_params('User[dan]', {}).and_return(true) } it { is_expected.to run.with_params('User[dan]', '').and_return(true) } - it { is_expected.to run.with_params('User[dan]', {'ensure' => 'present'}).and_return(true) } - it { is_expected.to run.with_params('User[dan]', {'ensure' => 'present', 'managehome' => false}).and_return(true) } - it { is_expected.to run.with_params('User[dan]', {'ensure' => 'absent', 'managehome' => false}).and_return(false) } + it { is_expected.to run.with_params('User[dan]', 'ensure' => 'present').and_return(true) } + it { is_expected.to run.with_params('User[dan]', 'ensure' => 'present', 'managehome' => false).and_return(true) } + it { is_expected.to run.with_params('User[dan]', 'ensure' => 'absent', 'managehome' => false).and_return(false) } + end + + describe 'when passing undef values' do + let :pre_condition do + 'file { "/tmp/a": ensure => present }' + end + let(:is_puppet_6_or_greater) { Puppet::Util::Package.versioncmp(Puppet.version, '6.0.0') >= 0 } + let(:undef_value) { is_puppet_6_or_greater ? nil : :undef } # even if :undef would work on 6.0.1, :undef should not be used + + it { is_expected.to run.with_params('File[/tmp/a]', {}).and_return(true) } + it { is_expected.to run.with_params('File[/tmp/a]', 'ensure' => 'present', 'owner' => undef_value).and_return(true) } + end + + describe 'when the reference is a' do + let :pre_condition do + 'user { "dan": }' + end + + context 'with reference' do + it { is_expected.to run.with_params(Puppet::Resource.new('User[dan]'), {}).and_return(true) } + end + + if Puppet::Util::Package.versioncmp(Puppet.version, '4.6.0') >= 0 + context 'with array' do + it 'fails' do + expect { + subject.execute(['User[dan]'], {}) + }.to raise_error(ArgumentError, %r{not understood: 'Array'}) + end + end + end + end + + describe 'when passed a defined type' do + let :pre_condition do + <<-PRECOND + define test::deftype( + Optional $port = undef + ) { } + + test::deftype { "foo": } + test::deftype { "baz": port => 100 } + test::deftype { "adv": port => 200 } + test::deftype { "adv2": port => 200 } + + # Unsure how to stub this out below properly + if defined_with_params(Test::Deftype, { 'port' => 200 }) { + notify { 'Duplicate found somewhere': } + } + if defined_with_params(Test::Deftype, { 'port' => 'nope' }) { + notify { 'Should not find me': } + } + PRECOND + end + + it { is_expected.to run.with_params('Test::Deftype[foo]', {}).and_return(true) } + it { is_expected.to run.with_params('Test::Deftype[bar]', {}).and_return(false) } + it { is_expected.to run.with_params(Puppet::Resource.new('Test::Deftype[foo]'), {}).and_return(true) } + + it { + expect(subject).to run.with_params(Puppet::Resource.new('Test::Deftype[bar]'), {}).and_return(false) + + expect(catalogue.resource('Notify[Duplicate found somewhere]')).not_to be_nil + expect(catalogue.resource('Notify[Should not find me]')).to be_nil + } + end + + describe 'when called from within a defined type looking for a defined type of the same type' do + let :pre_condition do + <<-PRECOND + define test::deftype( + Optional $port = undef + ) { + if defined_with_params(Test::Deftype, { 'port' => $port }) { + fail('Ruh Roh Shaggy') + } + } + + test::deftype { 'foo': } + test::deftype { 'bar': port => 200 } + PRECOND + end + + # Testing to make sure that the internal logic handles this case via the pre_condition + it { is_expected.to run.with_params('NoOp[noop]', {}).and_return(false) } + end + + describe 'when passed a class' do + let :pre_condition do + 'class test () { } class { "test": }' + end + + it { is_expected.to run.with_params('Class[test]', {}).and_return(true) } + it { is_expected.to run.with_params('Class["bar"]', {}).and_return(false) } + it { is_expected.to run.with_params('Class[bar]', {}).and_return(false) } + it { is_expected.to run.with_params(Puppet::Resource.new('class', 'test'), {}).and_return(true) } + it { is_expected.to run.with_params(Puppet::Resource.new('Class["bar"]'), {}).and_return(false) } + it { is_expected.to run.with_params(Puppet::Resource.new('Class[bar]'), {}).and_return(false) } end end diff --git a/spec/functions/delete_at_spec.rb b/spec/functions/delete_at_spec.rb old mode 100755 new mode 100644 index 0e19472ef..dc0a7578e --- a/spec/functions/delete_at_spec.rb +++ b/spec/functions/delete_at_spec.rb @@ -1,28 +1,32 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'delete_at' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params('one', 1).and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params(1, 1).and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params(['one'], 'two').and_raise_error(Puppet::ParseError) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{Wrong number of arguments}) } + it { is_expected.to run.with_params('one', 1).and_raise_error(Puppet::ParseError, %r{Requires array}) } + it { is_expected.to run.with_params(1, 1).and_raise_error(Puppet::ParseError, %r{Requires array}) } + it { is_expected.to run.with_params(['one'], 'two').and_raise_error(Puppet::ParseError, %r{You must provide non-negative numeric}) } + it { - pending("Current implementation ignores parameters after the first two.") - is_expected.to run.with_params(['one'], 0, 1).and_raise_error(Puppet::ParseError) + pending('Current implementation ignores parameters after the first two.') + expect(subject).to run.with_params(['one'], 0, 1).and_raise_error(Puppet::ParseError) } describe 'argument validation' do - it { is_expected.to run.with_params([0, 1, 2], 3).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params([0, 1, 2], 3).and_raise_error(Puppet::ParseError, %r{Given index exceeds size of array}) } end it { is_expected.to run.with_params([0, 1, 2], 1).and_return([0, 2]) } it { is_expected.to run.with_params([0, 1, 2], -1).and_return([0, 1]) } it { is_expected.to run.with_params([0, 1, 2], -4).and_return([0, 1, 2]) } + it { is_expected.to run.with_params(['Ę’į»į»Ÿ', 'βāř', 'ьầż'], 1).and_return(['Ę’į»į»Ÿ', 'ьầż']) } - it "should leave the original array intact" do + it 'leaves the original array intact' do argument = [1, 2, 3] original = argument.dup - result = subject.call([argument,2]) + _result = subject.execute(argument, 2) expect(argument).to eq(original) end end diff --git a/spec/functions/delete_regex_spec.rb b/spec/functions/delete_regex_spec.rb new file mode 100644 index 000000000..6f4d7048f --- /dev/null +++ b/spec/functions/delete_regex_spec.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'delete_regex' do + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{Wrong number of arguments}) } + it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError, %r{Wrong number of arguments}) } + it { is_expected.to run.with_params([], 'two') } + it { is_expected.to run.with_params({}, 'two') } + it { is_expected.to run.with_params([], 'two', 'three').and_raise_error(Puppet::ParseError, %r{Wrong number of arguments}) } + it { is_expected.to run.with_params(1, 'two').and_raise_error(TypeError, %r{First argument must be an Array, Hash, or String}) } + + describe 'deleting from an array' do + it { is_expected.to run.with_params([], '').and_return([]) } + it { is_expected.to run.with_params([], 'two').and_return([]) } + it { is_expected.to run.with_params(['two'], 'two').and_return([]) } + it { is_expected.to run.with_params(['two', 'two'], 'two').and_return([]) } + it { is_expected.to run.with_params(['one', 'two', 'three'], '^t.*').and_return(['one']) } + it { is_expected.to run.with_params(['ab', 'b', 'c', 'b'], 'b').and_return(['ab', 'c']) } + it { is_expected.to run.with_params(['one', 'two', 'three'], 'four').and_return(['one', 'two', 'three']) } + it { is_expected.to run.with_params(['one', 'two', 'three'], 'e').and_return(['one', 'two', 'three']) } + it { is_expected.to run.with_params(['one', 'two', 'three'], 'two').and_return(['one', 'three']) } + it { is_expected.to run.with_params(['two', 'one', 'two', 'three', 'two'], 'two').and_return(['one', 'three']) } + it { is_expected.to run.with_params(['abracadabra'], 'abr').and_return(['abracadabra']) } + it { is_expected.to run.with_params(['abracadabra'], '^.*jimbob.*$').and_return(['abracadabra']) } + end + + describe 'deleting from an array' do + it { is_expected.to run.with_params({}, '').and_return({}) } + it { is_expected.to run.with_params({}, 'key').and_return({}) } + it { is_expected.to run.with_params({ 'key' => 'value' }, 'key').and_return({}) } + + it { + expect(subject).to run \ + .with_params({ 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3' }, 'key2') \ + .and_return('key1' => 'value1', 'key3' => 'value3') + } + + it { + expect(subject).to run \ + .with_params({ 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3' }, ['key1', 'key2']) \ + .and_return('key3' => 'value3') + } + end + + it 'leaves the original array intact' do + argument1 = ['one', 'two', 'three'] + original1 = argument1.dup + subject.execute(argument1, 'two') + expect(argument1).to eq(original1) + end + + it 'leaves the original hash intact' do + argument1 = { 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3' } + original1 = argument1.dup + subject.execute(argument1, 'key2') + expect(argument1).to eq(original1) + end +end diff --git a/spec/functions/delete_spec.rb b/spec/functions/delete_spec.rb old mode 100755 new mode 100644 index 6c4747bbd..37fee322b --- a/spec/functions/delete_spec.rb +++ b/spec/functions/delete_spec.rb @@ -1,21 +1,27 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'delete' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params([], 'two', 'three').and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params(1, 'two').and_raise_error(TypeError) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{Wrong number of arguments}) } + it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError, %r{Wrong number of arguments}) } + it { is_expected.to run.with_params([], 'two') } + it { is_expected.to run.with_params([], 'two', 'three').and_raise_error(Puppet::ParseError, %r{Wrong number of arguments}) } + it { is_expected.to run.with_params(1, 'two').and_raise_error(TypeError, %r{First argument must be an Array, String, or Hash}) } describe 'deleting from an array' do it { is_expected.to run.with_params([], '').and_return([]) } it { is_expected.to run.with_params([], 'two').and_return([]) } it { is_expected.to run.with_params(['two'], 'two').and_return([]) } it { is_expected.to run.with_params(['two', 'two'], 'two').and_return([]) } + it { is_expected.to run.with_params(['ab', 'b', 'c', 'b'], 'b').and_return(['ab', 'c']) } it { is_expected.to run.with_params(['one', 'two', 'three'], 'four').and_return(['one', 'two', 'three']) } + it { is_expected.to run.with_params(['one', 'two', 'three'], 'e').and_return(['one', 'two', 'three']) } it { is_expected.to run.with_params(['one', 'two', 'three'], 'two').and_return(['one', 'three']) } it { is_expected.to run.with_params(['two', 'one', 'two', 'three', 'two'], 'two').and_return(['one', 'three']) } it { is_expected.to run.with_params(['one', 'two', 'three', 'two'], ['one', 'two']).and_return(['three']) } + it { is_expected.to run.with_params(['ồאּẻ', 'ŧẅƔ', 'ŧңŗё℮', 'ŧẅƔ'], ['ồאּẻ', 'ŧẅƔ']).and_return(['ŧңŗё℮']) } end describe 'deleting from a string' do @@ -27,7 +33,8 @@ it { is_expected.to run.with_params('barfoobar', 'bar').and_return('foo') } it { is_expected.to run.with_params('foobarbabarz', 'bar').and_return('foobaz') } it { is_expected.to run.with_params('foobarbabarz', ['foo', 'bar']).and_return('baz') } - # this is so sick + it { is_expected.to run.with_params('Ę’ÅÅĪ²įŗ­ŃĪ²įŗ­Ī²įŗ­ŃÅŗ', ['Ę’ÅÅ', 'Ī²įŗ­Ń']).and_return('βậź') } + it { is_expected.to run.with_params('barfoobar', ['barbar', 'foo']).and_return('barbar') } it { is_expected.to run.with_params('barfoobar', ['foo', 'barbar']).and_return('') } end @@ -35,33 +42,45 @@ describe 'deleting from an array' do it { is_expected.to run.with_params({}, '').and_return({}) } it { is_expected.to run.with_params({}, 'key').and_return({}) } - it { is_expected.to run.with_params({'key' => 'value'}, 'key').and_return({}) } - it { is_expected.to run \ - .with_params({'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3'}, 'key2') \ - .and_return( {'key1' => 'value1', 'key3' => 'value3'}) + it { is_expected.to run.with_params({ 'key' => 'value' }, 'key').and_return({}) } + + it { + expect(subject).to run \ + .with_params({ 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3' }, 'key2') \ + .and_return('key1' => 'value1', 'key3' => 'value3') + } + + it { + expect(subject).to run \ + .with_params({ 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3' }, ['key1', 'key2']) \ + .and_return('key3' => 'value3') } - it { is_expected.to run \ - .with_params({'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3'}, ['key1', 'key2']) \ - .and_return( {'key3' => 'value3'}) + + it { + expect(subject).to run \ + .with_params({ 'ĸəұ1' => 'νãŀủĕ1', 'ĸəұ2' => 'νãŀủĕ2', 'ĸəұ3' => 'νãŀủĕ3' }, ['ĸəұ1', 'ĸəұ2']) \ + .and_return('ĸəұ3' => 'νãŀủĕ3') } end - it "should leave the original array intact" do - argument1 = ['one','two','three'] + it 'leaves the original array intact' do + argument1 = ['one', 'two', 'three'] original1 = argument1.dup - result = subject.call([argument1,'two']) + _result = subject.execute(argument1, 'two') expect(argument1).to eq(original1) end - it "should leave the original string intact" do + + it 'leaves the original string intact' do argument1 = 'onetwothree' original1 = argument1.dup - result = subject.call([argument1,'two']) + _result = subject.execute(argument1, 'two') expect(argument1).to eq(original1) end - it "should leave the original hash intact" do - argument1 = {'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3'} + + it 'leaves the original hash intact' do + argument1 = { 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3' } original1 = argument1.dup - result = subject.call([argument1,'key2']) + _result = subject.execute(argument1, 'key2') expect(argument1).to eq(original1) end end diff --git a/spec/functions/delete_undef_values_spec.rb b/spec/functions/delete_undef_values_spec.rb old mode 100755 new mode 100644 index ec9fb9c23..4a251cdc2 --- a/spec/functions/delete_undef_values_spec.rb +++ b/spec/functions/delete_undef_values_spec.rb @@ -1,27 +1,34 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'delete_undef_values' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params('one', 'two').and_raise_error(Puppet::ParseError) } + let(:is_puppet_6) { Puppet::Util::Package.versioncmp(Puppet.version, '6.0.0') == 0 } + + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{Wrong number of arguments}) } + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, %r{expected an array or hash}) } + it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, %r{expected an array or hash}) } + it { is_expected.to run.with_params('one', 'two').and_raise_error(Puppet::ParseError, %r{expected an array or hash}) } describe 'when deleting from an array' do - [ :undef, '', nil ].each do |undef_value| + # Behavior is different in Puppet 6.0.0, and fixed in PUP-9180 in Puppet 6.0.1 + [:undef, '', nil].each do |undef_value| describe "when undef is represented by #{undef_value.inspect}" do - before do + before(:each) do pending("review behaviour when being passed undef as #{undef_value.inspect}") if undef_value == '' - pending("review behaviour when being passed undef as #{undef_value.inspect}") if undef_value == nil + pending("review behaviour when being passed undef as #{undef_value.inspect}") if undef_value == :undef && is_puppet_6 end + it { is_expected.to run.with_params([undef_value]).and_return([]) } - it { is_expected.to run.with_params(['one',undef_value,'two','three']).and_return(['one','two','three']) } + it { is_expected.to run.with_params(['one', undef_value, 'two', 'three']).and_return(['one', 'two', 'three']) } + it { is_expected.to run.with_params(['ớņέ', undef_value, 'ŧשּׁō', 'ŧħґëə']).and_return(['ớņέ', 'ŧשּׁō', 'ŧħґëə']) } end - it "should leave the original argument intact" do - argument = ['one',undef_value,'two'] + it 'leaves the original argument intact' do + argument = ['one', undef_value, 'two'] original = argument.dup - result = subject.call([argument,2]) + _result = subject.execute(argument, 2) expect(argument).to eq(original) end end @@ -30,27 +37,30 @@ end describe 'when deleting from a hash' do - [ :undef, '', nil ].each do |undef_value| + [:undef, '', nil].each do |undef_value| describe "when undef is represented by #{undef_value.inspect}" do - before do + before(:each) do pending("review behaviour when being passed undef as #{undef_value.inspect}") if undef_value == '' - pending("review behaviour when being passed undef as #{undef_value.inspect}") if undef_value == nil + pending("review behaviour when being passed undef as #{undef_value.inspect}") if undef_value == :undef && is_puppet_6 end - it { is_expected.to run.with_params({'key' => undef_value}).and_return({}) } - it { is_expected.to run \ - .with_params({'key1' => 'value1', 'undef_key' => undef_value, 'key2' => 'value2'}) \ - .and_return({'key1' => 'value1', 'key2' => 'value2'}) + + it { is_expected.to run.with_params('key' => undef_value).and_return({}) } + + it { + expect(subject).to run \ + .with_params('key1' => 'value1', 'undef_key' => undef_value, 'key2' => 'value2') \ + .and_return('key1' => 'value1', 'key2' => 'value2') } end - it "should leave the original argument intact" do + it 'leaves the original argument intact' do argument = { 'key1' => 'value1', 'key2' => undef_value } original = argument.dup - result = subject.call([argument,2]) + _result = subject.execute(argument, 2) expect(argument).to eq(original) end end - it { is_expected.to run.with_params({'key' => 'undef'}).and_return({'key' => 'undef'}) } + it { is_expected.to run.with_params('key' => 'undef').and_return('key' => 'undef') } end end diff --git a/spec/functions/delete_values_spec.rb b/spec/functions/delete_values_spec.rb old mode 100755 new mode 100644 index 12907d4b7..df1752ec5 --- a/spec/functions/delete_values_spec.rb +++ b/spec/functions/delete_values_spec.rb @@ -1,37 +1,52 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'delete_values' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params('one', 'two', 'three').and_raise_error(Puppet::ParseError) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{Wrong number of arguments}) } + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, %r{Wrong number of arguments}) } + it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, %r{Wrong number of arguments}) } + it { is_expected.to run.with_params('one', 'two', 'three').and_raise_error(Puppet::ParseError, %r{Wrong number of arguments}) } + describe 'when the first argument is not a hash' do - it { is_expected.to run.with_params(1, 'two').and_raise_error(TypeError) } - it { is_expected.to run.with_params('one', 'two').and_raise_error(TypeError) } - it { is_expected.to run.with_params([], 'two').and_raise_error(TypeError) } + it { is_expected.to run.with_params(1, 'two').and_raise_error(TypeError, %r{First argument must be a Hash}) } + it { is_expected.to run.with_params('one', 'two').and_raise_error(TypeError, %r{First argument must be a Hash}) } + it { is_expected.to run.with_params([], 'two').and_raise_error(TypeError, %r{First argument must be a Hash}) } end describe 'when deleting from a hash' do it { is_expected.to run.with_params({}, 'value').and_return({}) } - it { is_expected.to run \ - .with_params({'key1' => 'value1'}, 'non-existing value') \ - .and_return({'key1' => 'value1'}) + + it { + expect(subject).to run \ + .with_params({ 'key1' => 'value1' }, 'non-existing value') \ + .and_return('key1' => 'value1') } - it { is_expected.to run \ - .with_params({'key1' => 'value1', 'key2' => 'value to delete'}, 'value to delete') \ - .and_return({'key1' => 'value1'}) + + it { + expect(subject).to run \ + .with_params({ 'Ņįŗæį»µ1 ' => 'νâĺūẹ1', 'Ņįŗæį»µ2' => 'value to delete' }, 'value to delete') \ + .and_return('Ņįŗæį»µ1 ' => 'νâĺūẹ1') } - it { is_expected.to run \ - .with_params({'key1' => 'value1', 'key2' => 'value to delete', 'key3' => 'value to delete'}, 'value to delete') \ - .and_return({'key1' => 'value1'}) + + it { + expect(subject).to run \ + .with_params({ 'key1' => 'value1', 'key2' => 'Ī½ĒŽÅ€į»Æā„® ńớ Ä‘ĆŖÅ‚į»ƒÅ„Ä—' }, 'Ī½ĒŽÅ€į»Æā„® ńớ Ä‘ĆŖÅ‚į»ƒÅ„Ä—') \ + .and_return('key1' => 'value1') + } + + it { + expect(subject).to run \ + .with_params({ 'key1' => 'value1', 'key2' => 'value to delete', 'key3' => 'value to delete' }, 'value to delete') \ + .and_return('key1' => 'value1') } end - it "should leave the original argument intact" do + it 'leaves the original argument intact' do argument = { 'key1' => 'value1', 'key2' => 'value2' } original = argument.dup - result = subject.call([argument, 'value2']) + _result = subject.execute(argument, 'value2') expect(argument).to eq(original) end end diff --git a/spec/functions/deprecation_spec.rb b/spec/functions/deprecation_spec.rb new file mode 100644 index 000000000..e0b66a7bb --- /dev/null +++ b/spec/functions/deprecation_spec.rb @@ -0,0 +1,76 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'deprecation' do + before(:each) do + # this is to reset the strict variable to default + Puppet.settings[:strict] = :warning + end + + after(:each) do + # this is to reset the strict variable to default + Puppet.settings[:strict] = :warning + end + + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(ArgumentError) } + + it 'displays a single warning' do + if Puppet::Util::Package.versioncmp(Puppet.version, '5.0.0') >= 0 && Puppet::Util::Package.versioncmp(Puppet.version, '5.5.7') < 0 + expect(Puppet).to receive(:deprecation_warning).with('heelo at :', 'key') + expect(Puppet).to receive(:deprecation_warning).with("Modifying 'autosign' as a setting is deprecated.") + else + expect(Puppet).to receive(:warning).with(include('heelo')).once + end + expect(subject).to run.with_params('key', 'heelo') + end + + it 'displays a single warning, despite multiple calls' do + if Puppet::Util::Package.versioncmp(Puppet.version, '5.0.0') >= 0 && Puppet::Util::Package.versioncmp(Puppet.version, '5.5.7') < 0 + expect(Puppet).to receive(:deprecation_warning).with('heelo at :', 'key').twice + expect(Puppet).to receive(:deprecation_warning).with("Modifying 'autosign' as a setting is deprecated.") + else + expect(Puppet).to receive(:warning).with(include('heelo')).once + end + 2.times do |_i| + expect(subject).to run.with_params('key', 'heelo') + end + end + + it 'fails twice with message, with multiple calls. when strict= :error' do + Puppet.settings[:strict] = :error + expect(Puppet).not_to receive(:warning).with(include('heelo')) + 2.times do |_i| + expect(subject).to run.with_params('key', 'heelo').and_raise_error(RuntimeError, %r{deprecation. key. heelo}) + end + end + + it 'displays nothing, despite multiple calls. strict= :off' do + Puppet.settings[:strict] = :off + expect(Puppet).not_to receive(:warning).with(include('heelo')) + 2.times do |_i| + expect(subject).to run.with_params('key', 'heelo') + end + end + + context 'with `use_strict_setting` `false`' do + let(:params) { ['key', 'heelo', false] } + + context 'and `strict` setting set to `error`' do + it 'displays a warning' do + Puppet.settings[:strict] = :error + expect(Puppet).to receive(:warning).with(include('heelo')).once + expect(subject).to run.with_params(*params) + end + end + + context 'and `strict` setting set to `off`' do + it 'displays a warning' do + Puppet.settings[:strict] = :off + expect(Puppet).to receive(:warning).with(include('heelo')).once + expect(subject).to run.with_params(*params) + end + end + end +end diff --git a/spec/functions/difference_spec.rb b/spec/functions/difference_spec.rb old mode 100755 new mode 100644 index d5e983d8f..a66317567 --- a/spec/functions/difference_spec.rb +++ b/spec/functions/difference_spec.rb @@ -1,21 +1,24 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'difference' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params('one', 'two').and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params('one', 'two', 'three').and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params('one', []).and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params([], 'two').and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params({}, {}).and_raise_error(Puppet::ParseError) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{Wrong number of arguments}) } + it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, %r{Wrong number of arguments}) } + it { is_expected.to run.with_params('one', 'two').and_raise_error(Puppet::ParseError, %r{Requires 2 arrays}) } + it { is_expected.to run.with_params('one', []).and_raise_error(Puppet::ParseError, %r{Requires 2 arrays}) } + it { is_expected.to run.with_params({}, {}).and_raise_error(Puppet::ParseError, %r{Requires 2 arrays}) } + it { is_expected.to run.with_params([], []).and_return([]) } it { is_expected.to run.with_params([], ['one']).and_return([]) } it { is_expected.to run.with_params(['one'], ['one']).and_return([]) } + it { is_expected.to run.with_params(['ớņέ'], ['']).and_return(['ớņέ']) } it { is_expected.to run.with_params(['one'], []).and_return(['one']) } it { is_expected.to run.with_params(['one', 'two', 'three'], ['two', 'three']).and_return(['one']) } + it { is_expected.to run.with_params(['ớņέ', 'ŧשּׁō', 'ŧħґëə', 2], ['ŧשּׁō', 'ŧħґëə']).and_return(['ớņέ', 2]) } it { is_expected.to run.with_params(['one', 'two', 'two', 'three'], ['two', 'three']).and_return(['one']) } it { is_expected.to run.with_params(['one', 'two', 'three'], ['two', 'two', 'three']).and_return(['one']) } it { is_expected.to run.with_params(['one', 'two', 'three'], ['two', 'three', 'four']).and_return(['one']) } - it 'should not confuse types' do is_expected.to run.with_params(['1', '2', '3'], [1, 2]).and_return(['1', '2', '3']) end + it 'does not confuse types' do is_expected.to run.with_params(['1', '2', '3'], [1, 2]).and_return(['1', '2', '3']) end end diff --git a/spec/functions/dirname_spec.rb b/spec/functions/dirname_spec.rb old mode 100755 new mode 100644 index 46c4c35c7..ef8c8a05a --- a/spec/functions/dirname_spec.rb +++ b/spec/functions/dirname_spec.rb @@ -1,13 +1,22 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'dirname' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params('one', 'two').and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params('/path/to/a/file.ext', []).and_raise_error(Puppet::ParseError) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{No arguments given}) } + it { is_expected.to run.with_params('one', 'two').and_raise_error(Puppet::ParseError, %r{Too many arguments given}) } + it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError, %r{Requires string as argument}) } + it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, %r{Requires string as argument}) } + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, %r{Requires string as argument}) } + it { is_expected.to run.with_params('').and_raise_error(Puppet::ParseError, %r{Requires a non-empty string as argument}) } + it { is_expected.to run.with_params(:undef).and_raise_error(Puppet::ParseError, %r{string as argument}) } + it { is_expected.to run.with_params(nil).and_raise_error(Puppet::ParseError, %r{string as argument}) } it { is_expected.to run.with_params('/path/to/a/file.ext').and_return('/path/to/a') } it { is_expected.to run.with_params('relative_path/to/a/file.ext').and_return('relative_path/to/a') } + + context 'with UTF8 and double byte characters' do + it { is_expected.to run.with_params('scheme:///āˆšįŗ”ÄŗÅ±Ä“/竹.ext').and_return('scheme:///āˆšįŗ”ÄŗÅ±Ä“') } + it { is_expected.to run.with_params('Ņįŗ½Ī³:/āˆšįŗ”ÄŗÅ±Ä“/竹.愘').and_return('Ņįŗ½Ī³:/āˆšįŗ”ÄŗÅ±Ä“') } + end end diff --git a/spec/functions/dos2unix_spec.rb b/spec/functions/dos2unix_spec.rb index 9c84703cb..26abe1204 100644 --- a/spec/functions/dos2unix_spec.rb +++ b/spec/functions/dos2unix_spec.rb @@ -1,40 +1,54 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'dos2unix' do - context 'Checking parameter validity' do - it { is_expected.not_to eq(nil) } + context 'when checking parameter validity' do + it { is_expected.not_to be_nil } + it do - is_expected.to run.with_params.and_raise_error(ArgumentError, /Wrong number of arguments/) + expect(subject).to run.with_params.and_raise_error(ArgumentError, %r{Wrong number of arguments}) end + it do - is_expected.to run.with_params('one', 'two').and_raise_error(ArgumentError, /Wrong number of arguments/) + expect(subject).to run.with_params('one', 'two').and_raise_error(ArgumentError, %r{Wrong number of arguments}) end + it do - is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError) + expect(subject).to run.with_params([]).and_raise_error(Puppet::ParseError, %r{Requires string as argument}) end + it do - is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError) + expect(subject).to run.with_params({}).and_raise_error(Puppet::ParseError, %r{Requires string as argument}) end + it do - is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError) + expect(subject).to run.with_params(1).and_raise_error(Puppet::ParseError, %r{Requires string as argument}) end end - context 'Converting from dos to unix format' do + context 'when converting from dos to unix format' do sample_text = "Hello\r\nWorld\r\n" desired_output = "Hello\nWorld\n" - it 'should output unix format' do - should run.with_params(sample_text).and_return(desired_output) + it 'outputs unix format' do + expect(subject).to run.with_params(sample_text).and_return(desired_output) end end - context 'Converting from unix to unix format' do - sample_text = "Hello\nWorld\n" - desired_output = "Hello\nWorld\n" + context 'with internationalization (i18N) values' do + sample_text_utf8 = "Ħ℮ļłǿ\r\nשׁөŕłđ\r\n" + desired_output_utf8 = "Ħ℮ļłǿ\nשׁөŕłđ\n" + + sample_text_doublebyte = "こんにごは\r\näø–ē•Œ\r\n" + desired_output_doublebyte = "こんにごは\näø–ē•Œ\n" + + it 'outputs uft8 string' do + expect(subject).to run.with_params(sample_text_utf8).and_return(desired_output_utf8) + end - it 'should output unix format' do - should run.with_params(sample_text).and_return(desired_output) + it 'outputs double byte string' do + expect(subject).to run.with_params(sample_text_doublebyte).and_return(desired_output_doublebyte) end end end diff --git a/spec/functions/downcase_spec.rb b/spec/functions/downcase_spec.rb deleted file mode 100755 index c594560a0..000000000 --- a/spec/functions/downcase_spec.rb +++ /dev/null @@ -1,15 +0,0 @@ -require 'spec_helper' - -describe 'downcase' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params(100).and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params("abc").and_return("abc") } - it { is_expected.to run.with_params("Abc").and_return("abc") } - it { is_expected.to run.with_params("ABC").and_return("abc") } - - it { is_expected.to run.with_params(AlsoString.new("ABC")).and_return("abc") } - it { is_expected.to run.with_params([]).and_return([]) } - it { is_expected.to run.with_params(["ONE", "TWO"]).and_return(["one", "two"]) } - it { is_expected.to run.with_params(["One", 1, "Two"]).and_return(["one", 1, "two"]) } -end diff --git a/spec/functions/empty_spec.rb b/spec/functions/empty_spec.rb deleted file mode 100755 index a3a25d6a0..000000000 --- a/spec/functions/empty_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -require 'spec_helper' - -describe 'empty' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } - it { - pending("Current implementation ignores parameters after the first.") - is_expected.to run.with_params('one', 'two').and_raise_error(Puppet::ParseError) - } - it { is_expected.to run.with_params(0).and_return(false) } - it { is_expected.to run.with_params('').and_return(true) } - it { is_expected.to run.with_params('one').and_return(false) } - - it { is_expected.to run.with_params(AlsoString.new('')).and_return(true) } - it { is_expected.to run.with_params(AlsoString.new('one')).and_return(false) } - - it { is_expected.to run.with_params([]).and_return(true) } - it { is_expected.to run.with_params(['one']).and_return(false) } - - it { is_expected.to run.with_params({}).and_return(true) } - it { is_expected.to run.with_params({'key' => 'value'}).and_return(false) } -end diff --git a/spec/functions/end_with_spec.rb b/spec/functions/end_with_spec.rb new file mode 100644 index 000000000..058f9a77a --- /dev/null +++ b/spec/functions/end_with_spec.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'stdlib::end_with' do + it { is_expected.to run.with_params('', 'bar').and_return(false) } + it { is_expected.to run.with_params('foobar', 'bar').and_return(true) } + it { is_expected.to run.with_params('foobar', 'foo').and_return(false) } + it { is_expected.to run.with_params('foobar', ['foo', 'baz']).and_return(false) } + + it do + expect(subject).to run.with_params('foobar', '').and_raise_error( + ArgumentError, %r{'stdlib::end_with' parameter 'suffixes' expects a value of type String\[1\] or Array\[String\[1\], 1\]} + ) + end +end diff --git a/spec/functions/ensure_packages_spec.rb b/spec/functions/ensure_packages_spec.rb old mode 100755 new mode 100644 index c82473299..8a4bc9869 --- a/spec/functions/ensure_packages_spec.rb +++ b/spec/functions/ensure_packages_spec.rb @@ -1,36 +1,95 @@ +# frozen_string_literal: true + require 'spec_helper' -describe 'ensure_packages' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } - it { - pending("should not accept numbers as arguments") - is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError) - } - it { - pending("should not accept numbers as arguments") - is_expected.to run.with_params(["packagename", 1]).and_raise_error(Puppet::ParseError) - } - it { is_expected.to run.with_params("packagename") } - it { is_expected.to run.with_params(["packagename1", "packagename2"]) } - - context 'given a catalog with "package { puppet: ensure => absent }"' do +describe 'stdlib::ensure_packages' do + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params('packagename') } + it { is_expected.to run.with_params(['packagename1', 'packagename2']) } + + context 'when given a catalog with "package { puppet: ensure => absent }"' do let(:pre_condition) { 'package { puppet: ensure => absent }' } describe 'after running ensure_package("facter")' do - before { subject.call(['facter']) } + before(:each) { subject.execute('facter') } # this lambda is required due to strangeness within rspec-puppet's expectation handling - it { expect(lambda { catalogue }).to contain_package('puppet').with_ensure('absent') } - it { expect(lambda { catalogue }).to contain_package('facter').with_ensure('present') } + it { expect(-> { catalogue }).to contain_package('puppet').with_ensure('absent') } + it { expect(-> { catalogue }).to contain_package('facter').with_ensure('installed') } end describe 'after running ensure_package("facter", { "provider" => "gem" })' do - before { subject.call(['facter', { "provider" => "gem" }]) } + before(:each) { subject.execute('facter', 'provider' => 'gem') } # this lambda is required due to strangeness within rspec-puppet's expectation handling - it { expect(lambda { catalogue }).to contain_package('puppet').with_ensure('absent').without_provider() } - it { expect(lambda { catalogue }).to contain_package('facter').with_ensure('present').with_provider("gem") } + it { expect(-> { catalogue }).to contain_package('puppet').with_ensure('absent').without_provider } + it { expect(-> { catalogue }).to contain_package('facter').with_ensure('installed').with_provider('gem') } + end + end + + context 'when given hash of packages' do + before(:each) do + subject.execute({ 'foo' => { 'provider' => 'rpm' }, 'bar' => { 'provider' => 'gem' } }, 'ensure' => 'present') + subject.execute('ćƒ‘ćƒƒć‚±ćƒ¼ć‚ø' => { 'ensure' => 'absent' }) + subject.execute('ρǻ¢κầģẻ' => { 'ensure' => 'absent' }) + subject.execute( + { + 'package_one' => {}, + 'package_two' => {}, + 'package_three' => { 'provider' => 'puppetserver_gem' } + }, + { 'provider' => 'puppet_gem' }, + ) + end + + # this lambda is required due to strangeness within rspec-puppet's expectation handling + it { expect(-> { catalogue }).to contain_package('foo').with('provider' => 'rpm', 'ensure' => 'installed') } + it { expect(-> { catalogue }).to contain_package('bar').with('provider' => 'gem', 'ensure' => 'installed') } + + context 'with UTF8 and double byte characters' do + it { expect(-> { catalogue }).to contain_package('ćƒ‘ćƒƒć‚±ćƒ¼ć‚ø').with('ensure' => 'absent') } + it { expect(-> { catalogue }).to contain_package('ρǻ¢κầģẻ').with('ensure' => 'absent') } + end + + describe 'default attributes' do + it 'package specific attributes take precedence' do + expect(-> { catalogue }).to contain_package('package_one').with('provider' => 'puppet_gem') + expect(-> { catalogue }).to contain_package('package_two').with('provider' => 'puppet_gem') + expect(-> { catalogue }).to contain_package('package_three').with('provider' => 'puppetserver_gem') + end + end + end + + context 'when given a catalog with "package { puppet: ensure => installed }"' do + let(:pre_condition) { 'package { puppet: ensure => installed }' } + + describe 'after running ensure_package("puppet", { "ensure" => "present" })' do + before(:each) { subject.execute('puppet', 'ensure' => 'present') } + + # this lambda is required due to strangeness within rspec-puppet's expectation handling + it { expect(-> { catalogue }).to contain_package('puppet').with_ensure('installed') } + end + end + + context 'when given a catalog with "package { puppet: ensure => present }"' do + let(:pre_condition) { 'package { puppet: ensure => present }' } + + describe 'after running ensure_package("puppet", { "ensure" => "present" })' do + before(:each) { subject.execute('puppet', 'ensure' => 'present') } + + it { expect(-> { catalogue }).to contain_package('puppet').with_ensure('present') } + end + + describe 'after running ensure_package("puppet", { "ensure" => "installed" })' do + before(:each) { subject.execute('puppet', 'ensure' => 'installed') } + + it { expect(-> { catalogue }).to contain_package('puppet').with_ensure('present') } + end + + describe 'after running ensure_package(["puppet"])' do + before(:each) { subject.execute(['puppet']) } + + it { expect(-> { catalogue }).to contain_package('puppet').with_ensure('present') } end end end diff --git a/spec/functions/ensure_resource_spec.rb b/spec/functions/ensure_resource_spec.rb old mode 100755 new mode 100644 index c4f2cbd0e..9b04db6b6 --- a/spec/functions/ensure_resource_spec.rb +++ b/spec/functions/ensure_resource_spec.rb @@ -1,55 +1,152 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'ensure_resource' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(ArgumentError, /Must specify a type/) } - it { is_expected.to run.with_params('type').and_raise_error(ArgumentError, /Must specify a title/) } - it { is_expected.to run.with_params('type', 'title', {}, 'extras').and_raise_error(Puppet::ParseError) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(ArgumentError, %r{Must specify a type}) } + it { is_expected.to run.with_params('type').and_raise_error(ArgumentError, %r{Must specify a title}) } + + if Puppet::Util::Package.versioncmp(Puppet.version, '4.6.0') >= 0 + it { is_expected.to run.with_params('type', 'title', {}, 'extras').and_raise_error(ArgumentError) } + else + it { is_expected.to run.with_params('type', 'title', {}, 'extras').and_raise_error(Puppet::ParseError) } + end + it { - pending("should not accept numbers as arguments") - is_expected.to run.with_params(1,2,3).and_raise_error(Puppet::ParseError) + pending('should not accept numbers as arguments') + expect(subject).to run.with_params(1, 2, 3).and_raise_error(Puppet::ParseError) } - context 'given a catalog with "user { username1: ensure => present }"' do + context 'when given an empty catalog' do + describe 'after running ensure_resource("user", "username1", {})' do + before(:each) { subject.execute('User', 'username1', {}) } + + # this lambda is required due to strangeness within rspec-puppet's expectation handling + it { expect(-> { catalogue }).to contain_user('username1').without_ensure } + end + + describe 'after running ensure_resource("user", "username1", { gid => undef })' do + before(:each) { subject.execute('User', 'username1', 'gid' => undef_value) } + + # this lambda is required due to strangeness within rspec-puppet's expectation handling + it { expect(-> { catalogue }).to contain_user('username1').without_ensure } + it { expect(-> { catalogue }).to contain_user('username1').without_gid } + end + + describe 'after running ensure_resource("user", "username1", { ensure => present, gid => undef })' do + before(:each) { subject.execute('User', 'username1', 'ensure' => 'present', 'gid' => undef_value) } + + # this lambda is required due to strangeness within rspec-puppet's expectation handling + it { expect(-> { catalogue }).to contain_user('username1').with_ensure('present') } + it { expect(-> { catalogue }).to contain_user('username1').without_gid } + end + + describe 'after running ensure_resource("test::deftype", "foo", {})' do + let(:pre_condition) { 'define test::deftype { }' } + + before(:each) { subject.execute('test::deftype', 'foo', {}) } + + # this lambda is required due to strangeness within rspec-puppet's expectation handling + it { expect(-> { catalogue }).to contain_test__deftype('foo').without_ensure } + end + end + + context 'when given a catalog with UTF8 chars' do + describe 'after running ensure_resource("user", "ÅžįŗÆįƒŃ€Å€į»… Ţë×ń", {})' do + before(:each) { subject.execute('User', 'ÅžįŗÆįƒŃ€Å€į»… Ţë×ń', {}) } + + # this lambda is required due to strangeness within rspec-puppet's expectation handling + it { expect(-> { catalogue }).to contain_user('ÅžįŗÆįƒŃ€Å€į»… Ţë×ń').without_ensure } + end + + describe 'after running ensure_resource("user", "ÅžįŗÆįƒŃ€Å€į»… Ţë×ń", { gid => undef })' do + before(:each) { subject.execute('User', 'ÅžįŗÆįƒŃ€Å€į»… Ţë×ń', 'gid' => undef_value) } + + # this lambda is required due to strangeness within rspec-puppet's expectation handling + it { expect(-> { catalogue }).to contain_user('ÅžįŗÆįƒŃ€Å€į»… Ţë×ń').without_ensure } + it { expect(-> { catalogue }).to contain_user('ÅžįŗÆįƒŃ€Å€į»… Ţë×ń').without_gid } + end + + describe 'after running ensure_resource("user", "ÅžįŗÆįƒŃ€Å€į»… Ţë×ń", { ensure => present, gid => undef })' do + before(:each) { subject.execute('User', 'ÅžįŗÆįƒŃ€Å€į»… Ţë×ń', 'ensure' => 'present', 'gid' => undef_value) } + + # this lambda is required due to strangeness within rspec-puppet's expectation handling + it { expect(-> { catalogue }).to contain_user('ÅžįŗÆįƒŃ€Å€į»… Ţë×ń').with_ensure('present') } + it { expect(-> { catalogue }).to contain_user('ÅžįŗÆįƒŃ€Å€į»… Ţë×ń').without_gid } + end + end + + context 'when given a catalog with "user { username1: ensure => present }"' do let(:pre_condition) { 'user { username1: ensure => present }' } describe 'after running ensure_resource("user", "username1", {})' do - before { subject.call(['User', 'username1', {}]) } + before(:each) { subject.execute('User', 'username1', {}) } # this lambda is required due to strangeness within rspec-puppet's expectation handling - it { expect(lambda { catalogue }).to contain_user('username1').with_ensure('present') } + it { expect(-> { catalogue }).to contain_user('username1').with_ensure('present') } end describe 'after running ensure_resource("user", "username2", {})' do - before { subject.call(['User', 'username2', {}]) } + before(:each) { subject.execute('User', 'username2', {}) } # this lambda is required due to strangeness within rspec-puppet's expectation handling - it { expect(lambda { catalogue }).to contain_user('username1').with_ensure('present') } - it { expect(lambda { catalogue }).to contain_user('username2').without_ensure } + it { expect(-> { catalogue }).to contain_user('username1').with_ensure('present') } + it { expect(-> { catalogue }).to contain_user('username2').without_ensure } + end + + describe 'after running ensure_resource("user", "username1", { gid => undef })' do + before(:each) { subject.execute('User', 'username1', 'gid' => undef_value) } + + # this lambda is required due to strangeness within rspec-puppet's expectation handling + it { expect(-> { catalogue }).to contain_user('username1').with_ensure('present') } end describe 'after running ensure_resource("user", ["username1", "username2"], {})' do - before { subject.call(['User', ['username1', 'username2'], {}]) } + before(:each) { subject.execute('User', ['username1', 'username2'], {}) } # this lambda is required due to strangeness within rspec-puppet's expectation handling - it { expect(lambda { catalogue }).to contain_user('username1').with_ensure('present') } - it { expect(lambda { catalogue }).to contain_user('username2').without_ensure } + it { expect(-> { catalogue }).to contain_user('username1').with_ensure('present') } + it { expect(-> { catalogue }).to contain_user('username2').without_ensure } end describe 'when providing already set params' do let(:params) { { 'ensure' => 'present' } } - before { subject.call(['User', ['username2', 'username3'], params]) } + + before(:each) { subject.execute('User', ['username2', 'username3'], params) } # this lambda is required due to strangeness within rspec-puppet's expectation handling - it { expect(lambda { catalogue }).to contain_user('username1').with(params) } - it { expect(lambda { catalogue }).to contain_user('username2').with(params) } + it { expect(-> { catalogue }).to contain_user('username1').with(params) } + it { expect(-> { catalogue }).to contain_user('username2').with(params) } end context 'when trying to add params' do - it { is_expected.to run \ - .with_params('User', 'username1', { 'ensure' => 'present', 'shell' => true }) \ - .and_raise_error(Puppet::Resource::Catalog::DuplicateResourceError, /User\[username1\] is already declared/) + it { + expect(subject).to run \ + .with_params('User', 'username1', 'ensure' => 'present', 'shell' => true) \ + .and_raise_error(Puppet::Resource::Catalog::DuplicateResourceError, %r{User\[username1\] is already declared}) } end end + + context 'when given a catalog with "test::deftype { foo: }"' do + let(:pre_condition) { 'define test::deftype { } test::deftype { "foo": }' } + + describe 'after running ensure_resource("test::deftype", "foo", {})' do + before(:each) { subject.execute('test::deftype', 'foo', {}) } + + # this lambda is required due to strangeness within rspec-puppet's expectation handling + it { expect(-> { catalogue }).to contain_test__deftype('foo').without_ensure } + end + end + + if Puppet::Util::Package.versioncmp(Puppet.version, '6.0.0') < 0 + def undef_value + :undef + end + else + def undef_value + nil + end + end end diff --git a/spec/functions/ensure_resources_spec.rb b/spec/functions/ensure_resources_spec.rb new file mode 100644 index 000000000..cf4de9e48 --- /dev/null +++ b/spec/functions/ensure_resources_spec.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'ensure_resources' do + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(ArgumentError, %r{Must specify a type}) } + it { is_expected.to run.with_params('type').and_raise_error(ArgumentError, %r{Must specify a title}) } + + describe 'given a title hash of multiple resources' do + before(:each) do + subject.execute('user', { 'dan' => { 'gid' => 'mygroup', 'uid' => '600' }, 'alex' => { 'gid' => 'mygroup', 'uid' => '700' } }, 'ensure' => 'present') + end + + # this lambda is required due to strangeness within rspec-puppet's expectation handling + it { expect(-> { catalogue }).to contain_user('dan').with_ensure('present') } + it { expect(-> { catalogue }).to contain_user('alex').with_ensure('present') } + it { expect(-> { catalogue }).to contain_user('dan').with('gid' => 'mygroup', 'uid' => '600') } + it { expect(-> { catalogue }).to contain_user('alex').with('gid' => 'mygroup', 'uid' => '700') } + end + + describe 'given a title hash of a single resource' do + before(:each) { subject.execute('user', { 'dan' => { 'gid' => 'mygroup', 'uid' => '600' } }, 'ensure' => 'present') } + + # this lambda is required due to strangeness within rspec-puppet's expectation handling + it { expect(-> { catalogue }).to contain_user('dan').with_ensure('present') } + it { expect(-> { catalogue }).to contain_user('dan').with('gid' => 'mygroup', 'uid' => '600') } + end +end diff --git a/spec/functions/extname_spec.rb b/spec/functions/extname_spec.rb new file mode 100644 index 000000000..bca462998 --- /dev/null +++ b/spec/functions/extname_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'stdlib::extname' do + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(ArgumentError, %r{'stdlib::extname' expects 1 argument, got none}) } + it { is_expected.to run.with_params('one', 'two').and_raise_error(ArgumentError, %r{'stdlib::extname' expects 1 argument, got 2}) } + it { is_expected.to run.with_params([]).and_raise_error(ArgumentError, %r{'stdlib::extname' parameter 'filename' expects a String value, got Array}) } + it { is_expected.to run.with_params('test.rb').and_return('.rb') } + it { is_expected.to run.with_params('a/b/d/test.rb').and_return('.rb') } + it { is_expected.to run.with_params('test').and_return('') } + it { is_expected.to run.with_params('.profile').and_return('') } + + context 'with UTF8 and double byte characters' do + it { is_expected.to run.with_params('file_āˆšįŗ”ÄŗÅ±Ä“/竹.rb').and_return('.rb') } + end +end diff --git a/spec/functions/flatten_spec.rb b/spec/functions/flatten_spec.rb deleted file mode 100755 index a4338be4d..000000000 --- a/spec/functions/flatten_spec.rb +++ /dev/null @@ -1,14 +0,0 @@ -require 'spec_helper' - -describe 'flatten' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params([], []).and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params([]).and_return([]) } - it { is_expected.to run.with_params(['one']).and_return(['one']) } - it { is_expected.to run.with_params([['one']]).and_return(['one']) } - it { is_expected.to run.with_params(["a","b","c","d","e","f","g"]).and_return(["a","b","c","d","e","f","g"]) } - it { is_expected.to run.with_params([["a","b",["c",["d","e"],"f","g"]]]).and_return(["a","b","c","d","e","f","g"]) } -end diff --git a/spec/functions/floor_spec.rb b/spec/functions/floor_spec.rb deleted file mode 100755 index 608c602fa..000000000 --- a/spec/functions/floor_spec.rb +++ /dev/null @@ -1,12 +0,0 @@ -require 'spec_helper' - -describe 'floor' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params("foo").and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params(34).and_return(34) } - it { is_expected.to run.with_params(-34).and_return(-34) } - it { is_expected.to run.with_params(33.1).and_return(33) } - it { is_expected.to run.with_params(-33.1).and_return(-34) } -end diff --git a/spec/functions/fqdn_rand_string_spec.rb b/spec/functions/fqdn_rand_string_spec.rb index e4070846b..d19b28cbb 100644 --- a/spec/functions/fqdn_rand_string_spec.rb +++ b/spec/functions/fqdn_rand_string_spec.rb @@ -1,65 +1,57 @@ +# frozen_string_literal: true + require 'spec_helper' -describe 'fqdn_rand_string' do +describe 'stdlib::fqdn_rand_string' do let(:default_charset) { %r{\A[a-zA-Z0-9]{100}\z} } - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(ArgumentError, /wrong number of arguments/i) } - it { is_expected.to run.with_params(0).and_raise_error(ArgumentError, /first argument must be a positive integer/) } - it { is_expected.to run.with_params(1.5).and_raise_error(ArgumentError, /first argument must be a positive integer/) } - it { is_expected.to run.with_params(-10).and_raise_error(ArgumentError, /first argument must be a positive integer/) } - it { is_expected.to run.with_params("-10").and_raise_error(ArgumentError, /first argument must be a positive integer/) } - it { is_expected.to run.with_params("string").and_raise_error(ArgumentError, /first argument must be a positive integer/) } - it { is_expected.to run.with_params([]).and_raise_error(ArgumentError, /first argument must be a positive integer/) } - it { is_expected.to run.with_params({}).and_raise_error(ArgumentError, /first argument must be a positive integer/) } - it { is_expected.to run.with_params(1, 1).and_raise_error(ArgumentError, /second argument must be undef or a string/) } - it { is_expected.to run.with_params(1, []).and_raise_error(ArgumentError, /second argument must be undef or a string/) } - it { is_expected.to run.with_params(1, {}).and_raise_error(ArgumentError, /second argument must be undef or a string/) } - it { is_expected.to run.with_params(100).and_return(default_charset) } - it { is_expected.to run.with_params("100").and_return(default_charset) } + + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(ArgumentError, %r{expects at least 1 argument, got none}i) } + it { is_expected.to run.with_params(0).and_raise_error(ArgumentError, %r{parameter 'length' expects an Integer\[1\] value, got Integer\[0, 0\]}) } + it { is_expected.to run.with_params(1.5).and_raise_error(ArgumentError, %r{parameter 'length' expects an Integer\ value, got Float}) } + it { is_expected.to run.with_params(-10).and_raise_error(ArgumentError, %r{parameter 'length' expects an Integer\[1\] value, got Integer\[-10, -10\]}) } + it { is_expected.to run.with_params('-10').and_raise_error(ArgumentError, %r{parameter 'length' expects an Integer\ value, got String}) } + it { is_expected.to run.with_params('string').and_raise_error(ArgumentError, %r{parameter 'length' expects an Integer\ value, got String}) } + it { is_expected.to run.with_params([]).and_raise_error(ArgumentError, %r{parameter 'length' expects an Integer value, got Array}) } + it { is_expected.to run.with_params({}).and_raise_error(ArgumentError, %r{parameter 'length' expects an Integer value, got Hash}) } + it { is_expected.to run.with_params(1, 1).and_raise_error(ArgumentError, %r{parameter 'charset' expects a value of type Undef or String, got Integer}) } + it { is_expected.to run.with_params(1, []).and_raise_error(ArgumentError, %r{parameter 'charset' expects a value of type Undef or String, got Array}) } + it { is_expected.to run.with_params(1, {}).and_raise_error(ArgumentError, %r{parameter 'charset' expects a value of type Undef or String, got Hash}) } + it { is_expected.to run.with_params('100').and_raise_error(ArgumentError, %r{parameter 'length' expects an Integer value, got String}) } it { is_expected.to run.with_params(100, nil).and_return(default_charset) } it { is_expected.to run.with_params(100, '').and_return(default_charset) } - it { is_expected.to run.with_params(100, 'a').and_return(/\Aa{100}\z/) } - it { is_expected.to run.with_params(100, 'ab').and_return(/\A[ab]{100}\z/) } - - it "provides the same 'random' value on subsequent calls for the same host" do - expect(fqdn_rand_string(10)).to eql(fqdn_rand_string(10)) - end - - it "considers the same host and same extra arguments to have the same random sequence" do - first_random = fqdn_rand_string(10, :extra_identifier => [1, "same", "host"]) - second_random = fqdn_rand_string(10, :extra_identifier => [1, "same", "host"]) - - expect(first_random).to eql(second_random) - end - - it "allows extra arguments to control the random value on a single host" do - first_random = fqdn_rand_string(10, :extra_identifier => [1, "different", "host"]) - second_different_random = fqdn_rand_string(10, :extra_identifier => [2, "different", "host"]) - - expect(first_random).not_to eql(second_different_random) - end - - it "should return different strings for different hosts" do - val1 = fqdn_rand_string(10, :host => "first.host.com") - val2 = fqdn_rand_string(10, :host => "second.host.com") + it { is_expected.to run.with_params(100, nil, 'MY_CUSTOM_SEED').and_return(default_charset) } + it { is_expected.to run.with_params(100, '', 'MY_CUSTOM_SEED').and_return(default_charset) } + it { is_expected.to run.with_params(100).and_return(default_charset) } + it { is_expected.to run.with_params(100, 'a').and_return(%r{\Aa{100}\z}) } + it { is_expected.to run.with_params(100, 'ab').and_return(%r{\A[ab]{100}\z}) } + it { is_expected.to run.with_params(100, 'ãβ').and_return(%r{\A[ãβ]{100}\z}) } + + context 'produce predictible and reproducible results' do + before(:each) do + if Gem::Version.new(Puppet::PUPPETVERSION) < Gem::Version.new('7.23.0') + allow(scope).to receive(:lookupvar).with('::fqdn', {}).and_return(fqdn) + else + allow(scope).to receive(:lookupvar).with('facts', {}).and_return({ 'networking' => { 'fqdn' => fqdn } }) + end + end - expect(val1).not_to eql(val2) - end + context 'on a node named example.com' do + let(:fqdn) { 'example.com' } - def fqdn_rand_string(max, args = {}) - host = args[:host] || '127.0.0.1' - charset = args[:charset] - extra = args[:extra_identifier] || [] + it { is_expected.to run.with_params(5).and_return('Pw5NP') } + it { is_expected.to run.with_params(10, 'abcd').and_return('cdadaaacaa') } + it { is_expected.to run.with_params(20, '', 'custom seed').and_return('3QKQHP4wmEObY3a6hkeg') } + it { is_expected.to run.with_params(20, '', 'custom seed', 1, 'extra').and_return('OA19SVDoc3QPY5NlSQ28') } + end - # workaround not being able to use let(:facts) because some tests need - # multiple different hostnames in one context - scope.stubs(:lookupvar).with("::fqdn", {}).returns(host) + context 'on a node named desktop-fln40kq.lan' do + let(:fqdn) { 'desktop-fln40kq.lan' } - function_args = [max] - if args.has_key?(:charset) or !extra.empty? - function_args << charset + it { is_expected.to run.with_params(5).and_return('bgQsB') } + it { is_expected.to run.with_params(10, 'abcd').and_return('bcdbcdacad') } + it { is_expected.to run.with_params(20, '', 'custom seed').and_return('KaZsFlWkUo5SeA3gBEf0') } + it { is_expected.to run.with_params(20, '', 'custom seed', 1, 'extra').and_return('dcAzn1e8AA7hhoLpxAD6') } end - function_args += extra - scope.function_fqdn_rand_string(function_args) end end diff --git a/spec/functions/fqdn_rotate_spec.rb b/spec/functions/fqdn_rotate_spec.rb old mode 100755 new mode 100644 index db7a71732..7906c42c2 --- a/spec/functions/fqdn_rotate_spec.rb +++ b/spec/functions/fqdn_rotate_spec.rb @@ -1,63 +1,62 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'fqdn_rotate' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params(0).and_raise_error(Puppet::ParseError, /Requires either array or string to work with/) } - it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, /Requires either array or string to work with/) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(ArgumentError, %r{expects at least 1 argument, got none}) } + it { is_expected.to run.with_params(0).and_raise_error(ArgumentError, %r{parameter 'input' expects a value of type String or Array, got Integer}) } + it { is_expected.to run.with_params({}).and_raise_error(ArgumentError, %r{parameter 'input' expects a value of type String or Array, got Hash}) } it { is_expected.to run.with_params('').and_return('') } it { is_expected.to run.with_params('a').and_return('a') } + it { is_expected.to run.with_params('Ć£').and_return('Ć£') } it { is_expected.to run.with_params([]).and_return([]) } it { is_expected.to run.with_params(['a']).and_return(['a']) } - it "should rotate a string and the result should be the same size" do - expect(fqdn_rotate("asdf").size).to eq(4) + it 'rotates a string and the result should be the same size' do + expect(fqdn_rotate('asdf').size).to eq(4) end - it "should rotate a string to give the same results for one host" do - val1 = fqdn_rotate("abcdefg", :host => 'one') - val2 = fqdn_rotate("abcdefg", :host => 'one') + it 'rotates a string to give the same results for one host' do + val1 = fqdn_rotate('abcdefg', host: 'one') + val2 = fqdn_rotate('abcdefg', host: 'one') expect(val1).to eq(val2) end - it "allows extra arguments to control the random rotation on a single host" do - val1 = fqdn_rotate("abcdefg", :extra_identifier => [1, "different", "host"]) - val2 = fqdn_rotate("abcdefg", :extra_identifier => [2, "different", "host"]) + it 'allows extra arguments to control the random rotation on a single host' do + val1 = fqdn_rotate('abcdefg', extra_identifier: [1, 'different', 'host']) + val2 = fqdn_rotate('abcdefg', extra_identifier: [2, 'different', 'host']) expect(val1).not_to eq(val2) end - it "considers the same host and same extra arguments to have the same random rotation" do - val1 = fqdn_rotate("abcdefg", :extra_identifier => [1, "same", "host"]) - val2 = fqdn_rotate("abcdefg", :extra_identifier => [1, "same", "host"]) + it 'considers the same host and same extra arguments to have the same random rotation' do + val1 = fqdn_rotate('abcdefg', extra_identifier: [1, 'same', 'host']) + val2 = fqdn_rotate('abcdefg', extra_identifier: [1, 'same', 'host']) expect(val1).to eq(val2) end - it "should rotate a string to give different values on different hosts" do - val1 = fqdn_rotate("abcdefg", :host => 'one') - val2 = fqdn_rotate("abcdefg", :host => 'two') + it 'rotates a string to give different values on different hosts' do + val1 = fqdn_rotate('abcdefg', host: 'one') + val2 = fqdn_rotate('abcdefg', host: 'two') expect(val1).not_to eq(val2) end - it "should accept objects which extend String" do + it 'accepts objects which extend String' do result = fqdn_rotate(AlsoString.new('asdf')) expect(result).to eq('dfas') end - it "should use the Puppet::Util.deterministic_rand function" do - if Puppet::Util.respond_to?(:deterministic_rand) - Puppet::Util.expects(:deterministic_rand).with(44489829212339698569024999901561968770,4) - fqdn_rotate("asdf") - else - skip 'Puppet::Util#deterministic_rand not available' - end + it 'uses the Puppet::Util.deterministic_rand function' do + expect(Puppet::Util).to receive(:deterministic_rand).with(44_489_829_212_339_698_569_024_999_901_561_968_770, 4) + fqdn_rotate('asdf') end - it "should not leave the global seed in a deterministic state" do - fqdn_rotate("asdf") - rand1 = rand() - fqdn_rotate("asdf") - rand2 = rand() + it 'does not leave the global seed in a deterministic state' do + fqdn_rotate('asdf') + rand1 = rand + fqdn_rotate('asdf') + rand2 = rand expect(rand1).not_to eql(rand2) end @@ -67,9 +66,9 @@ def fqdn_rotate(value, args = {}) # workaround not being able to use let(:facts) because some tests need # multiple different hostnames in one context - scope.stubs(:lookupvar).with("::fqdn").returns(host) + allow(subject.func.closure_scope).to receive(:[]).with('facts').and_return({ 'networking' => { 'fqdn' => host } }) function_args = [value] + extra - scope.function_fqdn_rotate(function_args) + scope.call_function('fqdn_rotate', function_args) end end diff --git a/spec/functions/fqdn_uuid_spec.rb b/spec/functions/fqdn_uuid_spec.rb new file mode 100644 index 000000000..a15751f6f --- /dev/null +++ b/spec/functions/fqdn_uuid_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'fqdn_uuid' do + context 'with invalid parameters' do + it { is_expected.to run.with_params.and_raise_error(ArgumentError, %r{No arguments given}) } + it { is_expected.to run.with_params('puppetlabs.com', 'google.com').and_raise_error(ArgumentError, %r{Too many arguments given}) } + it { is_expected.to run.with_params({}).and_raise_error(TypeError, %r{no implicit conversion of Hash}) } + it { is_expected.to run.with_params(0).and_raise_error(TypeError, %r{no implicit conversion of Integer}) } + end + + context 'with given string' do + it { is_expected.to run.with_params('puppetlabs.com').and_return('9c70320f-6815-5fc5-ab0f-debe68bf764c') } + it { is_expected.to run.with_params('google.com').and_return('64ee70a4-8cc1-5d25-abf2-dea6c79a09c8') } + it { is_expected.to run.with_params('0').and_return('6af613b6-569c-5c22-9c37-2ed93f31d3af') } + end +end diff --git a/spec/functions/get_module_path_spec.rb b/spec/functions/get_module_path_spec.rb old mode 100755 new mode 100644 index b1f682fdb..25740380a --- a/spec/functions/get_module_path_spec.rb +++ b/spec/functions/get_module_path_spec.rb @@ -1,51 +1,61 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'get_module_path' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /Wrong number of arguments, expects one/) } - it { is_expected.to run.with_params('one', 'two').and_raise_error(Puppet::ParseError, /Wrong number of arguments, expects one/) } - it { is_expected.to run.with_params('one', 'two', 'three').and_raise_error(Puppet::ParseError, /Wrong number of arguments, expects one/) } - if Puppet.version.to_f >= 4.0 - it { is_expected.to run.with_params('one').and_raise_error(Puppet::Environments::EnvironmentNotFound, /Could not find a directory environment/) } - else - it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, /Could not find module/) } - end + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{Wrong number of arguments, expects one}) } + it { is_expected.to run.with_params('one', 'two').and_raise_error(Puppet::ParseError, %r{Wrong number of arguments, expects one}) } + it { is_expected.to run.with_params('one', 'two', 'three').and_raise_error(Puppet::ParseError, %r{Wrong number of arguments, expects one}) } + it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, %r{Could not find module}) } + # class Stubmodule class StubModule attr_reader :path + def initialize(path) @path = path end end describe 'when locating a module' do - let(:modulepath) { "/tmp/does_not_exist" } - let(:path_of_module_foo) { StubModule.new("/tmp/does_not_exist/foo") } + let(:modulepath) { '/tmp/does_not_exist' } + let(:path_of_module_foo) { StubModule.new('/tmp/does_not_exist/foo') } - before(:each) { Puppet[:modulepath] = modulepath } + before(:each) do + Puppet[:modulepath] = modulepath + end - context 'in the default environment' do - before(:each) { Puppet::Module.expects(:find).with('foo', 'rp_env').returns(path_of_module_foo) } + context 'when in the default environment' do + before(:each) do + allow(Puppet::Module).to receive(:find).with('foo', 'rp_env').and_return(path_of_module_foo) + end - it { is_expected.to run.with_params('foo').and_return(path_of_module_foo.path) } + it 'runs against foo' do + expect(subject).to run.with_params('foo').and_return(path_of_module_foo.path) + end - context 'when the modulepath is a list' do - before(:each) { Puppet[:modulepath] = modulepath + 'tmp/something_else' } + it 'when the modulepath is a list' do + Puppet[:modulepath] = "#{modulepath}tmp/something_else" - it { is_expected.to run.with_params('foo').and_return(path_of_module_foo.path) } + expect(subject).to run.with_params('foo').and_return(path_of_module_foo.path) end end - context 'in a non-default default environment' do + context 'when in a non-default default environment' do let(:environment) { 'test' } - before(:each) { Puppet::Module.expects(:find).with('foo', 'test').returns(path_of_module_foo) } - it { is_expected.to run.with_params('foo').and_return(path_of_module_foo.path) } + before(:each) do + allow(Puppet::Module).to receive(:find).with('foo', 'test').and_return(path_of_module_foo) + end - context 'when the modulepath is a list' do - before(:each) { Puppet[:modulepath] = modulepath + 'tmp/something_else' } + it 'runs against foo' do + expect(subject).to run.with_params('foo').and_return(path_of_module_foo.path) + end - it { is_expected.to run.with_params('foo').and_return(path_of_module_foo.path) } + it 'when the modulepath is a list' do + Puppet[:modulepath] = "#{modulepath}tmp/something_else" + expect(subject).to run.with_params('foo').and_return(path_of_module_foo.path) end end end diff --git a/spec/functions/getparam_spec.rb b/spec/functions/getparam_spec.rb old mode 100755 new mode 100644 index 9e3d9e470..eee123d9a --- a/spec/functions/getparam_spec.rb +++ b/spec/functions/getparam_spec.rb @@ -1,12 +1,14 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'getparam' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(ArgumentError, /Must specify a reference/) } - it { is_expected.to run.with_params('User[one]').and_raise_error(ArgumentError, /Must specify name of a parameter/) } - it { is_expected.to run.with_params('User[one]', 2).and_raise_error(ArgumentError, /Must specify name of a parameter/) } - it { is_expected.to run.with_params('User[one]', []).and_raise_error(ArgumentError, /Must specify name of a parameter/) } - it { is_expected.to run.with_params('User[one]', {}).and_raise_error(ArgumentError, /Must specify name of a parameter/) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(ArgumentError, %r{Must specify a reference}) } + it { is_expected.to run.with_params('User[one]').and_raise_error(ArgumentError, %r{Must specify name of a parameter}) } + it { is_expected.to run.with_params('User[one]', 2).and_raise_error(ArgumentError, %r{Must specify name of a parameter}) } + it { is_expected.to run.with_params('User[one]', []).and_raise_error(ArgumentError, %r{Must specify name of a parameter}) } + it { is_expected.to run.with_params('User[one]', {}).and_raise_error(ArgumentError, %r{Must specify name of a parameter}) } describe 'when compared against a user resource with no params' do let(:pre_condition) { 'user { "one": }' } @@ -22,9 +24,13 @@ it { is_expected.to run.with_params('User[one]', 'ensure').and_return('present') } it { is_expected.to run.with_params('User[two]', 'ensure').and_return('') } it { is_expected.to run.with_params('User[one]', 'shell').and_return('/bin/sh') } - it { - pending("both rspec-puppet as well as the function do the wrong thing here.") - is_expected.to run.with_params('User[one]', 'managehome').and_return(false) - } + it { is_expected.to run.with_params('User[one]', 'managehome').and_return(false) } + end + + describe 'when compared against a user resource with UTF8 and double byte params' do + let(:pre_condition) { 'user { ["äø‰", "ƒốưř"]: ensure => present }' } + + it { is_expected.to run.with_params('User[äø‰]', 'ensure').and_return('present') } + it { is_expected.to run.with_params('User[ƒốưř]', 'ensure').and_return('present') } end end diff --git a/spec/functions/getvar_spec.rb b/spec/functions/getvar_spec.rb deleted file mode 100755 index 6ab137ec7..000000000 --- a/spec/functions/getvar_spec.rb +++ /dev/null @@ -1,21 +0,0 @@ -require 'spec_helper' - -describe 'getvar' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('one', 'two').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - - context 'given variables in namespaces' do - let(:pre_condition) { - <<-'ENDofPUPPETcode' - class site::data { $foo = 'baz' } - include site::data - ENDofPUPPETcode - } - - it { is_expected.to run.with_params('site::data::foo').and_return('baz') } - it { is_expected.to run.with_params('::site::data::foo').and_return('baz') } - it { is_expected.to run.with_params('::site::data::bar').and_return(nil) } - end -end diff --git a/spec/functions/glob_spec.rb b/spec/functions/glob_spec.rb new file mode 100644 index 000000000..a057122ca --- /dev/null +++ b/spec/functions/glob_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'glob' do + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params('').and_return([]) } + it { is_expected.to run.with_params(['']).and_return([]) } + it { is_expected.to run.with_params(['', '']).and_return([]) } + it { is_expected.to run.with_params(['/etc/xyzxyzxyz', '/etcxyzxyzxyz']).and_return([]) } +end diff --git a/spec/functions/grep_spec.rb b/spec/functions/grep_spec.rb old mode 100755 new mode 100644 index 6e0bd6eb9..b8e8e2efe --- a/spec/functions/grep_spec.rb +++ b/spec/functions/grep_spec.rb @@ -1,19 +1,25 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'grep' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { - pending("grep does not actually check this, and raises NoMethodError instead") - is_expected.to run.with_params('one', 'two').and_raise_error(Puppet::ParseError, /first argument not an array/) + pending('grep does not actually check this, and raises NoMethodError instead') + expect(subject).to run.with_params('one', 'two').and_raise_error(Puppet::ParseError, %r{first argument not an array}) } + it { - pending("grep does not actually check this, and raises NoMethodError instead") - is_expected.to run.with_params(1, 'two').and_raise_error(Puppet::ParseError, /first argument not an array/) + pending('grep does not actually check this, and raises NoMethodError instead') + expect(subject).to run.with_params(1, 'two').and_raise_error(Puppet::ParseError, %r{first argument not an array}) } - it { is_expected.to run.with_params('one', 'two', 'three').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + + it { is_expected.to run.with_params('one', 'two', 'three').and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } it { is_expected.to run.with_params([], 'two').and_return([]) } it { is_expected.to run.with_params(['one', 'two', 'three'], 'two').and_return(['two']) } it { is_expected.to run.with_params(['one', 'two', 'three'], 't(wo|hree)').and_return(['two', 'three']) } + it { is_expected.to run.with_params(['į»×Ö¼ĆŖ', 'ţשּׂỔ', 'ţһŗəè'], 'Å£(שּׂỔ|һŗəè)').and_return(['ţשּׂỔ', 'ţһŗəè']) } end diff --git a/spec/functions/has_function_spec.rb b/spec/functions/has_function_spec.rb new file mode 100644 index 000000000..dd66ebde2 --- /dev/null +++ b/spec/functions/has_function_spec.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'stdlib::has_function' do + let(:pre_condition) { 'function puppet_func {}' } + + before(:each) do + Puppet::Parser::Functions.newfunction(:test_3x_func) do |_args| + true + end + end + + it { is_expected.not_to be_nil } + + # Itself, a namespaced function: + it { is_expected.to run.with_params('stdlib::has_function').and_return(true) } + + # A namespaced function which does not exist: + it { is_expected.to run.with_params('stdlib::not_a_function').and_return(false) } + + # A top-function which does not exist: + it { is_expected.to run.with_params('not_a_function').and_return(false) } + + # A Puppet core function: + it { is_expected.to run.with_params('assert_type').and_return(true) } + + # A Puppet function stubbed during testing: + it { is_expected.to run.with_params('puppet_func').and_return(true) } + + # A file-loaded 3x style function in stdlib: + it { is_expected.to run.with_params('validate_augeas').and_return(true) } + + # A stubbed 3x-style function: + it { is_expected.to run.with_params('test_3x_func').and_return(true) } +end diff --git a/spec/functions/has_interface_with_spec.rb b/spec/functions/has_interface_with_spec.rb old mode 100755 new mode 100644 index 7334d38b9..16e90447f --- a/spec/functions/has_interface_with_spec.rb +++ b/spec/functions/has_interface_with_spec.rb @@ -1,38 +1,147 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'has_interface_with' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params("one", "two", "three").and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(ArgumentError, %r{expects between 1 and 2 arguments, got none}) } + it { is_expected.to run.with_params('one', 'two', 'three').and_raise_error(ArgumentError, %r{expects between 1 and 2 arguments, got 3}) } # We need to mock out the Facts so we can specify how we expect this function # to behave on different platforms. - context "On Mac OS X Systems" do - let(:facts) { { :interfaces => 'lo0,gif0,stf0,en1,p2p0,fw0,en0,vmnet1,vmnet8,utun0' } } + context 'when on Mac OS X Systems' do + let(:facts) do + { + 'networking' => { + 'interfaces' => { + 'lo0' => { + 'bindings' => [ + { + 'address' => '127.0.0.1', + 'netmask' => '255.0.0.0', + 'network' => '127.0.0.0' + }, + ], + bindings6: [ + { + 'address' => '::1', + 'netmask' => 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', + 'network' => '::1' + }, + { + 'address' => 'fe80::1', + 'netmask' => 'ffff:ffff:ffff:ffff::', + 'network' => 'fe80::' + }, + ], + 'ip' => '127.0.0.1', + 'ip6' => '::1', + 'mtu' => 16_384, + 'netmask' => '255.0.0.0', + 'netmask6' => 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', + 'network' => '127.0.0.0', + 'network6' => '::1', + 'scope6' => 'host' + } + } + } + } + end + it { is_expected.to run.with_params('lo0').and_return(true) } it { is_expected.to run.with_params('lo').and_return(false) } end - context "On Linux Systems" do + context 'when on Linux Systems' do let(:facts) do { - :interfaces => 'eth0,lo', - :ipaddress => '10.0.0.1', - :ipaddress_lo => '127.0.0.1', - :ipaddress_eth0 => '10.0.0.1', - :muppet => 'kermit', - :muppet_lo => 'mspiggy', - :muppet_eth0 => 'kermit', + 'networking' => { + 'interfaces' => { + 'eth0' => { + 'bindings' => [ + { + 'address' => '10.0.2.15', + 'netmask' => '255.255.255.0', + 'network' => '10.0.2.0' + }, + ], + 'bindings6' => [ + { + 'address' => 'fe80::5054:ff:fe8a:fee6', + 'netmask' => 'ffff:ffff:ffff:ffff::', + 'network' => 'fe80::' + }, + ], + 'dhcp' => '10.0.2.2', + 'ip' => '10.0.2.15', + 'ip6' => 'fe80::5054:ff:fe8a:fee6', + 'mac' => '52:54:00:8a:fe:e6', + 'mtu' => 1500, + 'netmask' => '255.255.255.0', + 'netmask6' => 'ffff:ffff:ffff:ffff::', + 'network' => '10.0.2.0', + 'network6' => 'fe80::' + }, + 'eth1' => { + 'bindings' => [ + { + 'address' => '10.0.0.2', + 'netmask' => '255.255.255.0', + 'network' => '10.0.0.0' + }, + ], + 'bindings6' => [ + { + 'address' => 'fe80::a00:27ff:fed1:d28c', + 'netmask' => 'ffff:ffff:ffff:ffff::', + 'network' => 'fe80::' + }, + ], + 'ip' => '10.0.0.2', + 'ip6' => 'fe80::a00:27ff:fed1:d28c', + 'mac' => '08:00:27:d1:d2:8c', + 'mtu' => 1500, + 'netmask' => '255.255.255.0', + 'netmask6' => 'ffff:ffff:ffff:ffff::', + 'network' => '10.0.0.0', + 'network6' => 'fe80::' + }, + 'lo' => { + 'bindings' => [ + { + 'address' => '127.0.0.1', + 'netmask' => '255.0.0.0', + 'network' => '127.0.0.0' + }, + ], + 'bindings6' => [ + { + 'address' => '::1', + 'netmask' => 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', + 'network' => '::1' + }, + ], + 'ip' => '127.0.0.1', + 'ip6' => '::1', + 'mtu' => 65_536, + 'netmask' => '255.0.0.0', + 'netmask6' => 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', + 'network' => '127.0.0.0', + 'network6' => '::1' + } + } + } } end it { is_expected.to run.with_params('lo').and_return(true) } it { is_expected.to run.with_params('lo0').and_return(false) } it { is_expected.to run.with_params('ipaddress', '127.0.0.1').and_return(true) } - it { is_expected.to run.with_params('ipaddress', '10.0.0.1').and_return(true) } + it { is_expected.to run.with_params('ipaddress', '10.0.0.2').and_return(true) } it { is_expected.to run.with_params('ipaddress', '8.8.8.8').and_return(false) } - it { is_expected.to run.with_params('muppet', 'kermit').and_return(true) } - it { is_expected.to run.with_params('muppet', 'mspiggy').and_return(true) } - it { is_expected.to run.with_params('muppet', 'bigbird').and_return(false) } + it { is_expected.to run.with_params('netmask', '255.255.255.0').and_return(true) } + it { is_expected.to run.with_params('macaddress', '52:54:00:8a:fe:e6').and_return(true) } + it { is_expected.to run.with_params('network', '42.0.0.0').and_return(false) } + it { is_expected.to run.with_params('network', '10.0.0.0').and_return(true) } end end diff --git a/spec/functions/has_ip_address_spec.rb b/spec/functions/has_ip_address_spec.rb old mode 100755 new mode 100644 index 42a5a7926..7256e7518 --- a/spec/functions/has_ip_address_spec.rb +++ b/spec/functions/has_ip_address_spec.rb @@ -1,22 +1,32 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'has_ip_address' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params("one", "two").and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(ArgumentError, %r{'stdlib::has_ip_address' expects 1 argument, got none}) } + it { is_expected.to run.with_params('one', 'two').and_raise_error(ArgumentError, %r{'stdlib::has_ip_address' expects 1 argument, got 2}) } - context "On Linux Systems" do + context 'when on Linux Systems' do let(:facts) do { - :interfaces => 'eth0,lo', - :ipaddress => '10.0.0.1', - :ipaddress_lo => '127.0.0.1', - :ipaddress_eth0 => '10.0.0.1', + networking: { + 'interfaces' => { + 'eth0' => { + 'ip' => '10.0.0.1', + }, + 'lo' => { + 'ip' => '127.0.0.1', + }, + }, + 'ip' => '10.0.0.1', + }, } end it { is_expected.to run.with_params('127.0.0.1').and_return(true) } it { is_expected.to run.with_params('10.0.0.1').and_return(true) } it { is_expected.to run.with_params('8.8.8.8').and_return(false) } + it { is_expected.to run.with_params('invalid').and_raise_error(ArgumentError, %r{parameter 'ip_address' expects a match}) } end end diff --git a/spec/functions/has_ip_network_spec.rb b/spec/functions/has_ip_network_spec.rb old mode 100755 new mode 100644 index 7b5fe66ac..c8352272e --- a/spec/functions/has_ip_network_spec.rb +++ b/spec/functions/has_ip_network_spec.rb @@ -1,22 +1,31 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'has_ip_network' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params("one", "two").and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(ArgumentError, %r{'stdlib::has_ip_network' expects 1 argument, got none}) } + it { is_expected.to run.with_params('one', 'two').and_raise_error(ArgumentError, %r{'stdlib::has_ip_network' expects 1 argument, got 2}) } - context "On Linux Systems" do + context 'when on Linux Systems' do let(:facts) do { - :interfaces => 'eth0,lo', - :network => :undefined, - :network_lo => '127.0.0.0', - :network_eth0 => '10.0.0.0', + networking: { + 'interfaces' => { + 'eth0' => { + 'network' => '10.0.0.0', + }, + 'lo' => { + 'network' => '127.0.0.0', + }, + }, + }, } end it { is_expected.to run.with_params('127.0.0.0').and_return(true) } it { is_expected.to run.with_params('10.0.0.0').and_return(true) } it { is_expected.to run.with_params('8.8.8.0').and_return(false) } + it { is_expected.to run.with_params('invalid').and_raise_error(ArgumentError, %r{parameter 'ip_network' expects a match}) } end end diff --git a/spec/functions/has_key_spec.rb b/spec/functions/has_key_spec.rb deleted file mode 100755 index 965d5a657..000000000 --- a/spec/functions/has_key_spec.rb +++ /dev/null @@ -1,15 +0,0 @@ -require 'spec_helper' - -describe 'has_key' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params("one").and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params("one", "two", "three").and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params("one", "two").and_raise_error(Puppet::ParseError, /expects the first argument to be a hash/) } - it { is_expected.to run.with_params(1, "two").and_raise_error(Puppet::ParseError, /expects the first argument to be a hash/) } - it { is_expected.to run.with_params([], "two").and_raise_error(Puppet::ParseError, /expects the first argument to be a hash/) } - - it { is_expected.to run.with_params({ 'key' => 'value' }, "key").and_return(true) } - it { is_expected.to run.with_params({}, "key").and_return(false) } - it { is_expected.to run.with_params({ 'key' => 'value'}, "not a key").and_return(false) } -end diff --git a/spec/functions/hash_spec.rb b/spec/functions/hash_spec.rb deleted file mode 100755 index 4fe99ceeb..000000000 --- a/spec/functions/hash_spec.rb +++ /dev/null @@ -1,14 +0,0 @@ -require 'spec_helper' - -describe 'hash' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { - pending("Current implementation ignores parameters after the first.") - is_expected.to run.with_params([], 'two').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) - } - it { is_expected.to run.with_params(['one']).and_raise_error(Puppet::ParseError, /Unable to compute/) } - it { is_expected.to run.with_params([]).and_return({}) } - it { is_expected.to run.with_params(['key1', 'value1']).and_return({ 'key1' => 'value1' }) } - it { is_expected.to run.with_params(['key1', 'value1', 'key2', 'value2']).and_return({ 'key1' => 'value1', 'key2' => 'value2' }) } -end diff --git a/spec/functions/intersection_spec.rb b/spec/functions/intersection_spec.rb old mode 100755 new mode 100644 index c0f608690..6e1664609 --- a/spec/functions/intersection_spec.rb +++ b/spec/functions/intersection_spec.rb @@ -1,8 +1,10 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'intersection' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError) } it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError) } it { is_expected.to run.with_params('one', 'two').and_raise_error(Puppet::ParseError) } it { is_expected.to run.with_params('one', 'two', 'three').and_raise_error(Puppet::ParseError) } @@ -14,8 +16,9 @@ it { is_expected.to run.with_params(['one'], []).and_return([]) } it { is_expected.to run.with_params(['one'], ['one']).and_return(['one']) } it { is_expected.to run.with_params(['one', 'two', 'three'], ['two', 'three']).and_return(['two', 'three']) } + it { is_expected.to run.with_params(['ÅÅ‹į»ƒ', 'ŧשợ', 'ţђŕẽё'], ['ŧשợ', 'ţђŕẽё']).and_return(['ŧשợ', 'ţђŕẽё']) } it { is_expected.to run.with_params(['one', 'two', 'two', 'three'], ['two', 'three']).and_return(['two', 'three']) } it { is_expected.to run.with_params(['one', 'two', 'three'], ['two', 'two', 'three']).and_return(['two', 'three']) } it { is_expected.to run.with_params(['one', 'two', 'three'], ['two', 'three', 'four']).and_return(['two', 'three']) } - it 'should not confuse types' do is_expected.to run.with_params(['1', '2', '3'], [1, 2]).and_return([]) end + it 'does not confuse types' do is_expected.to run.with_params(['1', '2', '3'], [1, 2]).and_return([]) end end diff --git a/spec/functions/ip_in_range_spec.rb b/spec/functions/ip_in_range_spec.rb new file mode 100644 index 000000000..900d59023 --- /dev/null +++ b/spec/functions/ip_in_range_spec.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'stdlib::ip_in_range' do + describe 'signature validation' do + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(ArgumentError, %r{'stdlib::ip_in_range' expects 2 arguments, got none}) } + it { is_expected.to run.with_params('one', 'two', '3').and_raise_error(ArgumentError, %r{'stdlib::ip_in_range' expects 2 arguments, got 3}) } + it { is_expected.to run.with_params([], []).and_raise_error(ArgumentError, %r{'stdlib::ip_in_range' parameter 'ipaddress' expects a String value, got Array}) } + it { is_expected.to run.with_params('1.1.1.1', 7).and_raise_error(ArgumentError, %r{'stdlib::ip_in_range' parameter 'range' expects a value of type String or Array, got Integer}) } + end + + describe 'basic validation inputs' do + it { is_expected.to run.with_params('192.168.100.12', '192.168.100.0/24').and_return(true) } + it { is_expected.to run.with_params('192.168.100.12', ['10.10.10.10/24', '192.168.100.0/24']).and_return(true) } + it { is_expected.to run.with_params('10.10.10.10', '192.168.100.0/24').and_return(false) } + end +end diff --git a/spec/functions/is_a_spec.rb b/spec/functions/is_a_spec.rb index 8dec13f5a..bd689c7ca 100644 --- a/spec/functions/is_a_spec.rb +++ b/spec/functions/is_a_spec.rb @@ -1,25 +1,34 @@ +# frozen_string_literal: true + require 'spec_helper' -if ENV["FUTURE_PARSER"] == 'yes' +if ENV['FUTURE_PARSER'] == 'yes' describe 'type_of' do pending 'teach rspec-puppet to load future-only functions under 3.7.5' do - it { is_expected.not_to eq(nil) } + it { is_expected.not_to be_nil } end end end if Puppet.version.to_f >= 4.0 describe 'is_a' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(ArgumentError) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(ArgumentError) } it { is_expected.to run.with_params('', '').and_raise_error(ArgumentError) } it 'succeeds when comparing a string and a string' do - is_expected.to run.with_params('hello world', String).and_return(true) + expect(subject).to run.with_params('hello world', String).and_return(true) end it 'fails when comparing an integer and a string' do - is_expected.to run.with_params(5, String).and_return(false) + expect(subject).to run.with_params(5, String).and_return(false) + end + + it 'suceeds when comparing an UTF8 and double byte characters' do + comparison_array = ['ć“ć®ćƒ†ć‚­ć‚¹ćƒˆ', 'ŧћịś ŧêχŧ'] + comparison_array.each do |comparison_value| + expect(subject).to run.with_params(comparison_value, String).and_return(true) + end end end end diff --git a/spec/functions/is_array_spec.rb b/spec/functions/is_array_spec.rb deleted file mode 100755 index 7dd21c23b..000000000 --- a/spec/functions/is_array_spec.rb +++ /dev/null @@ -1,19 +0,0 @@ -require 'spec_helper' - -describe 'is_array' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { - pending("Current implementation ignores parameters after the first.") - is_expected.to run.with_params([], []).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) - } - it { is_expected.to run.with_params([]).and_return(true) } - it { is_expected.to run.with_params(['one']).and_return(true) } - it { is_expected.to run.with_params([1]).and_return(true) } - it { is_expected.to run.with_params([{}]).and_return(true) } - it { is_expected.to run.with_params([[]]).and_return(true) } - it { is_expected.to run.with_params('').and_return(false) } - it { is_expected.to run.with_params('one').and_return(false) } - it { is_expected.to run.with_params(1).and_return(false) } - it { is_expected.to run.with_params({}).and_return(false) } -end diff --git a/spec/functions/is_bool_spec.rb b/spec/functions/is_bool_spec.rb deleted file mode 100755 index 76d619b00..000000000 --- a/spec/functions/is_bool_spec.rb +++ /dev/null @@ -1,15 +0,0 @@ -require 'spec_helper' - -describe 'is_bool' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params(true, false).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params(true).and_return(true) } - it { is_expected.to run.with_params(false).and_return(true) } - it { is_expected.to run.with_params([1]).and_return(false) } - it { is_expected.to run.with_params([{}]).and_return(false) } - it { is_expected.to run.with_params([[]]).and_return(false) } - it { is_expected.to run.with_params([true]).and_return(false) } - it { is_expected.to run.with_params('true').and_return(false) } - it { is_expected.to run.with_params('false').and_return(false) } -end diff --git a/spec/functions/is_domain_name_spec.rb b/spec/functions/is_domain_name_spec.rb deleted file mode 100755 index c1bf0e34b..000000000 --- a/spec/functions/is_domain_name_spec.rb +++ /dev/null @@ -1,43 +0,0 @@ -require 'spec_helper' - -describe 'is_domain_name' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('one', 'two').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params(1).and_return(false) } - it { is_expected.to run.with_params([]).and_return(false) } - it { is_expected.to run.with_params({}).and_return(false) } - it { is_expected.to run.with_params('').and_return(false) } - it { is_expected.to run.with_params('.').and_return(true) } - it { is_expected.to run.with_params('com').and_return(true) } - it { is_expected.to run.with_params('com.').and_return(true) } - it { is_expected.to run.with_params('x.com').and_return(true) } - it { is_expected.to run.with_params('x.com.').and_return(true) } - it { is_expected.to run.with_params('foo.example.com').and_return(true) } - it { is_expected.to run.with_params('foo.example.com.').and_return(true) } - it { is_expected.to run.with_params('2foo.example.com').and_return(true) } - it { is_expected.to run.with_params('2foo.example.com.').and_return(true) } - it { is_expected.to run.with_params('www.2foo.example.com').and_return(true) } - it { is_expected.to run.with_params('www.2foo.example.com.').and_return(true) } - describe 'inputs with spaces' do - it { is_expected.to run.with_params('invalid domain').and_return(false) } - end - describe 'inputs with hyphens' do - it { is_expected.to run.with_params('foo-bar.example.com').and_return(true) } - it { is_expected.to run.with_params('foo-bar.example.com.').and_return(true) } - it { is_expected.to run.with_params('www.foo-bar.example.com').and_return(true) } - it { is_expected.to run.with_params('www.foo-bar.example.com.').and_return(true) } - it { is_expected.to run.with_params('-foo.example.com').and_return(false) } - it { is_expected.to run.with_params('-foo.example.com').and_return(false) } - end - # Values obtained from Facter values will be frozen strings - # in newer versions of Facter: - it { is_expected.to run.with_params('www.example.com'.freeze).and_return(true) } - describe 'top level domain must be alphabetic if there are multiple labels' do - it { is_expected.to run.with_params('2com').and_return(true) } - it { is_expected.to run.with_params('www.example.2com').and_return(false) } - end - describe 'IP addresses are not domain names' do - it { is_expected.to run.with_params('192.168.1.1').and_return(false) } - end -end diff --git a/spec/functions/is_float_spec.rb b/spec/functions/is_float_spec.rb deleted file mode 100755 index ffff971a7..000000000 --- a/spec/functions/is_float_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -require 'spec_helper' - -describe 'is_float' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params(0.1, 0.2).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - - describe 'passing a string' do - it { is_expected.to run.with_params('0.1').and_return(true) } - it { is_expected.to run.with_params('1.0').and_return(true) } - it { is_expected.to run.with_params('1').and_return(false) } - it { is_expected.to run.with_params('one').and_return(false) } - it { is_expected.to run.with_params('one 1.0').and_return(false) } - it { is_expected.to run.with_params('1.0 one').and_return(false) } - end - - describe 'passing numbers' do - it { is_expected.to run.with_params(0.1).and_return(true) } - it { is_expected.to run.with_params(1.0).and_return(true) } - it { is_expected.to run.with_params(1).and_return(false) } - end -end diff --git a/spec/functions/is_function_available.rb b/spec/functions/is_function_available.rb deleted file mode 100755 index 44f08c081..000000000 --- a/spec/functions/is_function_available.rb +++ /dev/null @@ -1,9 +0,0 @@ -require 'spec_helper' - -describe 'is_function_available' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('one', 'two').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('include').and_return(true) } - it { is_expected.to run.with_params('no_such_function').and_return(false) } -end diff --git a/spec/functions/is_hash_spec.rb b/spec/functions/is_hash_spec.rb deleted file mode 100755 index c2599a02a..000000000 --- a/spec/functions/is_hash_spec.rb +++ /dev/null @@ -1,11 +0,0 @@ -require 'spec_helper' - -describe 'is_hash' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params({}, {}).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('').and_return(false) } - it { is_expected.to run.with_params({}).and_return(true) } - it { is_expected.to run.with_params([]).and_return(false) } - it { is_expected.to run.with_params(1).and_return(false) } -end diff --git a/spec/functions/is_integer_spec.rb b/spec/functions/is_integer_spec.rb deleted file mode 100755 index 67263c18f..000000000 --- a/spec/functions/is_integer_spec.rb +++ /dev/null @@ -1,25 +0,0 @@ -require 'spec_helper' - -describe 'is_integer' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params(1, 2).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - - it { is_expected.to run.with_params(3).and_return(true) } - it { is_expected.to run.with_params('3').and_return(true) } - it { is_expected.to run.with_params(-3).and_return(true) } - it { is_expected.to run.with_params('-3').and_return(true) } - - it { is_expected.to run.with_params(3.7).and_return(false) } - it { is_expected.to run.with_params('3.7').and_return(false) } - it { is_expected.to run.with_params(-3.7).and_return(false) } - it { is_expected.to run.with_params('3.7').and_return(false) } - - it { is_expected.to run.with_params('one').and_return(false) } - it { is_expected.to run.with_params([]).and_return(false) } - it { is_expected.to run.with_params([1]).and_return(false) } - it { is_expected.to run.with_params({}).and_return(false) } - it { is_expected.to run.with_params(true).and_return(false) } - it { is_expected.to run.with_params(false).and_return(false) } - it { is_expected.to run.with_params('0001234').and_return(false) } -end diff --git a/spec/functions/is_ip_address_spec.rb b/spec/functions/is_ip_address_spec.rb deleted file mode 100755 index a7a383a1e..000000000 --- a/spec/functions/is_ip_address_spec.rb +++ /dev/null @@ -1,23 +0,0 @@ -require 'spec_helper' - -describe 'is_ip_address' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params([], []).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('1.2.3.4').and_return(true) } - it { is_expected.to run.with_params('1.2.3.255').and_return(true) } - it { is_expected.to run.with_params('1.2.3.256').and_return(false) } - it { is_expected.to run.with_params('1.2.3').and_return(false) } - it { is_expected.to run.with_params('1.2.3.4.5').and_return(false) } - it { is_expected.to run.with_params('fe00::1').and_return(true) } - it { is_expected.to run.with_params('fe80:0000:cd12:d123:e2f8:47ff:fe09:dd74').and_return(true) } - it { is_expected.to run.with_params('FE80:0000:CD12:D123:E2F8:47FF:FE09:DD74').and_return(true) } - it { is_expected.to run.with_params('fe80:0000:cd12:d123:e2f8:47ff:fe09:zzzz').and_return(false) } - it { is_expected.to run.with_params('fe80:0000:cd12:d123:e2f8:47ff:fe09').and_return(false) } - it { is_expected.to run.with_params('fe80:0000:cd12:d123:e2f8:47ff:fe09:dd74:dd74').and_return(false) } - it { is_expected.to run.with_params('').and_return(false) } - it { is_expected.to run.with_params('one').and_return(false) } - it { is_expected.to run.with_params(1).and_return(false) } - it { is_expected.to run.with_params({}).and_return(false) } - it { is_expected.to run.with_params([]).and_return(false) } -end diff --git a/spec/functions/is_mac_address_spec.rb b/spec/functions/is_mac_address_spec.rb deleted file mode 100755 index 5f76a91b4..000000000 --- a/spec/functions/is_mac_address_spec.rb +++ /dev/null @@ -1,24 +0,0 @@ -require 'spec_helper' - -describe 'is_mac_address' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params([], []).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('00:a0:1f:12:7f:a0').and_return(true) } - it { is_expected.to run.with_params('00:A0:1F:12:7F:A0').and_return(true) } - it { is_expected.to run.with_params('00:00:00:00:00:0g').and_return(false) } - it { is_expected.to run.with_params('').and_return(false) } - it { is_expected.to run.with_params('one').and_return(false) } - it { - pending "should properly typecheck its arguments" - is_expected.to run.with_params(1).and_return(false) - } - it { - pending "should properly typecheck its arguments" - is_expected.to run.with_params({}).and_return(false) - } - it { - pending "should properly typecheck its arguments" - is_expected.to run.with_params([]).and_return(false) - } -end diff --git a/spec/functions/is_numeric_spec.rb b/spec/functions/is_numeric_spec.rb deleted file mode 100755 index d0f5a6eb6..000000000 --- a/spec/functions/is_numeric_spec.rb +++ /dev/null @@ -1,28 +0,0 @@ -require 'spec_helper' - -describe 'is_numeric' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params(1, 2).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - - it { is_expected.to run.with_params(3).and_return(true) } - it { is_expected.to run.with_params('3').and_return(true) } - it { is_expected.to run.with_params(-3).and_return(true) } - it { is_expected.to run.with_params('-3').and_return(true) } - - it { is_expected.to run.with_params(3.7).and_return(true) } - it { is_expected.to run.with_params('3.7').and_return(true) } - it { is_expected.to run.with_params(-3.7).and_return(true) } - it { is_expected.to run.with_params('3.7').and_return(true) } - - it { is_expected.to run.with_params('-342.2315e-12').and_return(true) } - - it { is_expected.to run.with_params('one').and_return(false) } - it { is_expected.to run.with_params([]).and_return(false) } - it { is_expected.to run.with_params([1]).and_return(false) } - it { is_expected.to run.with_params({}).and_return(false) } - it { is_expected.to run.with_params(true).and_return(false) } - it { is_expected.to run.with_params(false).and_return(false) } - it { is_expected.to run.with_params('0001234').and_return(false) } - it { is_expected.to run.with_params(' - 1234').and_return(false) } -end diff --git a/spec/functions/is_string_spec.rb b/spec/functions/is_string_spec.rb deleted file mode 100755 index 8e459ccfe..000000000 --- a/spec/functions/is_string_spec.rb +++ /dev/null @@ -1,28 +0,0 @@ -require 'spec_helper' - -describe 'is_string' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { - pending("Current implementation ignores parameters after the first.") - is_expected.to run.with_params('', '').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) - } - - it { is_expected.to run.with_params(3).and_return(false) } - it { is_expected.to run.with_params('3').and_return(false) } - it { is_expected.to run.with_params(-3).and_return(false) } - it { is_expected.to run.with_params('-3').and_return(false) } - - it { is_expected.to run.with_params(3.7).and_return(false) } - it { is_expected.to run.with_params('3.7').and_return(false) } - it { is_expected.to run.with_params(-3.7).and_return(false) } - it { is_expected.to run.with_params('3.7').and_return(false) } - - it { is_expected.to run.with_params([]).and_return(false) } - it { is_expected.to run.with_params([1]).and_return(false) } - it { is_expected.to run.with_params({}).and_return(false) } - it { is_expected.to run.with_params(true).and_return(false) } - it { is_expected.to run.with_params(false).and_return(false) } - it { is_expected.to run.with_params('one').and_return(true) } - it { is_expected.to run.with_params('0001234').and_return(true) } -end diff --git a/spec/functions/join_keys_to_values_spec.rb b/spec/functions/join_keys_to_values_spec.rb old mode 100755 new mode 100644 index 6c109d1c2..f23825391 --- a/spec/functions/join_keys_to_values_spec.rb +++ b/spec/functions/join_keys_to_values_spec.rb @@ -1,19 +1,36 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'join_keys_to_values' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /Takes exactly two arguments/) } - it { is_expected.to run.with_params({}, '', '').and_raise_error(Puppet::ParseError, /Takes exactly two arguments/) } - it { is_expected.to run.with_params('one', '').and_raise_error(TypeError, /The first argument must be a hash/) } - it { is_expected.to run.with_params({}, 2).and_raise_error(TypeError, /The second argument must be a string/) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{Takes exactly two arguments}) } + it { is_expected.to run.with_params({}, '', '').and_raise_error(Puppet::ParseError, %r{Takes exactly two arguments}) } + it { is_expected.to run.with_params('one', '').and_raise_error(TypeError, %r{The first argument must be a hash}) } + it { is_expected.to run.with_params({}, 2).and_raise_error(TypeError, %r{The second argument must be a string}) } it { is_expected.to run.with_params({}, '').and_return([]) } it { is_expected.to run.with_params({}, ':').and_return([]) } it { is_expected.to run.with_params({ 'key' => 'value' }, '').and_return(['keyvalue']) } it { is_expected.to run.with_params({ 'key' => 'value' }, ':').and_return(['key:value']) } - it { is_expected.to run.with_params({ 'key' => nil }, ':').and_return(['key:']) } - it 'should run join_keys_to_values(, ":") and return the proper array' do - result = subject.call([{ 'key1' => 'value1', 'key2' => 'value2' }, ':']) - expect(result.sort).to eq(['key1:value1', 'key2:value2'].sort) + + context 'with UTF8 and double byte characters' do + it { is_expected.to run.with_params({ 'Ņįŗ½Ī³' => 'āˆšįŗ”ÄŗÅ±Ä“' }, ':').and_return(['Ņįŗ½Ī³:āˆšįŗ”ÄŗÅ±Ä“']) } + it { is_expected.to run.with_params({ 'Ņįŗ½Ī³' => 'āˆšįŗ”ÄŗÅ±Ä“' }, 'äø‡').and_return(['Ņįŗ½Ī³äø‡āˆšįŗ”ÄŗÅ±Ä“']) } + end + + if Puppet::Util::Package.versioncmp(Puppet.version, '5.5.7') == 0 + it { is_expected.to run.with_params({ 'key' => '' }, ':').and_return(['key:']) } + else + it { is_expected.to run.with_params({ 'key' => nil }, ':').and_return(['key:']) } + end + + it 'runs join_keys_to_values(, ":") and return the proper array' do + expect(subject).to run.with_params({ 'key1' => 'value1', 'key2' => 'value2' }, ':').and_return(['key1:value1', 'key2:value2']) + end + + it 'runs join_keys_to_values(, " ") and return the proper array' do + expected_result = ['key1 value1', 'key2 value2', 'key2 value3'] + expect(subject).to run.with_params({ 'key1' => 'value1', 'key2' => ['value2', 'value3'] }, ' ').and_return(expected_result) end end diff --git a/spec/functions/join_spec.rb b/spec/functions/join_spec.rb deleted file mode 100755 index a3005714b..000000000 --- a/spec/functions/join_spec.rb +++ /dev/null @@ -1,19 +0,0 @@ -require 'spec_helper' - -describe 'join' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { - pending("Current implementation ignores parameters after the second.") - is_expected.to run.with_params([], '', '').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) - } - it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, /Requires array to work with/) } - it { is_expected.to run.with_params([], 2).and_raise_error(Puppet::ParseError, /Requires string to work with/) } - - it { is_expected.to run.with_params([]).and_return('') } - it { is_expected.to run.with_params([], ':').and_return('') } - it { is_expected.to run.with_params(['one']).and_return('one') } - it { is_expected.to run.with_params(['one'], ':').and_return('one') } - it { is_expected.to run.with_params(['one', 'two', 'three']).and_return('onetwothree') } - it { is_expected.to run.with_params(['one', 'two', 'three'], ':').and_return('one:two:three') } -end diff --git a/spec/functions/keys_spec.rb b/spec/functions/keys_spec.rb deleted file mode 100755 index 2e009dcc8..000000000 --- a/spec/functions/keys_spec.rb +++ /dev/null @@ -1,19 +0,0 @@ -require 'spec_helper' - -describe 'keys' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { - pending("Current implementation ignores parameters after the first.") - is_expected.to run.with_params({}, {}).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) - } - it { is_expected.to run.with_params('').and_raise_error(Puppet::ParseError, /Requires hash to work with/) } - it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /Requires hash to work with/) } - it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError, /Requires hash to work with/) } - it { is_expected.to run.with_params({}).and_return([]) } - it { is_expected.to run.with_params({ 'key' => 'value' }).and_return(['key']) } - it 'should return the array of keys' do - result = subject.call([{ 'key1' => 'value1', 'key2' => 'value2' }]) - expect(result).to match_array(['key1', 'key2']) - end -end diff --git a/spec/functions/load_module_metadata_spec.rb b/spec/functions/load_module_metadata_spec.rb old mode 100755 new mode 100644 index fe665fb50..6a8124a0f --- a/spec/functions/load_module_metadata_spec.rb +++ b/spec/functions/load_module_metadata_spec.rb @@ -1,29 +1,53 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'load_module_metadata' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params("one", "two", "three").and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params('one', 'two', 'three').and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } - it "should json parse the file" do - allow(scope).to receive(:function_get_module_path).with(['science']).and_return('/path/to/module/') - allow(File).to receive(:exists?).with(/metadata.json/).and_return(true) - allow(File).to receive(:read).with(/metadata.json/).and_return('{"name": "spencer-science"}') + describe 'when calling with valid arguments' do + before :each do + # In Puppet 7, there are two prior calls to File.read prior to the responses we want to mock + allow(File).to receive(:read).with(anything, anything).and_call_original + allow(File).to receive(:read).with(%r{/(stdlib|test)/metadata.json}, encoding: 'utf-8').and_return('{"name": "puppetlabs-stdlib"}') + allow(File).to receive(:read).with(%r{/(stdlib|test)/metadata.json}).and_return('{"name": "puppetlabs-stdlib"}') + # Additional modules used by litmus which are identified while running these dues to being in fixtures + allow(File).to receive(:read).with(%r{/(provision|puppet_agent|facts)/metadata.json}, encoding: 'utf-8') + end - result = subject.call(['science']) - expect(result['name']).to eq('spencer-science') - end + context 'when calling with valid utf8 and double byte character arguments' do + before :each do + allow(File).to receive(:read).with(%r{/(stdlib|test)/metadata.json}, encoding: 'utf-8').and_return('{"Ä­ÄĆØÅ‰Å£Ä©Ę’Ń–į»ƒŃ": "ċƔņńęאּń Ổƒ ţħíŔ - +この文字"}') + allow(File).to receive(:read).with(%r{/(stdlib|test)/metadata.json}).and_return('{"Ä­ÄĆØÅ‰Å£Ä©Ę’Ń–į»ƒŃ": "ċƔņńęאּń Ổƒ ţħíŔ - +この文字"}') + end - it "should fail by default if there is no metadata.json" do - allow(scope).to receive(:function_get_module_path).with(['science']).and_return('/path/to/module/') - allow(File).to receive(:exists?).with(/metadata.json/).and_return(false) - expect {subject.call(['science'])}.to raise_error(Puppet::ParseError) - end + let(:prefix) { 'C:' if Puppet::Util::Platform.windows? } + + it 'jsons parse the file' do + allow(scope).to receive(:function_get_module_path).with(['science']).and_return("#{prefix}/path/to/module/") + allow(File).to receive(:exist?).with("#{prefix}/path/to/module/metadata.json").and_return(true) + allow(File).to receive(:read).with("#{prefix}/path/to/module/metadata.json").and_return('{"name": "spencer-science"}') + + result = subject.execute('science') + expect(result['name']).to eq('spencer-science') + end + + it 'fails by default if there is no metadata.json' do + allow(scope).to receive(:function_get_module_path).with(['science']).and_return("#{prefix}/path/to/module/") + allow(File).to receive(:exist?).with("#{prefix}/path/to/module/metadata.json").and_return(false) + expect { subject.call(['science']) }.to raise_error(Puppet::ParseError) + end - it "should return nil if user allows empty metadata.json" do - allow(scope).to receive(:function_get_module_path).with(['science']).and_return('/path/to/module/') - allow(File).to receive(:exists?).with(/metadata.json/).and_return(false) - result = subject.call(['science', true]) - expect(result).to eq({}) + it 'returns nil if user allows empty metadata.json' do + allow(scope).to receive(:function_get_module_path).with(['science']).and_return("#{prefix}/path/to/module/") + allow(File).to receive(:exist?).with("#{prefix}/path/to/module/metadata.json").and_return(false) + result = subject.execute('science', true) + expect(result).to eq({}) + end + end end end diff --git a/spec/functions/loadjson_spec.rb b/spec/functions/loadjson_spec.rb new file mode 100644 index 000000000..17d01e451 --- /dev/null +++ b/spec/functions/loadjson_spec.rb @@ -0,0 +1,179 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'loadjson' do + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(ArgumentError, %r{wrong number of arguments}i) } + + describe 'when calling with valid arguments' do + before :each do + # In Puppet 7, there are two prior calls to File.read prior to the responses we want to mock + allow(File).to receive(:read).with(anything, anything).and_call_original + allow(File).to receive(:read).with(%r{/(stdlib|test)/metadata.json}, encoding: 'utf-8').and_return('{"name": "puppetlabs-stdlib"}') + allow(File).to receive(:read).with(%r{/(stdlib|test)/metadata.json}).and_return('{"name": "puppetlabs-stdlib"}') + # Additional modules used by litmus which are identified while running these dues to being in fixtures + allow(File).to receive(:read).with(%r{/(provision|puppet_agent|facts)/metadata.json}, encoding: 'utf-8') + end + + context 'when a non-existing file is specified' do + let(:filename) do + if Puppet::Util::Platform.windows? + 'C:/tmp/doesnotexist' + else + '/tmp/doesnotexist' + end + end + + before(:each) do + allow(File).to receive(:exist?).and_call_original + allow(File).to receive(:exist?).with(filename).and_return(false).once + if Puppet::PUPPETVERSION[0].to_i < 8 + allow(PSON).to receive(:load).never # rubocop:disable RSpec/ReceiveNever Switching to not_to receive breaks testing in this case + else + allow(JSON).to receive(:parse).never # rubocop:disable RSpec/ReceiveNever + end + end + + it { is_expected.to run.with_params(filename, 'default' => 'value').and_return('default' => 'value') } + it { is_expected.to run.with_params(filename, 'đẽƒằưļŧ' => '٧ẵłựέ').and_return('đẽƒằưļŧ' => '٧ẵłựέ') } + it { is_expected.to run.with_params(filename, 'ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆ' => '値').and_return('ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆ' => '値') } + end + + context 'when an existing file is specified' do + let(:filename) do + if Puppet::Util::Platform.windows? + 'C:/tmp/doesexist' + else + '/tmp/doesexist' + end + end + let(:data) { { 'key' => 'value', 'ķęŷ' => 'νậŀųề', 'ć‚­ćƒ¼' => '値' } } + let(:json) { '{"key":"value", {"ķęŷ":"νậŀųề" }, {"ć‚­ćƒ¼":"値" }' } + + before(:each) do + allow(File).to receive(:exist?).and_call_original + allow(File).to receive(:exist?).with(filename).and_return(true).once + allow(File).to receive(:read).with(filename).and_return(json).once + allow(File).to receive(:read).with(filename).and_return(json).once + if Puppet::PUPPETVERSION[0].to_i < 8 + allow(PSON).to receive(:load).with(json).and_return(data).once + else + allow(JSON).to receive(:parse).with(json).and_return(data).once + end + end + + it { is_expected.to run.with_params(filename).and_return(data) } + end + + context 'when the file could not be parsed' do + let(:filename) do + if Puppet::Util::Platform.windows? + 'C:/tmp/doesexist' + else + '/tmp/doesexist' + end + end + let(:json) { '{"key":"value"}' } + + before(:each) do + allow(File).to receive(:exist?).and_call_original + allow(File).to receive(:exist?).with(filename).and_return(true).once + allow(File).to receive(:read).with(filename).and_return(json).once + if Puppet::PUPPETVERSION[0].to_i < 8 + allow(PSON).to receive(:load).with(json).once.and_raise StandardError, 'Something terrible have happened!' + else + allow(JSON).to receive(:parse).with(json).once.and_raise StandardError, 'Something terrible have happened!' + end + end + + it { is_expected.to run.with_params(filename, 'default' => 'value').and_return('default' => 'value') } + end + + context 'when an existing URL is specified' do + let(:filename) do + 'https://example.local/myhash.json' + end + let(:data) { { 'key' => 'value', 'ķęŷ' => 'νậŀųề', 'ć‚­ćƒ¼' => '値' } } + let(:json) { '{"key":"value", {"ķęŷ":"νậŀųề" }, {"ć‚­ćƒ¼":"値" }' } + + it { + expect(OpenURI).to receive(:open_uri).with(filename, {}).and_return(json) + if Puppet::PUPPETVERSION[0].to_i < 8 + expect(PSON).to receive(:load).with(json).and_return(data).once + else + expect(JSON).to receive(:parse).with(json).and_return(data).once + end + expect(subject).to run.with_params(filename).and_return(data) + } + end + + context 'when an existing URL (with username and password) is specified' do + let(:filename) do + 'https://user1:pass1@example.local/myhash.json' + end + let(:url_no_auth) { 'https://example.local/myhash.json' } + let(:basic_auth) { { http_basic_authentication: ['user1', 'pass1'] } } + let(:data) { { 'key' => 'value', 'ķęŷ' => 'νậŀųề', 'ć‚­ćƒ¼' => '値' } } + let(:json) { '{"key":"value", {"ķęŷ":"νậŀųề" }, {"ć‚­ćƒ¼":"値" }' } + + it { + expect(OpenURI).to receive(:open_uri).with(url_no_auth, basic_auth).and_return(json) + if Puppet::PUPPETVERSION[0].to_i < 8 + expect(PSON).to receive(:load).with(json).and_return(data).once + else + expect(JSON).to receive(:parse).with(json).and_return(data).once + end + expect(subject).to run.with_params(filename).and_return(data) + } + end + + context 'when an existing URL (with username) is specified' do + let(:filename) do + 'https://user1@example.local/myhash.json' + end + let(:url_no_auth) { 'https://example.local/myhash.json' } + let(:basic_auth) { { http_basic_authentication: ['user1', ''] } } + let(:data) { { 'key' => 'value', 'ķęŷ' => 'νậŀųề', 'ć‚­ćƒ¼' => '値' } } + let(:json) { '{"key":"value", {"ķęŷ":"νậŀųề" }, {"ć‚­ćƒ¼":"値" }' } + + it { + expect(OpenURI).to receive(:open_uri).with(url_no_auth, basic_auth).and_return(json) + if Puppet::PUPPETVERSION[0].to_i < 8 + expect(PSON).to receive(:load).with(json).and_return(data).once + else + expect(JSON).to receive(:parse).with(json).and_return(data).once + end + expect(subject).to run.with_params(filename).and_return(data) + } + end + + context 'when the URL output could not be parsed, with default specified' do + let(:filename) do + 'https://example.local/myhash.json' + end + let(:json) { ',;{"key":"value"}' } + + it { + expect(OpenURI).to receive(:open_uri).with(filename, {}).and_return(json) + if Puppet::PUPPETVERSION[0].to_i < 8 + expect(PSON).to receive(:load).with(json).once.and_raise StandardError, 'Something terrible have happened!' + else + expect(JSON).to receive(:parse).with(json).once.and_raise StandardError, 'Something terrible have happened!' + end + expect(subject).to run.with_params(filename, 'default' => 'value').and_return('default' => 'value') + } + end + + context 'when the URL does not exist, with default specified' do + let(:filename) do + 'https://example.local/myhash.json' + end + + it { + expect(OpenURI).to receive(:open_uri).with(filename, {}).and_raise OpenURI::HTTPError, '404 File not Found' + expect(subject).to run.with_params(filename, 'default' => 'value').and_return('default' => 'value') + } + end + end +end diff --git a/spec/functions/loadyaml_spec.rb b/spec/functions/loadyaml_spec.rb old mode 100755 new mode 100644 index ffc714d11..0eff7100e --- a/spec/functions/loadyaml_spec.rb +++ b/spec/functions/loadyaml_spec.rb @@ -1,24 +1,163 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'loadyaml' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('', '').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(ArgumentError, %r{wrong number of arguments}i) } + context 'when a non-existing file is specified' do let(:filename) { '/tmp/doesnotexist' } - before { - File.expects(:exists?).with(filename).returns(false).once - YAML.expects(:load_file).never - } - it { is_expected.to run.with_params(filename).and_return(nil) } + + it "'default' => 'value'" do + allow(File).to receive(:exist?).and_call_original + expect(File).to receive(:exist?).with(filename).and_return(false).once + expect(YAML).not_to receive(:safe_load) + expect(subject).to run.with_params(filename, 'default' => 'value').and_return('default' => 'value') + end end + context 'when an existing file is specified' do - let(:filename) { '/tmp/doesexist' } - let(:data) { { 'key' => 'value' } } - before { - File.expects(:exists?).with(filename).returns(true).once - YAML.expects(:load_file).with(filename).returns(data).once + let(:tempfile) { Tempfile.new } + let(:filename) { tempfile.path } + let(:data) { { 'key' => 'value', 'ķęŷ' => 'νậŀųề', 'ć‚­ćƒ¼' => '値' } } + let(:yaml) do + <<~YAML + key: 'value' + ķęŷ: 'νậŀųề' + ć‚­ćƒ¼: '値' + YAML + end + + it "returns 'key' => 'value', 'ķęŷ' => 'νậŀųề', 'ć‚­ćƒ¼' => '値'" do + tempfile.write(yaml) + tempfile.rewind + allow(File).to receive(:exist?).and_call_original + expect(File).to receive(:exist?).with(filename).and_return(true).once + expect(YAML).to receive(:safe_load).and_call_original + expect(subject).to run.with_params(filename).and_return(data) + end + end + + context 'when the file could not be parsed, with default specified' do + let(:tempfile) { Tempfile.new } + let(:filename) { tempfile.path } + let(:yaml) do + <<~YAML + ,,,, + YAML + end + + it 'is expected to return the default value' do + tempfile.write(yaml) + tempfile.rewind + allow(File).to receive(:exist?).and_call_original + expect(File).to receive(:exist?).with(filename).and_return(true).once + allow(YAML).to receive(:safe_load).with(yaml, aliases: true).once.and_raise(StandardError, 'Something terrible have happened!') + expect(subject).to run.with_params(filename, 'default' => 'value').and_return('default' => 'value') + end + end + + context 'when an existing URL is specified' do + let(:filename) { 'https://example.local/myhash.yaml' } + let(:basic_auth) { { http_basic_authentication: ['', ''] } } + let(:yaml) { 'Dummy YAML' } + let(:data) { { 'key' => 'value', 'ķęŷ' => 'νậŀųề', 'ć‚­ćƒ¼' => '値' } } + + it { + expect(OpenURI).to receive(:open_uri).with(filename, basic_auth).and_return(yaml) + expect(YAML).to receive(:safe_load).with(yaml, aliases: true).and_return(data).once + expect(subject).to run.with_params(filename).and_return(data) + } + end + + context 'when an existing URL (with username and password) is specified' do + let(:filename) { 'https://user1:pass1@example.local/myhash.yaml' } + let(:url_no_auth) { 'https://example.local/myhash.yaml' } + let(:basic_auth) { { http_basic_authentication: ['user1', 'pass1'] } } + let(:yaml) { 'Dummy YAML' } + let(:data) { { 'key' => 'value', 'ķęŷ' => 'νậŀųề', 'ć‚­ćƒ¼' => '値' } } + + it { + expect(OpenURI).to receive(:open_uri).with(url_no_auth, basic_auth).and_return(yaml) + expect(YAML).to receive(:safe_load).with(yaml, aliases: true).and_return(data).once + expect(subject).to run.with_params(filename).and_return(data) + } + end + + context 'when an existing URL (with username) is specified' do + let(:filename) { 'https://user1@example.local/myhash.yaml' } + let(:url_no_auth) { 'https://example.local/myhash.yaml' } + let(:basic_auth) { { http_basic_authentication: ['user1', ''] } } + let(:yaml) { 'Dummy YAML' } + let(:data) { { 'key' => 'value', 'ķęŷ' => 'νậŀųề', 'ć‚­ćƒ¼' => '値' } } + + it { + expect(OpenURI).to receive(:open_uri).with(url_no_auth, basic_auth).and_return(yaml) + expect(YAML).to receive(:safe_load).with(yaml, aliases: true).and_return(data).once + expect(subject).to run.with_params(filename).and_return(data) + } + end + + context 'when an existing URL could not be parsed, with default specified' do + let(:filename) { 'https://example.local/myhash.yaml' } + let(:basic_auth) { { http_basic_authentication: ['', ''] } } + let(:yaml) { 'Dummy YAML' } + + it { + expect(OpenURI).to receive(:open_uri).with(filename, basic_auth).and_return(yaml) + expect(YAML).to receive(:safe_load).with(yaml, aliases: true).and_raise StandardError, 'Cannot parse data' + expect(subject).to run.with_params(filename, 'default' => 'value').and_return('default' => 'value') + } + end + + context 'when a URL does not exist, with default specified' do + let(:filename) { 'https://example.local/myhash.yaml' } + let(:basic_auth) { { http_basic_authentication: ['', ''] } } + let(:yaml) { 'Dummy YAML' } + + it { + expect(OpenURI).to receive(:open_uri).with(filename, basic_auth).and_raise OpenURI::HTTPError, '404 File not Found' + expect(subject).to run.with_params(filename, 'default' => 'value').and_return('default' => 'value') + } + end + + context 'when the file contains aliases' do + let(:tempfile) { Tempfile.new } + let(:filename) { tempfile.path } + let(:yaml) do + <<~YAML + some_numbers: &nums + - one + - two + more_numbers: *nums + YAML + end + let(:data) { { 'some_numbers' => ['one', 'two'], 'more_numbers' => ['one', 'two'] } } + + it 'parses the aliases' do + tempfile.write(yaml) + tempfile.rewind + expect(subject).to run.with_params(filename).and_return(data) + end + end + + context 'when a URL returns yaml with aliases' do + let(:filename) { 'https://example.local/myhash.yaml' } + let(:basic_auth) { { http_basic_authentication: ['', ''] } } + let(:yaml) do + <<~YAML + some_numbers: &nums + - one + - two + more_numbers: *nums + YAML + end + let(:data) { { 'some_numbers' => ['one', 'two'], 'more_numbers' => ['one', 'two'] } } + + it { + expect(OpenURI).to receive(:open_uri).with(filename, basic_auth).and_return(yaml) + expect(subject).to run.with_params(filename).and_return(data) } - it { is_expected.to run.with_params(filename).and_return(data) } end end diff --git a/spec/functions/lstrip_spec.rb b/spec/functions/lstrip_spec.rb deleted file mode 100755 index 981794edf..000000000 --- a/spec/functions/lstrip_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -require 'spec_helper' - -describe 'lstrip' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { - pending("Current implementation ignores parameters after the first.") - is_expected.to run.with_params('', '').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) - } - it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, /Requires either array or string to work with/) } - it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /Requires either array or string to work with/) } - it { is_expected.to run.with_params('').and_return('') } - it { is_expected.to run.with_params(' ').and_return('') } - it { is_expected.to run.with_params(' ').and_return('') } - it { is_expected.to run.with_params("\t").and_return('') } - it { is_expected.to run.with_params("\t ").and_return('') } - it { is_expected.to run.with_params('one').and_return('one') } - it { is_expected.to run.with_params(' one').and_return('one') } - it { is_expected.to run.with_params(' one').and_return('one') } - it { is_expected.to run.with_params("\tone").and_return('one') } - it { is_expected.to run.with_params("\t one").and_return('one') } - it { is_expected.to run.with_params('one ').and_return('one ') } - it { is_expected.to run.with_params(' one ').and_return('one ') } - it { is_expected.to run.with_params(' one ').and_return('one ') } - it { is_expected.to run.with_params("\tone ").and_return('one ') } - it { is_expected.to run.with_params("\t one ").and_return('one ') } - it { is_expected.to run.with_params("one \t").and_return("one \t") } - it { is_expected.to run.with_params(" one \t").and_return("one \t") } - it { is_expected.to run.with_params(" one \t").and_return("one \t") } - it { is_expected.to run.with_params("\tone \t").and_return("one \t") } - it { is_expected.to run.with_params("\t one \t").and_return("one \t") } - it { is_expected.to run.with_params(' o n e ').and_return('o n e ') } - it { is_expected.to run.with_params(AlsoString.new(' one ')).and_return('one ') } -end diff --git a/spec/functions/max_spec.rb b/spec/functions/max_spec.rb deleted file mode 100755 index 66fb0c869..000000000 --- a/spec/functions/max_spec.rb +++ /dev/null @@ -1,21 +0,0 @@ -require 'spec_helper' - -describe 'max' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params(1).and_return(1) } - it { is_expected.to run.with_params(1, 2).and_return(2) } - it { is_expected.to run.with_params(1, 2, 3).and_return(3) } - it { is_expected.to run.with_params(3, 2, 1).and_return(3) } - it { is_expected.to run.with_params('one').and_return('one') } - it { is_expected.to run.with_params('one', 'two').and_return('two') } - it { is_expected.to run.with_params('one', 'two', 'three').and_return('two') } - it { is_expected.to run.with_params('three', 'two', 'one').and_return('two') } - - describe 'implementation artifacts' do - it { is_expected.to run.with_params(1, 'one').and_return('one') } - it { is_expected.to run.with_params('1', 'one').and_return('one') } - it { is_expected.to run.with_params('1.3e1', '1.4e0').and_return('1.4e0') } - it { is_expected.to run.with_params(1.3e1, 1.4e0).and_return(1.3e1) } - end -end diff --git a/spec/functions/member_spec.rb b/spec/functions/member_spec.rb old mode 100755 new mode 100644 index 527f887fa..244c2eea5 --- a/spec/functions/member_spec.rb +++ b/spec/functions/member_spec.rb @@ -1,13 +1,17 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'member' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { - pending("Current implementation ignores parameters after the first.") - is_expected.to run.with_params([], [], []).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) + pending('Current implementation ignores parameters after the first.') + expect(subject).to run.with_params([], [], []).and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params([], '').and_return(false) } it { is_expected.to run.with_params([], ['']).and_return(false) } it { is_expected.to run.with_params([''], '').and_return(true) } @@ -17,5 +21,9 @@ it { is_expected.to run.with_params(['one'], 'one').and_return(true) } it { is_expected.to run.with_params(['one'], ['one']).and_return(true) } it { is_expected.to run.with_params(['one', 'two', 'three', 'four'], ['four', 'two']).and_return(true) } + it { is_expected.to run.with_params([1, 2, 3, 4], [4, 2]).and_return(true) } + it { is_expected.to run.with_params([1, 'a', 'b', 4], [4, 'b']).and_return(true) } + it { is_expected.to run.with_params(['į»×Ö¼įŗ¹', 'ŧẅồ', 'ţҺŗęē', 'Ę’Ę”ŃŸÅ•'], ['Ę’Ę”ŃŸÅ•', 'ŧẅồ']).and_return(true) } it { is_expected.to run.with_params(['one', 'two', 'three', 'four'], ['four', 'five']).and_return(false) } + it { is_expected.to run.with_params(['į»×Ö¼įŗ¹', 'ŧẅồ', 'ţҺŗęē', 'Ę’Ę”ŃŸÅ•'], ['Ę’Ę”ŃŸÅ•', 'Ę’ĪÆāˆšÉ™']).and_return(false) } end diff --git a/spec/functions/merge_spec.rb b/spec/functions/merge_spec.rb old mode 100755 new mode 100644 index 7b53363ed..cbe00ee10 --- a/spec/functions/merge_spec.rb +++ b/spec/functions/merge_spec.rb @@ -1,25 +1,92 @@ +# frozen_string_literal: true + require 'spec_helper' -describe 'merge' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params({}, 'two').and_raise_error(Puppet::ParseError, /unexpected argument type String/) } - it { is_expected.to run.with_params({}, 1).and_raise_error(Puppet::ParseError, /unexpected argument type Fixnum/) } +describe 'stdlib::merge' do + it { is_expected.not_to be_nil } + + it { + expect(subject).to run \ + .with_params({}, 'two') \ + .and_raise_error( + ArgumentError, \ + Regexp.new(Regexp.escape("rejected: parameter 'args' expects a value of type Undef, Hash[Scalar, Any], or String[0, 0], got String")), + ) + } + it { - pending 'should not special case this' - is_expected.to run.with_params({}).and_return({}) + expect(subject).to run \ + .with_params({}, 1) \ + .and_raise_error(ArgumentError, %r{parameter 'args' expects a value of type Undef, Hash, or String, got Integer}) } + + it { + expect(subject).to run \ + .with_params({ 'one' => 1, 'three' => { 'four' => 4 } }, 'two' => 'dos', 'three' => { 'five' => 5 }) \ + .and_return('one' => 1, 'three' => { 'five' => 5 }, 'two' => 'dos') + } + + it { is_expected.to run.with_params.and_return({}) } + it { is_expected.to run.with_params({}).and_return({}) } it { is_expected.to run.with_params({}, {}).and_return({}) } it { is_expected.to run.with_params({}, {}, {}).and_return({}) } + describe 'should accept empty strings as puppet undef' do it { is_expected.to run.with_params({}, '').and_return({}) } end - it { is_expected.to run.with_params({ 'key' => 'value' }, {}).and_return({ 'key' => 'value' }) } - it { is_expected.to run.with_params({}, { 'key' => 'value' }).and_return({ 'key' => 'value' }) } - it { is_expected.to run.with_params({ 'key' => 'value1' }, { 'key' => 'value2' }).and_return({ 'key' => 'value2' }) } + + it { is_expected.to run.with_params({ 'key' => 'value' }, {}).and_return('key' => 'value') } + it { is_expected.to run.with_params({}, 'key' => 'value').and_return('key' => 'value') } + it { is_expected.to run.with_params({ 'key' => 'value1' }, 'key' => 'value2').and_return('key' => 'value2') } + it { - is_expected.to run \ - .with_params({ 'key1' => 'value1' }, { 'key2' => 'value2' }, { 'key3' => 'value3' }) \ - .and_return({ 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3' }) + expect(subject).to run \ + .with_params({ 'key1' => 'value1' }, { 'key2' => 'value2' }, 'key3' => 'value3') \ + .and_return('key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3') } + + describe 'should accept iterable and merge produced hashes' do + it { + expect(subject).to run \ + .with_params([1, 2, 3]) \ + .with_lambda { |_hsh, val| { val => val } } \ + .and_return(1 => 1, 2 => 2, 3 => 3) + } + + it { + expect(subject).to run \ + .with_params([1, 2, 3]) \ + .with_lambda { |_hsh, val| { val => val } unless val == 2 } \ + .and_return(1 => 1, 3 => 3) + } + + it { + expect(subject).to run \ + .with_params([1, 2, 3]) \ + # rubocop:disable Style/Semicolon + .with_lambda { |_hsh, val| raise StopIteration if val == 3; { val => val } } \ + .and_return(1 => 1, 2 => 2) + } + + it { + expect(subject).to run \ + .with_params(['a', 'b', 'b', 'c', 'b']) \ + .with_lambda { |hsh, val| { val => (hsh[val] || 0) + 1 } } \ + .and_return('a' => 1, 'b' => 3, 'c' => 1) + } + + it { + expect(subject).to run \ + .with_params(['a', 'b', 'c']) \ + .with_lambda { |_hsh, idx, val| { idx => val } } \ + .and_return(0 => 'a', 1 => 'b', 2 => 'c') + } + + it { + expect(subject).to run \ + .with_params('a' => 'A', 'b' => 'B', 'c' => 'C') \ + .with_lambda { |_hsh, key, val| { key => "#{key}#{val}" } } \ + .and_return('a' => 'aA', 'b' => 'bB', 'c' => 'cC') + } + end end diff --git a/spec/functions/min_spec.rb b/spec/functions/min_spec.rb deleted file mode 100755 index c840a72c9..000000000 --- a/spec/functions/min_spec.rb +++ /dev/null @@ -1,21 +0,0 @@ -require 'spec_helper' - -describe 'min' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params(1).and_return(1) } - it { is_expected.to run.with_params(1, 2).and_return(1) } - it { is_expected.to run.with_params(1, 2, 3).and_return(1) } - it { is_expected.to run.with_params(3, 2, 1).and_return(1) } - it { is_expected.to run.with_params('one').and_return('one') } - it { is_expected.to run.with_params('one', 'two').and_return('one') } - it { is_expected.to run.with_params('one', 'two', 'three').and_return('one') } - it { is_expected.to run.with_params('three', 'two', 'one').and_return('one') } - - describe 'implementation artifacts' do - it { is_expected.to run.with_params(1, 'one').and_return(1) } - it { is_expected.to run.with_params('1', 'one').and_return('1') } - it { is_expected.to run.with_params('1.3e1', '1.4e0').and_return('1.3e1') } - it { is_expected.to run.with_params(1.3e1, 1.4e0).and_return(1.4e0) } - end -end diff --git a/spec/functions/nested_values_spec.rb b/spec/functions/nested_values_spec.rb new file mode 100644 index 000000000..93ebabfbc --- /dev/null +++ b/spec/functions/nested_values_spec.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'stdlib::nested_values' do + it { is_expected.to run.with_params({}).and_return([]) } + it { is_expected.to run.with_params({ 'key' => 'value' }).and_return(['value']) } + it { is_expected.to run.with_params({ 'key' => { 'key1' => 'value1', 'key2' => 'value2' } }).and_return(['value1', 'value2']) } + it { is_expected.to run.with_params({ 'key1' => 'value1', 'key2' => { 'key1' => 'value21', 'key2' => 'value22' }, 'key3' => 'value3' }).and_return(['value1', 'value21', 'value22', 'value3']) } + it { is_expected.to run.with_params(2).and_raise_error(StandardError) } + it { is_expected.to run.with_params(nil).and_raise_error(StandardError) } +end diff --git a/spec/functions/num2bool_spec.rb b/spec/functions/num2bool_spec.rb old mode 100755 new mode 100644 index 494afff9f..ad87b45f0 --- a/spec/functions/num2bool_spec.rb +++ b/spec/functions/num2bool_spec.rb @@ -1,10 +1,12 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'num2bool' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params(1, 2).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('abc').and_raise_error(Puppet::ParseError, /does not look like a number/) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params(1, 2).and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params('abc').and_raise_error(Puppet::ParseError, %r{does not look like a number}) } it { is_expected.to run.with_params(1).and_return(true) } it { is_expected.to run.with_params('1').and_return(true) } it { is_expected.to run.with_params(1.5).and_return(true) } @@ -16,7 +18,8 @@ it { is_expected.to run.with_params(0).and_return(false) } it { is_expected.to run.with_params('0').and_return(false) } it { is_expected.to run.with_params([]).and_return(false) } - it { is_expected.to run.with_params('[]').and_raise_error(Puppet::ParseError, /does not look like a number/) } + it { is_expected.to run.with_params('[]').and_raise_error(Puppet::ParseError, %r{does not look like a number}) } it { is_expected.to run.with_params({}).and_return(false) } - it { is_expected.to run.with_params('{}').and_raise_error(Puppet::ParseError, /does not look like a number/) } + it { is_expected.to run.with_params('{}').and_raise_error(Puppet::ParseError, %r{does not look like a number}) } + it { is_expected.to run.with_params(['-50', '1']).and_return(false) } end diff --git a/spec/functions/os_version_gte_spec.rb b/spec/functions/os_version_gte_spec.rb new file mode 100644 index 000000000..e1ee6e41a --- /dev/null +++ b/spec/functions/os_version_gte_spec.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'stdlib::os_version_gte' do + context 'on Debian 9' do + let(:facts) do + { + os: { + name: 'Debian', + release: { major: '9' } + } + } + end + + it { is_expected.to run.with_params('Debian', '10').and_return(false) } + it { is_expected.to run.with_params('Debian', '9').and_return(true) } + it { is_expected.to run.with_params('Debian', '8').and_return(true) } + it { is_expected.to run.with_params('Debian', '8.0').and_return(true) } + it { is_expected.to run.with_params('Ubuntu', '16.04').and_return(false) } + it { is_expected.to run.with_params('Fedora', '29').and_return(false) } + end + + context 'on Ubuntu 16.04' do + let(:facts) do + { + os: { + name: 'Ubuntu', + release: { major: '16.04' } + } + } + end + + it { is_expected.to run.with_params('Debian', '9').and_return(false) } + it { is_expected.to run.with_params('Ubuntu', '16').and_return(true) } + it { is_expected.to run.with_params('Ubuntu', '14.04').and_return(true) } + it { is_expected.to run.with_params('Ubuntu', '16.04').and_return(true) } + it { is_expected.to run.with_params('Ubuntu', '18.04').and_return(false) } + it { is_expected.to run.with_params('Ubuntu', '20.04').and_return(false) } + it { is_expected.to run.with_params('Fedora', '29').and_return(false) } + end + + context 'with invalid params' do + let(:facts) do + { + os: { + name: 'Ubuntu', + release: { major: '16.04' } + } + } + end + + it { is_expected.to run.with_params('123', 'abc').and_return(false) } + it { is_expected.to run.with_params([], 123).and_raise_error(ArgumentError) } + end +end diff --git a/spec/functions/parsehocon_spec.rb b/spec/functions/parsehocon_spec.rb new file mode 100644 index 000000000..6448cbc5b --- /dev/null +++ b/spec/functions/parsehocon_spec.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'stdlib::parsehocon' do + it { is_expected.to run.with_params('').and_return({}) } + it { is_expected.to run.with_params('valid hocon: string').and_return('valid hocon' => 'string') } + it { is_expected.to run.with_params('invalid').and_raise_error(Hocon::ConfigError::ConfigParseError) } + it { is_expected.to run.with_params('invalid', 'default').and_return('default') } +end diff --git a/spec/functions/parsejson_spec.rb b/spec/functions/parsejson_spec.rb old mode 100755 new mode 100644 index a01f1f67b..6db0f9d95 --- a/spec/functions/parsejson_spec.rb +++ b/spec/functions/parsejson_spec.rb @@ -1,64 +1,76 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'parsejson' do - it 'should exist' do - is_expected.not_to eq(nil) + it 'exists' do + expect(subject).not_to be_nil end - it 'should raise an error if called without any arguments' do - is_expected.to run.with_params(). - and_raise_error(/wrong number of arguments/i) + it 'raises an error if called without any arguments' do + expect(subject).to run.with_params + .and_raise_error(%r{wrong number of arguments}i) end context 'with correct JSON data' do + it 'is able to parse JSON this is a null' do + expect(subject).to run.with_params('null').and_return(nil) + end + + it 'is able to parse JSON that is a string' do + expect(subject).to run.with_params('"a string"').and_return('a string') + end - it 'should be able to parse a JSON data with a Hash' do - is_expected.to run.with_params('{"a":"1","b":"2"}'). - and_return({'a'=>'1', 'b'=>'2'}) + it 'is able to parse JSON data with a Hash' do + expect(subject).to run.with_params('{"a":"1","b":"2"}') + .and_return('a' => '1', 'b' => '2') end - it 'should be able to parse a JSON data with an Array' do - is_expected.to run.with_params('["a","b","c"]'). - and_return(['a', 'b', 'c']) + it 'is able to parse JSON data with an Array' do + expect(subject).to run.with_params('["a","b","c"]') + .and_return(['a', 'b', 'c']) end - it 'should be able to parse empty JSON values' do - is_expected.to run.with_params('[]'). - and_return([]) - is_expected.to run.with_params('{}'). - and_return({}) + it 'is able to parse empty JSON values' do + actual_array = ['[]', '{}'] + expected = [[], {}] + actual_array.each_with_index do |actual, index| + expect(subject).to run.with_params(actual).and_return(expected[index]) + end end - it 'should be able to parse a JSON data with a mixed structure' do - is_expected.to run.with_params('{"a":"1","b":2,"c":{"d":[true,false]}}'). - and_return({'a' =>'1', 'b' => 2, 'c' => { 'd' => [true, false] } }) + it 'is able to parse JSON data with a mixed structure' do + expect(subject).to run.with_params('{"a":"1","b":2,"c":{"d":[true,false]}}') + .and_return('a' => '1', 'b' => 2, 'c' => { 'd' => [true, false] }) end - it 'should not return the default value if the data was parsed correctly' do - is_expected.to run.with_params('{"a":"1"}', 'default_value'). - and_return({'a' => '1'}) + it 'is able to parse JSON data with a UTF8 and double byte characters' do + expect(subject).to run.with_params('{"Ɨ":"恓悌","ý":"čØ˜å·","恧恙":{"Ā©":["Ɓ","ß"]}}') + .and_return('Ɨ' => '恓悌', 'ý' => 'čØ˜å·', '恧恙' => { 'Ā©' => ['Ɓ', 'ß'] }) end + it 'does not return the default value if the data was parsed correctly' do + expect(subject).to run.with_params('{"a":"1"}', 'default_value') + .and_return('a' => '1') + end end context 'with incorrect JSON data' do - it 'should raise an error with invalid JSON and no default' do - is_expected.to run.with_params(''). - and_raise_error(PSON::ParserError) + it 'raises an error with invalid JSON and no default' do + expect(subject).to run.with_params('error') + .and_raise_error(Puppet::Util::Json::ParseError) end - it 'should support a structure for a default value' do - is_expected.to run.with_params('', {'a' => '1'}). - and_return({'a' => '1'}) + it 'supports a structure for a default value' do + expect(subject).to run.with_params('', 'a' => '1') + .and_return('a' => '1') end - ['', 1, 1.2, nil, true, false, [], {}, :yaml].each do |value| - it "should return the default value for an incorrect #{value.inspect} (#{value.class}) parameter" do - is_expected.to run.with_params(value, 'default_value'). - and_return('default_value') + [1, 1.2, nil, true, false, [], {}, :yaml].each do |value| + it "returns the default value for an incorrect #{value.inspect} (#{value.class}) parameter" do + expect(subject).to run.with_params(value, 'default_value') + .and_return('default_value') end end - end - end diff --git a/spec/functions/parsepson_spec.rb b/spec/functions/parsepson_spec.rb new file mode 100644 index 000000000..cff940c84 --- /dev/null +++ b/spec/functions/parsepson_spec.rb @@ -0,0 +1,73 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'parsepson' do + if Puppet::Util::Package.versioncmp(Puppet.version, '8.0.0').negative? + it 'exists' do + expect(subject).not_to be_nil + end + + it 'raises an error if called without any arguments' do + expect(subject).to run.with_params + .and_raise_error(%r{'parsepson' expects between 1 and 2 arguments, got none}i) + end + + context 'with correct PSON data' do + it 'is able to parse PSON data with a Hash' do + expect(subject).to run.with_params('{"a":"1","b":"2"}') + .and_return('a' => '1', 'b' => '2') + end + + it 'is able to parse PSON data with an Array' do + expect(subject).to run.with_params('["a","b","c"]') + .and_return(['a', 'b', 'c']) + end + + it 'is able to parse empty PSON values' do + actual_array = ['[]', '{}'] + expected = [[], {}] + actual_array.each_with_index do |actual, index| + expect(subject).to run.with_params(actual).and_return(expected[index]) + end + end + + it 'is able to parse PSON data with a mixed structure' do + expect(subject).to run.with_params('{"a":"1","b":2,"c":{"d":[true,false]}}') + .and_return('a' => '1', 'b' => 2, 'c' => { 'd' => [true, false] }) + end + + it 'is able to parse PSON data with a UTF8 and double byte characters' do + expect(subject).to run.with_params('{"Ɨ":"恓悌","ý":"čØ˜å·","恧恙":{"Ā©":["Ɓ","ß"]}}') + .and_return('Ɨ' => '恓悌', 'ý' => 'čØ˜å·', '恧恙' => { 'Ā©' => ['Ɓ', 'ß'] }) + end + + it 'does not return the default value if the data was parsed correctly' do + expect(subject).to run.with_params('{"a":"1"}', 'default_value') + .and_return('a' => '1') + end + end + + context 'with incorrect PSON data' do + it 'raises an error with invalid PSON and no default' do + expect(subject).to run.with_params('invalid') + .and_raise_error(PSON::ParserError) + end + + it 'returns the default value for an invalid PSON and a given default' do + expect(subject).to run.with_params('invalid', 'default_value') + .and_return('default_value') + end + + it 'supports a structure for a default value' do + expect(subject).to run.with_params('invalid', 'a' => '1') + .and_return('a' => '1') + end + end + end + if Puppet::Util::Package.versioncmp(Puppet.version, '8.0.0').positive? + it 'doesnt work on Puppet 8' do + expect(subject).to run.with_params('{"a":"1","b":"2"}').and_return(nil) + end + end +end diff --git a/spec/functions/parseyaml_spec.rb b/spec/functions/parseyaml_spec.rb old mode 100755 new mode 100644 index fa947ca6a..2096f4758 --- a/spec/functions/parseyaml_spec.rb +++ b/spec/functions/parseyaml_spec.rb @@ -1,81 +1,76 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'parseyaml' do - it 'should exist' do - is_expected.not_to eq(nil) + it 'exists' do + expect(subject).not_to be_nil end - it 'should raise an error if called without any arguments' do - is_expected.to run.with_params(). - and_raise_error(/wrong number of arguments/i) + it 'raises an error if called without any arguments' do + expect(subject).to run.with_params + .and_raise_error(%r{wrong number of arguments}i) end context 'with correct YAML data' do - it 'should be able to parse a YAML data with a String' do - is_expected.to run.with_params('--- just a string'). - and_return('just a string') - is_expected.to run.with_params('just a string'). - and_return('just a string') + it 'is able to parse a YAML data with a String' do + actual_array = ['--- just a string', 'just a string'] + actual_array.each do |actual| + expect(subject).to run.with_params(actual).and_return('just a string') + end end - it 'should be able to parse a YAML data with a Hash' do - is_expected.to run.with_params("---\na: '1'\nb: '2'\n"). - and_return({'a' => '1', 'b' => '2'}) + it 'is able to parse YAML data with a Hash' do + expect(subject).to run.with_params("---\na: '1'\nb: '2'\n") + .and_return('a' => '1', 'b' => '2') end - it 'should be able to parse a YAML data with an Array' do - is_expected.to run.with_params("---\n- a\n- b\n- c\n"). - and_return(['a', 'b', 'c']) + it 'is able to parse YAML data with an Array' do + expect(subject).to run.with_params("---\n- a\n- b\n- c\n") + .and_return(['a', 'b', 'c']) end - it 'should be able to parse a YAML data with a mixed structure' do - is_expected.to run.with_params("---\na: '1'\nb: 2\nc:\n d:\n - :a\n - true\n - false\n"). - and_return({'a' => '1', 'b' => 2, 'c' => {'d' => [:a, true, false]}}) + it 'is able to parse YAML data with a mixed structure' do + expect(subject).to run.with_params("---\na: '1'\nb: 2\nc:\n d:\n - :a\n - true\n - false\n") + .and_return('a' => '1', 'b' => 2, 'c' => { 'd' => [:a, true, false] }) end - it 'should not return the default value if the data was parsed correctly' do - is_expected.to run.with_params("---\na: '1'\n", 'default_value'). - and_return({'a' => '1'}) + it 'is able to parse YAML data with a UTF8 and double byte characters' do + expect(subject).to run.with_params("---\na: Ɨ\n恓悌: čØ˜å·\n恧恙:\n Ā©:\n - Ɓ\n - ß\n") + .and_return('a' => 'Ɨ', '恓悌' => 'čØ˜å·', '恧恙' => { 'Ā©' => ['Ɓ', 'ß'] }) end - end - - context 'on a modern ruby', :unless => RUBY_VERSION == '1.8.7' do - it 'should raise an error with invalid YAML and no default' do - is_expected.to run.with_params('["one"'). - and_raise_error(Psych::SyntaxError) + it 'does not return the default value if the data was parsed correctly' do + expect(subject).to run.with_params("---\na: '1'\n", 'default_value') + .and_return('a' => '1') end end - context 'when running on ruby 1.8.7, which does not have Psych', :if => RUBY_VERSION == '1.8.7' do - it 'should raise an error with invalid YAML and no default' do - is_expected.to run.with_params('["one"'). - and_raise_error(ArgumentError) - end - end + it 'raises an error with invalid YAML and no default' do + expect(subject).to run.with_params('["one"') + .and_raise_error(Psych::SyntaxError) + end context 'with incorrect YAML data' do - it 'should support a structure for a default value' do - is_expected.to run.with_params('', {'a' => '1'}). - and_return({'a' => '1'}) + it 'supports a structure for a default value' do + expect(subject).to run.with_params('', 'a' => '1') + .and_return('a' => '1') end [1, 1.2, nil, true, false, [], {}, :yaml].each do |value| - it "should return the default value for an incorrect #{value.inspect} (#{value.class}) parameter" do - is_expected.to run.with_params(value, 'default_value'). - and_return('default_value') + it "returns the default value for an incorrect #{value.inspect} (#{value.class}) parameter" do + expect(subject).to run.with_params(value, 'default_value') + .and_return('default_value') end end - context 'when running on modern rubies', :unless => RUBY_VERSION == '1.8.7' do + context 'when running on modern rubies' do ['---', '...', '*8', ''].each do |value| - it "should return the default value for an incorrect #{value.inspect} string parameter" do - is_expected.to run.with_params(value, 'default_value'). - and_return('default_value') + it "returns the default value for an incorrect #{value.inspect} string parameter" do + expect(subject).to run.with_params(value, 'default_value') + .and_return('default_value') end end end - end - end diff --git a/spec/functions/pick_default_spec.rb b/spec/functions/pick_default_spec.rb old mode 100755 new mode 100644 index e2fc64a11..5062596dd --- a/spec/functions/pick_default_spec.rb +++ b/spec/functions/pick_default_spec.rb @@ -1,24 +1,42 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'pick_default' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::Error, /Must receive at least one argument/) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(RuntimeError, %r{Must receive at least one argument}) } it { is_expected.to run.with_params('one', 'two').and_return('one') } + it { is_expected.to run.with_params('ớņệ', 'ńωƔ').and_return('ớņệ') } it { is_expected.to run.with_params('', 'two').and_return('two') } it { is_expected.to run.with_params(:undef, 'two').and_return('two') } it { is_expected.to run.with_params(:undefined, 'two').and_return('two') } it { is_expected.to run.with_params(nil, 'two').and_return('two') } - [ '', :undef, :undefined, nil, {}, [], 1, 'default' ].each do |value| + ['', :undef, :undefined, nil, {}, [], 1, 'default'].each do |value| describe "when providing #{value.inspect} as default" do it { is_expected.to run.with_params('one', value).and_return('one') } + it { is_expected.to run.with_params('ớņệ', value).and_return('ớņệ') } it { is_expected.to run.with_params([], value).and_return([]) } it { is_expected.to run.with_params({}, value).and_return({}) } - it { is_expected.to run.with_params(value, value).and_return(value) } - it { is_expected.to run.with_params(:undef, value).and_return(value) } - it { is_expected.to run.with_params(:undefined, value).and_return(value) } - it { is_expected.to run.with_params(nil, value).and_return(value) } + it { is_expected.to run.with_params(value, value).and_return(mapped_value(value)) } + it { is_expected.to run.with_params(:undef, value).and_return(mapped_value(value)) } + it { is_expected.to run.with_params(:undefined, value).and_return(mapped_value(value)) } + it { is_expected.to run.with_params(nil, value).and_return(mapped_value(value)) } + end + end + + if Puppet::Util::Package.versioncmp(Puppet.version, '6.0.0') < 0 || + Puppet::Util::Package.versioncmp(Puppet.version, '5.5.7') == 0 + def mapped_value(v) + v + end + else + def mapped_value(v) + # Puppet 6.0.0 will always map arguments the same way as the Puppet Language + # even if function is called from Ruby via call_function + # The 3x function API expects nil and :undef to be represented as empty string + (v.nil? || v == :undef) ? '' : v end end end diff --git a/spec/functions/pick_spec.rb b/spec/functions/pick_spec.rb old mode 100755 new mode 100644 index 2c7caa87e..5e6ed1bde --- a/spec/functions/pick_spec.rb +++ b/spec/functions/pick_spec.rb @@ -1,12 +1,19 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'pick' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /must receive at least one non empty value/) } - it { is_expected.to run.with_params('', nil, :undef, :undefined).and_raise_error(Puppet::ParseError, /must receive at least one non empty value/) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{must receive at least one non empty value}) } + it { is_expected.to run.with_params('', nil, :undef, :undefined).and_raise_error(Puppet::ParseError, %r{must receive at least one non empty value}) } it { is_expected.to run.with_params('one', 'two').and_return('one') } it { is_expected.to run.with_params('', 'two').and_return('two') } it { is_expected.to run.with_params(:undef, 'two').and_return('two') } it { is_expected.to run.with_params(:undefined, 'two').and_return('two') } it { is_expected.to run.with_params(nil, 'two').and_return('two') } + + context 'with UTF8 and double byte characters' do + it { is_expected.to run.with_params(nil, 'ć“ć®ćƒ†ć‚­ć‚¹ćƒˆ').and_return('ć“ć®ćƒ†ć‚­ć‚¹ćƒˆ') } + it { is_expected.to run.with_params('', 'Åįŗ³Š¼Ń€Å‚į» ŃŸÅ£Ę’8 ţẽ×ń', 'ć“ć®ćƒ†ć‚­ć‚¹ćƒˆ').and_return('Åįŗ³Š¼Ń€Å‚į» ŃŸÅ£Ę’8 ţẽ×ń') } + end end diff --git a/spec/functions/powershell_escape_spec.rb b/spec/functions/powershell_escape_spec.rb new file mode 100644 index 000000000..20340e741 --- /dev/null +++ b/spec/functions/powershell_escape_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'stdlib::powershell_escape' do + it { is_expected.not_to be_nil } + + describe 'signature validation' do + it { is_expected.to run.with_params.and_raise_error(ArgumentError, %r{'stdlib::powershell_escape' expects 1 argument, got none}) } + it { is_expected.to run.with_params('foo', 'bar').and_raise_error(ArgumentError, %r{'stdlib::powershell_escape' expects 1 argument, got 2}) } + end + + describe 'stringification' do + it { is_expected.to run.with_params(10).and_return('10') } + it { is_expected.to run.with_params(false).and_return('false') } + end + + describe 'escaping' do + it { is_expected.to run.with_params('foo').and_return('foo') } + it { is_expected.to run.with_params('foo bar').and_return('foo` bar') } + + it { + expect(subject).to run.with_params('~`!@#$%^&*()_-=[]\{}|;\':",./<>?') + .and_return('~``!@#`$%^&*()_-=[]\{}`|;`\':\\`",./<>?') + } + end +end diff --git a/spec/functions/prefix_spec.rb b/spec/functions/prefix_spec.rb old mode 100755 new mode 100644 index 37610221a..0615a3f11 --- a/spec/functions/prefix_spec.rb +++ b/spec/functions/prefix_spec.rb @@ -1,28 +1,34 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'prefix' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { - pending("Current implementation ignores parameters after the second.") - is_expected.to run.with_params([], 'a', '').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) + pending('Current implementation ignores parameters after the second.') + expect(subject).to run.with_params([], 'a', '').and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } - it { is_expected.to run.with_params('', '').and_raise_error(Puppet::ParseError, /expected first argument to be an Array or a Hash/) } - it { is_expected.to run.with_params([], 2).and_raise_error(Puppet::ParseError, /expected second argument to be a String/) } + + it { is_expected.to run.with_params('', '').and_raise_error(Puppet::ParseError, %r{expected first argument to be an Array or a Hash}) } + it { is_expected.to run.with_params([], 2).and_raise_error(Puppet::ParseError, %r{expected second argument to be a String}) } it { is_expected.to run.with_params([]).and_return([]) } it { is_expected.to run.with_params(['one', 2]).and_return(['one', '2']) } + it { is_expected.to run.with_params(['ớņệ', 2]).and_return(['ớņệ', '2']) } it { is_expected.to run.with_params([], '').and_return([]) } it { is_expected.to run.with_params([''], '').and_return(['']) } it { is_expected.to run.with_params(['one'], 'pre').and_return(['preone']) } it { is_expected.to run.with_params(['one', 'two', 'three'], 'pre').and_return(['preone', 'pretwo', 'prethree']) } it { is_expected.to run.with_params({}).and_return({}) } - it { is_expected.to run.with_params({ 'key1' => 'value1', 2 => 3}).and_return({ 'key1' => 'value1', '2' => 3 }) } + it { is_expected.to run.with_params('key1' => 'value1', 2 => 3).and_return('key1' => 'value1', '2' => 3) } it { is_expected.to run.with_params({}, '').and_return({}) } - it { is_expected.to run.with_params({ 'key' => 'value' }, '').and_return({ 'key' => 'value' }) } - it { is_expected.to run.with_params({ 'key' => 'value' }, 'pre').and_return({ 'prekey' => 'value' }) } + it { is_expected.to run.with_params({ 'key' => 'value' }, '').and_return('key' => 'value') } + it { is_expected.to run.with_params({ 'key' => 'value' }, 'pre').and_return('prekey' => 'value') } + it { - is_expected.to run \ + expect(subject).to run \ .with_params({ 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3' }, 'pre') \ - .and_return({ 'prekey1' => 'value1', 'prekey2' => 'value2', 'prekey3' => 'value3' }) + .and_return('prekey1' => 'value1', 'prekey2' => 'value2', 'prekey3' => 'value3') } end diff --git a/spec/functions/private_spec.rb b/spec/functions/private_spec.rb deleted file mode 100644 index a13be6439..000000000 --- a/spec/functions/private_spec.rb +++ /dev/null @@ -1,56 +0,0 @@ -require 'spec_helper' - -describe 'private' do - it 'should issue a warning' do - scope.expects(:warning).with("private() DEPRECATED: This function will cease to function on Puppet 4; please use assert_private() before upgrading to puppet 4 for backwards-compatibility, or migrate to the new parser's typing system.") - begin - subject.call [] - rescue - # ignore this - end - end - - context "when called from inside module" do - it "should not fail" do - scope.expects(:lookupvar).with('module_name').returns('foo') - scope.expects(:lookupvar).with('caller_module_name').returns('foo') - expect { - subject.call [] - }.not_to raise_error - end - end - - context "with an explicit failure message" do - it "prints the failure message on error" do - scope.expects(:lookupvar).with('module_name').returns('foo') - scope.expects(:lookupvar).with('caller_module_name').returns('bar') - expect { - subject.call ['failure message!'] - }.to raise_error Puppet::ParseError, /failure message!/ - end - end - - context "when called from private class" do - it "should fail with a class error message" do - scope.expects(:lookupvar).with('module_name').returns('foo') - scope.expects(:lookupvar).with('caller_module_name').returns('bar') - scope.source.expects(:name).returns('foo::baz') - scope.source.expects(:type).returns('hostclass') - expect { - subject.call [] - }.to raise_error Puppet::ParseError, /Class foo::baz is private/ - end - end - - context "when called from private definition" do - it "should fail with a class error message" do - scope.expects(:lookupvar).with('module_name').returns('foo') - scope.expects(:lookupvar).with('caller_module_name').returns('bar') - scope.source.expects(:name).returns('foo::baz') - scope.source.expects(:type).returns('definition') - expect { - subject.call [] - }.to raise_error Puppet::ParseError, /Definition foo::baz is private/ - end - end -end diff --git a/spec/functions/pw_hash_spec.rb b/spec/functions/pw_hash_spec.rb index df5348c90..5e9af8921 100644 --- a/spec/functions/pw_hash_spec.rb +++ b/spec/functions/pw_hash_spec.rb @@ -1,25 +1,26 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'pw_hash' do - - it { is_expected.not_to eq(nil) } + it { is_expected.not_to be_nil } context 'when there are less than 3 arguments' do - it { is_expected.to run.with_params().and_raise_error(ArgumentError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('password').and_raise_error(ArgumentError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('password', 'sha-256').and_raise_error(ArgumentError, /wrong number of arguments/i) } + it { is_expected.to run.with_params.and_raise_error(ArgumentError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params('password').and_raise_error(ArgumentError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params('password', 'sha-256').and_raise_error(ArgumentError, %r{wrong number of arguments}i) } end context 'when there are more than 3 arguments' do - it { is_expected.to run.with_params('password', 'sha-256', 'salt', 'extra').and_raise_error(ArgumentError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('password', 'sha-256', 'salt', 'extra', 'extra').and_raise_error(ArgumentError, /wrong number of arguments/i) } + it { is_expected.to run.with_params('password', 'sha-256', 'salt', 'extra').and_raise_error(ArgumentError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params('password', 'sha-256', 'salt', 'extra', 'extra').and_raise_error(ArgumentError, %r{wrong number of arguments}i) } end context 'when the first argument is not a string' do - it { is_expected.to run.with_params([], 'sha-256', 'salt').and_raise_error(ArgumentError, /first argument must be a string/) } - it { is_expected.to run.with_params({}, 'sha-256', 'salt').and_raise_error(ArgumentError, /first argument must be a string/) } - it { is_expected.to run.with_params(1, 'sha-256', 'salt').and_raise_error(ArgumentError, /first argument must be a string/) } - it { is_expected.to run.with_params(true, 'sha-256', 'salt').and_raise_error(ArgumentError, /first argument must be a string/) } + it { is_expected.to run.with_params([], 'sha-256', 'salt').and_raise_error(ArgumentError, %r{first argument must be a string}) } + it { is_expected.to run.with_params({}, 'sha-256', 'salt').and_raise_error(ArgumentError, %r{first argument must be a string}) } + it { is_expected.to run.with_params(1, 'sha-256', 'salt').and_raise_error(ArgumentError, %r{first argument must be a string}) } + it { is_expected.to run.with_params(true, 'sha-256', 'salt').and_raise_error(ArgumentError, %r{first argument must be a string}) } end context 'when the first argument is undefined' do @@ -28,42 +29,86 @@ end context 'when the second argument is not a string' do - it { is_expected.to run.with_params('password', [], 'salt').and_raise_error(ArgumentError, /second argument must be a string/) } - it { is_expected.to run.with_params('password', {}, 'salt').and_raise_error(ArgumentError, /second argument must be a string/) } - it { is_expected.to run.with_params('password', 1, 'salt').and_raise_error(ArgumentError, /second argument must be a string/) } - it { is_expected.to run.with_params('password', true, 'salt').and_raise_error(ArgumentError, /second argument must be a string/) } + it { is_expected.to run.with_params('password', [], 'salt').and_raise_error(ArgumentError, %r{second argument must be a string}) } + it { is_expected.to run.with_params('password', {}, 'salt').and_raise_error(ArgumentError, %r{second argument must be a string}) } + it { is_expected.to run.with_params('password', 1, 'salt').and_raise_error(ArgumentError, %r{second argument must be a string}) } + it { is_expected.to run.with_params('password', true, 'salt').and_raise_error(ArgumentError, %r{second argument must be a string}) } end context 'when the second argument is not one of the supported hashing algorithms' do - it { is_expected.to run.with_params('password', 'no such algo', 'salt').and_raise_error(ArgumentError, /is not a valid hash type/) } + it { is_expected.to run.with_params('password', 'no such algo', 'salt').and_raise_error(ArgumentError, %r{is not a valid hash type}) } end context 'when the third argument is not a string' do - it { is_expected.to run.with_params('password', 'sha-256', []).and_raise_error(ArgumentError, /third argument must be a string/) } - it { is_expected.to run.with_params('password', 'sha-256', {}).and_raise_error(ArgumentError, /third argument must be a string/) } - it { is_expected.to run.with_params('password', 'sha-256', 1).and_raise_error(ArgumentError, /third argument must be a string/) } - it { is_expected.to run.with_params('password', 'sha-256', true).and_raise_error(ArgumentError, /third argument must be a string/) } + it { is_expected.to run.with_params('password', 'sha-256', []).and_raise_error(ArgumentError, %r{third argument must be a string}) } + it { is_expected.to run.with_params('password', 'sha-256', {}).and_raise_error(ArgumentError, %r{third argument must be a string}) } + it { is_expected.to run.with_params('password', 'sha-256', 1).and_raise_error(ArgumentError, %r{third argument must be a string}) } + it { is_expected.to run.with_params('password', 'sha-256', true).and_raise_error(ArgumentError, %r{third argument must be a string}) } end context 'when the third argument is empty' do - it { is_expected.to run.with_params('password', 'sha-512', '').and_raise_error(ArgumentError, /third argument must not be empty/) } + it { is_expected.to run.with_params('password', 'sha-512', '').and_raise_error(ArgumentError, %r{third argument must not be empty}) } end context 'when the third argument contains invalid characters' do - it { is_expected.to run.with_params('password', 'sha-512', 'one%').and_raise_error(ArgumentError, /characters in salt must be in the set/) } + it { is_expected.to run.with_params('password', 'sha-512', 'one%').and_raise_error(ArgumentError, %r{characters in salt must be in the set}) } + it { is_expected.to run.with_params('password', 'bcrypt', '1234').and_raise_error(ArgumentError, %r{characters in salt must match}) } + it { is_expected.to run.with_params('password', 'bcrypt-a', '1234').and_raise_error(ArgumentError, %r{characters in salt must match}) } + it { is_expected.to run.with_params('password', 'bcrypt-x', '1234').and_raise_error(ArgumentError, %r{characters in salt must match}) } + it { is_expected.to run.with_params('password', 'bcrypt-y', '1234').and_raise_error(ArgumentError, %r{characters in salt must match}) } + end + + context 'when the third argument has an invalid strength parameter for bcrypt' do + it { is_expected.to run.with_params('password', 'bcrypt', '03$salt.salt.salt.salt.sa').and_raise_error(ArgumentError, %r{characters in salt must match}) } + it { is_expected.to run.with_params('password', 'bcrypt-a', '03$salt.salt.salt.salt.sa').and_raise_error(ArgumentError, %r{characters in salt must match}) } + it { is_expected.to run.with_params('password', 'bcrypt-x', '03$salt.salt.salt.salt.sa').and_raise_error(ArgumentError, %r{characters in salt must match}) } + it { is_expected.to run.with_params('password', 'bcrypt-y', '03$salt.salt.salt.salt.sa').and_raise_error(ArgumentError, %r{characters in salt must match}) } + it { is_expected.to run.with_params('password', 'bcrypt', '32$salt.salt.salt.salt.sa').and_raise_error(ArgumentError, %r{characters in salt must match}) } + it { is_expected.to run.with_params('password', 'bcrypt-a', '32$salt.salt.salt.salt.sa').and_raise_error(ArgumentError, %r{characters in salt must match}) } + it { is_expected.to run.with_params('password', 'bcrypt-x', '32$salt.salt.salt.salt.sa').and_raise_error(ArgumentError, %r{characters in salt must match}) } + it { is_expected.to run.with_params('password', 'bcrypt-y', '32$salt.salt.salt.salt.sa').and_raise_error(ArgumentError, %r{characters in salt must match}) } end context 'when running on a platform with a weak String#crypt implementation' do - before(:each) { allow_any_instance_of(String).to receive(:crypt).with('$1$1').and_return('a bad hash') } + before(:each) { allow_any_instance_of(String).to receive(:crypt).with('$1$1').and_return('a bad hash') } # rubocop:disable RSpec/AnyInstance : Unable to find a viable replacement - it { is_expected.to run.with_params('password', 'sha-512', 'salt').and_raise_error(Puppet::ParseError, /system does not support enhanced salts/) } + it { is_expected.to run.with_params('password', 'sha-512', 'salt').and_raise_error(Puppet::ParseError, %r{system does not support enhanced salts}) } end - if RUBY_PLATFORM == 'java' or 'test'.crypt('$1$1') == '$1$1$Bp8CU9Oujr9SSEw53WV6G.' - describe "on systems with enhanced salts support" do + begin + require 'etc' + if Etc.confstr(Etc::CS_GNU_LIBC_VERSION) =~ %r{(\d+\.\d+)} && Puppet::Util::Package.versioncmp(Regexp.last_match(1), '2.28') >= 0 + context 'when running on platform with bcrypt' do + it { is_expected.to run.with_params('password', 'bcrypt', '05$salt.salt.salt.salt.sa').and_return('$2b$05$salt.salt.salt.salt.sO5QUgeeLRANZyvfNiKJW5amLo3cVD8nW') } + it { is_expected.to run.with_params('password', 'bcrypt-a', '05$salt.salt.salt.salt.sa').and_return('$2a$05$salt.salt.salt.salt.sO5QUgeeLRANZyvfNiKJW5amLo3cVD8nW') } + it { is_expected.to run.with_params('password', 'bcrypt-x', '05$salt.salt.salt.salt.sa').and_return('$2x$05$salt.salt.salt.salt.sO5QUgeeLRANZyvfNiKJW5amLo3cVD8nW') } + it { is_expected.to run.with_params('password', 'bcrypt-y', '05$salt.salt.salt.salt.sa').and_return('$2y$05$salt.salt.salt.salt.sO5QUgeeLRANZyvfNiKJW5amLo3cVD8nW') } + end + else + pending('Only testing bcrypt results on glibc 2.28 and later') + end + rescue NameError + pending('Only testing bcrypt results on glibc') + end + + if RUBY_PLATFORM == 'java' || 'test'.crypt('$1$1') == '$1$1$Bp8CU9Oujr9SSEw53WV6G.' + describe 'on systems with enhanced salts support' do it { is_expected.to run.with_params('password', 'md5', 'salt').and_return('$1$salt$qJH7.N4xYta3aEG/dfqo/0') } it { is_expected.to run.with_params('password', 'sha-256', 'salt').and_return('$5$salt$Gcm6FsVtF/Qa77ZKD.iwsJlCVPY0XSMgLJL0Hnww/c1') } it { is_expected.to run.with_params('password', 'sha-512', 'salt').and_return('$6$salt$IxDD3jeSOb5eB1CX5LBsqZFVkJdido3OUILO5Ifz5iwMuTS4XMS130MTSuDDl3aCI6WouIL9AjRbLCelDCy.g.') } end + + if Puppet::Util::Package.versioncmp(Puppet.version, '4.7.0') >= 0 + describe 'when arguments are sensitive' do + it { is_expected.to run.with_params(Puppet::Pops::Types::PSensitiveType::Sensitive.new('password'), 'md5', 'salt').and_return('$1$salt$qJH7.N4xYta3aEG/dfqo/0') } + + it { + expect(subject).to run.with_params(Puppet::Pops::Types::PSensitiveType::Sensitive.new('password'), 'md5', Puppet::Pops::Types::PSensitiveType::Sensitive.new('salt')) + .and_return('$1$salt$qJH7.N4xYta3aEG/dfqo/0') + } + + it { is_expected.to run.with_params('password', 'md5', Puppet::Pops::Types::PSensitiveType::Sensitive.new('salt')).and_return('$1$salt$qJH7.N4xYta3aEG/dfqo/0') } + end + end end end diff --git a/spec/functions/range_spec.rb b/spec/functions/range_spec.rb old mode 100755 new mode 100644 index 492cad40b..7d266f53a --- a/spec/functions/range_spec.rb +++ b/spec/functions/range_spec.rb @@ -1,31 +1,76 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'range' do - it { is_expected.not_to eq(nil) } + it { is_expected.not_to be_nil } + + describe 'signature validation in puppet3', unless: RSpec.configuration.puppet_future do + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } - describe 'signature validation in puppet3', :unless => RSpec.configuration.puppet_future do - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } it { - pending("Current implementation ignores parameters after the third.") - is_expected.to run.with_params(1, 2, 3, 4).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) + pending('Current implementation ignores parameters after the third.') + expect(subject).to run.with_params(1, 2, 3, 4).and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } - it { is_expected.to run.with_params('1..2..3').and_raise_error(Puppet::ParseError, /Unable to compute range/i) } - it { is_expected.to run.with_params('').and_raise_error(Puppet::ParseError, /Unknown range format/i) } + + it { is_expected.to run.with_params('1..2..3').and_raise_error(Puppet::ParseError, %r{Unable to compute range}i) } + it { is_expected.to run.with_params('').and_raise_error(Puppet::ParseError, %r{Unknown range format}i) } end - describe 'signature validation in puppet4', :if => RSpec.configuration.puppet_future do - it { pending "the puppet 4 implementation"; is_expected.to run.with_params().and_raise_error(ArgumentError) } - it { pending "the puppet 4 implementation"; is_expected.to run.with_params('').and_raise_error(ArgumentError) } - it { pending "the puppet 4 implementation"; is_expected.to run.with_params({}).and_raise_error(ArgumentError) } - it { pending "the puppet 4 implementation"; is_expected.to run.with_params([]).and_raise_error(ArgumentError) } - it { pending "the puppet 4 implementation"; is_expected.to run.with_params(true).and_raise_error(ArgumentError) } - it { pending "the puppet 4 implementation"; is_expected.to run.with_params(true).and_raise_error(ArgumentError) } - it { is_expected.to run.with_params(1, 2, 'foo').and_raise_error(ArgumentError) } - it { pending "the puppet 4 implementation"; is_expected.to run.with_params(1, 2, []).and_raise_error(ArgumentError) } - it { pending "the puppet 4 implementation"; is_expected.to run.with_params(1, 2, {}).and_raise_error(ArgumentError) } - it { pending "the puppet 4 implementation"; is_expected.to run.with_params(1, 2, true).and_raise_error(ArgumentError) } - it { pending "the puppet 4 implementation"; is_expected.to run.with_params(1, 2, 3, 4).and_raise_error(ArgumentError) } - it { pending "the puppet 4 implementation"; is_expected.to run.with_params('1..2..3').and_raise_error(ArgumentError) } + describe 'signature validation in puppet4', if: RSpec.configuration.puppet_future do + it { + pending 'the puppet 4 implementation' + expect(subject).to run.with_params.and_raise_error(ArgumentError) + } + + it { + pending 'the puppet 4 implementation' + expect(subject).to run.with_params('').and_raise_error(ArgumentError) + } + + it { + pending 'the puppet 4 implementation' + expect(subject).to run.with_params({}).and_raise_error(ArgumentError) + } + + it { + pending 'the puppet 4 implementation' + expect(subject).to run.with_params([]).and_raise_error(ArgumentError) + } + + it { + pending 'the puppet 4 implementation' + expect(subject).to run.with_params(true).and_raise_error(ArgumentError) + } + + it { + expect(subject).to run.with_params(1, 2, 'foo').and_raise_error(ArgumentError) + } + + it { + pending 'the puppet 4 implementation' + expect(subject).to run.with_params(1, 2, []).and_raise_error(ArgumentError) + } + + it { + pending 'the puppet 4 implementation' + expect(subject).to run.with_params(1, 2, {}).and_raise_error(ArgumentError) + } + + it { + pending 'the puppet 4 implementation' + expect(subject).to run.with_params(1, 2, true).and_raise_error(ArgumentError) + } + + it { + pending 'the puppet 4 implementation' + expect(subject).to run.with_params(1, 2, 3, 4).and_raise_error(ArgumentError) + } + + it { + pending 'the puppet 4 implementation' + expect(subject).to run.with_params('1..2..3').and_raise_error(ArgumentError) + } end context 'with characters as bounds' do @@ -79,6 +124,14 @@ it { is_expected.to run.with_params('01', '04').and_return([1, 2, 3, 4]) } end + context 'with prefixed numbers as utf8 strings as bounds' do + it { is_expected.to run.with_params('ħөŝŧ01', 'ħөŝŧ04').and_return(['ħөŝŧ01', 'ħөŝŧ02', 'ħөŝŧ03', 'ħөŝŧ04']) } + end + + context 'with prefixed numbers as double byte character strings as bounds' do + it { is_expected.to run.with_params('ćƒ›ć‚¹ćƒˆ01', 'ćƒ›ć‚¹ćƒˆ04').and_return(['ćƒ›ć‚¹ćƒˆ01', 'ćƒ›ć‚¹ćƒˆ02', 'ćƒ›ć‚¹ćƒˆ03', 'ćƒ›ć‚¹ćƒˆ04']) } + end + context 'with dash-range syntax' do it { is_expected.to run.with_params('4-1').and_return([]) } it { is_expected.to run.with_params('1-1').and_return([1]) } @@ -103,16 +156,18 @@ describe 'when passing mixed arguments as bounds' do it { - pending('these bounds should not be allowed as ruby will OOM hard. e.g. `(\'host0\'..\'hosta\').to_a` has 3239930 elements on ruby 1.9, adding more \'0\'s and \'a\'s increases that exponentially') - is_expected.to run.with_params('0', 'a').and_raise_error(Puppet::ParseError, /cannot interpolate between numeric and non-numeric bounds/) + pending('these bounds should not be allowed as ruby will OOM hard. e.g. `(\'host0\'..\'hosta\').to_a` has 3239930 elements on ruby 1.9, adding more \'0\'s and \'a\'s increases that exponentially') # rubocop:disable Layout/LineLength : unable to cut line to required length + expect(subject).to run.with_params('0', 'a').and_raise_error(Puppet::ParseError, %r{cannot interpolate between numeric and non-numeric bounds}) } + it { - pending('these bounds should not be allowed as ruby will OOM hard. e.g. `(\'host0\'..\'hosta\').to_a` has 3239930 elements on ruby 1.9, adding more \'0\'s and \'a\'s increases that exponentially') - is_expected.to run.with_params(0, 'a').and_raise_error(Puppet::ParseError, /cannot interpolate between numeric and non-numeric bounds/) + pending('these bounds should not be allowed as ruby will OOM hard. e.g. `(\'host0\'..\'hosta\').to_a` has 3239930 elements on ruby 1.9, adding more \'0\'s and \'a\'s increases that exponentially') # rubocop:disable Layout/LineLength : unable to cut line to required length + expect(subject).to run.with_params(0, 'a').and_raise_error(Puppet::ParseError, %r{cannot interpolate between numeric and non-numeric bounds}) } + it { - pending('these bounds should not be allowed as ruby will OOM hard. e.g. `(\'host0\'..\'hosta\').to_a` has 3239930 elements on ruby 1.9, adding more \'0\'s and \'a\'s increases that exponentially') - is_expected.to run.with_params('h0', 'ha').and_raise_error(Puppet::ParseError, /cannot interpolate between numeric and non-numeric bounds/) + pending('these bounds should not be allowed as ruby will OOM hard. e.g. `(\'host0\'..\'hosta\').to_a` has 3239930 elements on ruby 1.9, adding more \'0\'s and \'a\'s increases that exponentially') # rubocop:disable Layout/LineLength : unable to cut line to required length + expect(subject).to run.with_params('h0', 'ha').and_raise_error(Puppet::ParseError, %r{cannot interpolate between numeric and non-numeric bounds}) } end end diff --git a/spec/functions/regexpescape_spec.rb b/spec/functions/regexpescape_spec.rb new file mode 100644 index 000000000..fea5c8aa5 --- /dev/null +++ b/spec/functions/regexpescape_spec.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'regexpescape' do + describe 'signature validation' do + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + + it { + pending('Current implementation ignores parameters after the first.') + expect(subject).to run.with_params('', '').and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) + } + + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, %r{Requires either array or string to work}) } + it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, %r{Requires either array or string to work}) } + it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, %r{Requires either array or string to work}) } + end + + describe 'handling normal strings' do + it 'calls ruby\'s Regexp.escape function' do + expect(Regexp).to receive(:escape).with('regexp_string').and_return('escaped_regexp_string').once + expect(subject).to run.with_params('regexp_string').and_return('escaped_regexp_string') + end + end + + describe 'handling classes derived from String' do + it 'calls ruby\'s Regexp.escape function' do + regexp_string = AlsoString.new('regexp_string') + expect(Regexp).to receive(:escape).with(regexp_string).and_return('escaped_regexp_string').once + expect(subject).to run.with_params(regexp_string).and_return('escaped_regexp_string') + end + end + + describe 'strings in arrays handling' do + it { is_expected.to run.with_params([]).and_return([]) } + it { is_expected.to run.with_params(['one*', 'two']).and_return(['one\*', 'two']) } + it { is_expected.to run.with_params(['one*', 1, true, {}, 'two']).and_return(['one\*', 1, true, {}, 'two']) } + + context 'with UTF8 and double byte characters' do + it { is_expected.to run.with_params(['ÅÅ‰Īµ*']).and_return(['ÅÅ‰Īµ\*']) } + it { is_expected.to run.with_params(['ć‚¤ćƒ³ć‚æćƒ¼ćƒćƒƒćƒˆ*']).and_return(['ć‚¤ćƒ³ć‚æćƒ¼ćƒćƒƒćƒˆ\*']) } + end + end +end diff --git a/spec/functions/reject_spec.rb b/spec/functions/reject_spec.rb old mode 100755 new mode 100644 index 486305075..90fc1d190 --- a/spec/functions/reject_spec.rb +++ b/spec/functions/reject_spec.rb @@ -1,19 +1,24 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'reject' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params([], 'pattern', 'extra').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params([], 'pattern', 'extra').and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } it { - pending("reject does not actually check this, and raises NoMethodError instead") - is_expected.to run.with_params('one', 'two').and_raise_error(Puppet::ParseError, /first argument not an array/) + pending('reject does not actually check this, and raises NoMethodError instead') + expect(subject).to run.with_params('one', 'two').and_raise_error(Puppet::ParseError, %r{first argument not an array}) } + it { - pending("reject does not actually check this, and raises NoMethodError instead") - is_expected.to run.with_params(1, 'two').and_raise_error(Puppet::ParseError, /first argument not an array/) + pending('reject does not actually check this, and raises NoMethodError instead') + expect(subject).to run.with_params(1, 'two').and_raise_error(Puppet::ParseError, %r{first argument not an array}) } + it { is_expected.to run.with_params([], 'two').and_return([]) } it { is_expected.to run.with_params(['one', 'two', 'three'], 'two').and_return(['one', 'three']) } it { is_expected.to run.with_params(['one', 'two', 'three'], 't(wo|hree)').and_return(['one']) } + it { is_expected.to run.with_params(['ĻŒÅ‰į»‡', 'ţщồ', 'Å£Ņ£ŃĪ­Ī­'], 'Å£(щồ|Ņ£ŃĪ­Ī­)').and_return(['ĻŒÅ‰į»‡']) } end diff --git a/spec/functions/reverse_spec.rb b/spec/functions/reverse_spec.rb old mode 100755 new mode 100644 index e00dee92e..d4740945b --- a/spec/functions/reverse_spec.rb +++ b/spec/functions/reverse_spec.rb @@ -1,30 +1,36 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'reverse' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { - pending("Current implementation ignores parameters after the first.") - is_expected.to run.with_params([], 'extra').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) + pending('Current implementation ignores parameters after the first.') + expect(subject).to run.with_params([], 'extra').and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } - it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } - it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } - it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } + + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, %r{Requires either array or string to work}) } + it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, %r{Requires either array or string to work}) } + it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, %r{Requires either array or string to work}) } it { is_expected.to run.with_params([]).and_return([]) } it { is_expected.to run.with_params(['a']).and_return(['a']) } it { is_expected.to run.with_params(['one']).and_return(['one']) } it { is_expected.to run.with_params(['one', 'two', 'three']).and_return(['three', 'two', 'one']) } it { is_expected.to run.with_params(['one', 'two', 'three', 'four']).and_return(['four', 'three', 'two', 'one']) } + it { is_expected.to run.with_params(['į»•ÅˆĆ«', 'Å„Åµį»', 'Å§Ņ£ŃÉ™Ä—', 'Ę’ÅÅÆÅ—']).and_return(['Ę’ÅÅÆÅ—', 'Å§Ņ£ŃÉ™Ä—', 'Å„Åµį»', 'į»•ÅˆĆ«']) } it { is_expected.to run.with_params('').and_return('') } it { is_expected.to run.with_params('a').and_return('a') } it { is_expected.to run.with_params('abc').and_return('cba') } it { is_expected.to run.with_params('abcd').and_return('dcba') } + it { is_expected.to run.with_params('āβćđ').and_return('đćβā') } context 'when using a class extending String' do - it 'should call its reverse method' do + it 'calls its reverse method' do value = AlsoString.new('asdfghjkl') - value.expects(:reverse).returns('foo') + expect_any_instance_of(AlsoString).to receive(:reverse).and_return('foo') # rubocop:disable RSpec/AnyInstance expect(subject).to run.with_params(value).and_return('foo') end end diff --git a/spec/functions/rstrip_spec.rb b/spec/functions/rstrip_spec.rb deleted file mode 100755 index d2efac8ea..000000000 --- a/spec/functions/rstrip_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -require 'spec_helper' - -describe 'rstrip' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { - pending("Current implementation ignores parameters after the first.") - is_expected.to run.with_params('', '').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) - } - it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, /Requires either array or string to work with/) } - it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /Requires either array or string to work with/) } - it { is_expected.to run.with_params('').and_return('') } - it { is_expected.to run.with_params(' ').and_return('') } - it { is_expected.to run.with_params(' ').and_return('') } - it { is_expected.to run.with_params("\t").and_return('') } - it { is_expected.to run.with_params("\t ").and_return('') } - it { is_expected.to run.with_params('one').and_return('one') } - it { is_expected.to run.with_params(' one').and_return(' one') } - it { is_expected.to run.with_params(' one').and_return(' one') } - it { is_expected.to run.with_params("\tone").and_return("\tone") } - it { is_expected.to run.with_params("\t one").and_return("\t one") } - it { is_expected.to run.with_params('one ').and_return('one') } - it { is_expected.to run.with_params(' one ').and_return(' one') } - it { is_expected.to run.with_params(' one ').and_return(' one') } - it { is_expected.to run.with_params("\tone ").and_return("\tone") } - it { is_expected.to run.with_params("\t one ").and_return("\t one") } - it { is_expected.to run.with_params("one\t").and_return('one') } - it { is_expected.to run.with_params(" one\t").and_return(' one') } - it { is_expected.to run.with_params(" one\t").and_return(' one') } - it { is_expected.to run.with_params("\tone\t").and_return("\tone") } - it { is_expected.to run.with_params("\t one\t").and_return("\t one") } - it { is_expected.to run.with_params(' o n e ').and_return(' o n e') } - it { is_expected.to run.with_params(AlsoString.new(' one ')).and_return(' one') } -end diff --git a/spec/functions/seeded_rand_spec.rb b/spec/functions/seeded_rand_spec.rb new file mode 100644 index 000000000..43e22f578 --- /dev/null +++ b/spec/functions/seeded_rand_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'stdlib::seeded_rand' do + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(ArgumentError, %r{'stdlib::seeded_rand' expects 2 arguments, got none}i) } + it { is_expected.to run.with_params(1).and_raise_error(ArgumentError, %r{'stdlib::seeded_rand' expects 2 arguments, got 1}i) } + it { is_expected.to run.with_params(0, '').and_raise_error(ArgumentError, %r{parameter 'max' expects an Integer\[1\] value, got Integer\[0, 0\]}) } + it { is_expected.to run.with_params(1.5, '').and_raise_error(ArgumentError, %r{parameter 'max' expects an Integer value, got Float}) } + it { is_expected.to run.with_params(-10, '').and_raise_error(ArgumentError, %r{parameter 'max' expects an Integer\[1\] value, got Integer\[-10, -10\]}) } + it { is_expected.to run.with_params('string', '').and_raise_error(ArgumentError, %r{parameter 'max' expects an Integer value, got String}) } + it { is_expected.to run.with_params([], '').and_raise_error(ArgumentError, %r{parameter 'max' expects an Integer value, got Array}) } + it { is_expected.to run.with_params({}, '').and_raise_error(ArgumentError, %r{parameter 'max' expects an Integer value, got Hash}) } + it { is_expected.to run.with_params(1, 1).and_raise_error(ArgumentError, %r{parameter 'seed' expects a String value, got Integer}) } + it { is_expected.to run.with_params(1, []).and_raise_error(ArgumentError, %r{parameter 'seed' expects a String value, got Array}) } + it { is_expected.to run.with_params(1, {}).and_raise_error(ArgumentError, %r{parameter 'seed' expects a String value, got Hash}) } + + context 'produce predictible and reproducible results' do + it { is_expected.to run.with_params(20, 'foo').and_return(1) } + it { is_expected.to run.with_params(100, 'bar').and_return(35) } + it { is_expected.to run.with_params(1000, 'ǿňè').and_return(247) } + it { is_expected.to run.with_params(1000, 'ę–‡å­—åˆ—').and_return(67) } + end +end diff --git a/spec/functions/seeded_rand_string_spec.rb b/spec/functions/seeded_rand_string_spec.rb new file mode 100644 index 000000000..3c2c49bb5 --- /dev/null +++ b/spec/functions/seeded_rand_string_spec.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'stdlib::seeded_rand_string' do + it { is_expected.not_to be_nil } + + # Test for erroneous params + it { is_expected.to run.with_params.and_raise_error(ArgumentError, %r{expects between.+got none}i) } + it { is_expected.to run.with_params(1).and_raise_error(ArgumentError, %r{expects between.+got 1}i) } + it { is_expected.to run.with_params('1', 'hello').and_raise_error(ArgumentError, %r{parameter 'length' expects an Integer value}i) } + it { is_expected.to run.with_params(1, 1).and_raise_error(ArgumentError, %r{parameter 'seed' expects a String value}i) } + it { is_expected.to run.with_params(1, 'hello', 1).and_raise_error(ArgumentError, %r{parameter 'charset' expects a.+String}i) } + + # Test regular run + it { is_expected.to run.with_params(100, 'hello') } + + # Test custom charsets + it { is_expected.to run.with_params(100, 'hello', 'abcd').and_return(%r{[a-d]{100}}) } + it { is_expected.to run.with_params(100, 'hello', 'abcdefgh').and_return(%r{[a-h]{100}}) } + it { is_expected.to run.with_params(100, 'hello', 'ab,|').and_return(%r{[ab,|]{100}}) } + + # Test behavior + it 'generates the same string with the same seed' do + rand_str_one = call_function(:'stdlib::seeded_rand_string', 300, 'my_seed') + rand_str_two = call_function(:'stdlib::seeded_rand_string', 300, 'my_seed') + + expect(rand_str_one).to eq(rand_str_two) + end + + it 'generates different strings if seeded differently' do + rand_str_one = call_function(:'stdlib::seeded_rand_string', 300, 'my_seed_one') + rand_str_two = call_function(:'stdlib::seeded_rand_string', 300, 'my_seed_two') + + expect(rand_str_one).not_to eq(rand_str_two) + end +end diff --git a/spec/functions/sha256_spec.rb b/spec/functions/sha256_spec.rb new file mode 100644 index 000000000..5c9e2e3ce --- /dev/null +++ b/spec/functions/sha256_spec.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'stdlib::sha256' do + context 'when default' do + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(ArgumentError, %r{stdlib::sha256}) } + end + + context 'when testing a simple string' do + it { is_expected.to run.with_params('abc').and_return('ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad') } + it { is_expected.to run.with_params('acb').and_return('8e9766083b3bfc2003f791c9853941b0ea035d16379bfec16b72d376e272fa57') } + it { is_expected.to run.with_params('my string').and_return('2f7e2089add0288a309abd71ffcc3b3567e2d4215e20e6ed3b74d6042f7ef8e5') } + it { is_expected.to run.with_params('0').and_return('5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9') } + end + + context 'when testing a sensitive string' do + it { is_expected.to run.with_params(sensitive('my string')).and_return('2f7e2089add0288a309abd71ffcc3b3567e2d4215e20e6ed3b74d6042f7ef8e5') } + end + + context 'when testing an integer' do + it { is_expected.to run.with_params(0).and_return('5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9') } + it { is_expected.to run.with_params(100).and_return('ad57366865126e55649ecb23ae1d48887544976efea46a48eb5d85a6eeb4d306') } + it { is_expected.to run.with_params(sensitive(100)).and_return('ad57366865126e55649ecb23ae1d48887544976efea46a48eb5d85a6eeb4d306') } + end + + context 'when testing a float' do + it { is_expected.to run.with_params(200.3).and_return('441adfa0dd670f4193e4b6e4e373bd7fd3861ee53c834c562b825af79bf7dc98') } + + # .0 isn't always converted into an integer, but should have rational truncation + it { is_expected.to run.with_params(100.0).and_return('43b87f618caab482ebe4976c92bcd6ad308b48055f1c27b4c574f3e31d7683e0') } + it { is_expected.to run.with_params(sensitive(100.0000)).and_return('43b87f618caab482ebe4976c92bcd6ad308b48055f1c27b4c574f3e31d7683e0') } + end + + context 'when testing a bool' do + it { is_expected.to run.with_params(true).and_return('b5bea41b6c623f7c09f1bf24dcae58ebab3c0cdd90ad966bc43a45b44867e12b') } + it { is_expected.to run.with_params(false).and_return('fcbcf165908dd18a9e49f7ff27810176db8e9f63b4352213741664245224f8aa') } + end + + context 'when testing a binary' do + it { is_expected.to run.with_params("\xFE\xED\xBE\xEF").and_return('bf6b255a261ddde9ea66060dcb239e06d321ad37755d2a97a5846f5144b779b4') } + end +end diff --git a/spec/functions/shell_escape_spec.rb b/spec/functions/shell_escape_spec.rb new file mode 100644 index 000000000..cd90c501a --- /dev/null +++ b/spec/functions/shell_escape_spec.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'stdlib::shell_escape' do + it { is_expected.not_to be_nil } + + describe 'signature validation' do + it { is_expected.to run.with_params.and_raise_error(ArgumentError, %r{'stdlib::shell_escape' expects 1 argument, got none}) } + it { is_expected.to run.with_params('foo', 'bar').and_raise_error(ArgumentError, %r{'stdlib::shell_escape' expects 1 argument, got 2}) } + end + + describe 'stringification' do + it { is_expected.to run.with_params(10).and_return('10') } + it { is_expected.to run.with_params(false).and_return('false') } + end + + describe 'escaping' do + it { is_expected.to run.with_params('foo').and_return('foo') } + it { is_expected.to run.with_params('foo bar').and_return('foo\ bar') } + + it { + expect(subject).to run.with_params('~`!@#$%^&*()_-=[]\{}|;\':",./<>?') + .and_return('\~\`\!@\#\$\%\^\&\*\(\)_-\=\[\]\\\\\{\}\|\;\\\':\",./\<\>\?') + } + end + + context 'with UTF8 and double byte characters' do + it { is_expected.to run.with_params('ć‚¹ćƒšćƒ¼ ć‚¹ć‚’å«ć‚€ćƒ† ć‚­ć‚¹ćƒˆ').and_return('\\ス\\ペ\\ー\\ \\ス\\悒\\含\\悀\\惆\\ \\ \\悭\\ス\\惈') } + it { is_expected.to run.with_params('μńƒ 8 ŧĕχń').and_return('\\μ\\Å„\\ʒ\\ 8\\ \\ \\ŧ\\ĕ\\χ\\Å„') } + end +end diff --git a/spec/functions/shell_join_spec.rb b/spec/functions/shell_join_spec.rb new file mode 100644 index 000000000..03144c3ee --- /dev/null +++ b/spec/functions/shell_join_spec.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'shell_join' do + it { is_expected.not_to be_nil } + + describe 'signature validation' do + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params(['foo'], ['bar']).and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params('foo').and_raise_error(Puppet::ParseError, %r{is not an Array}i) } + end + + describe 'shell argument joining' do + it { is_expected.to run.with_params(['foo']).and_return('foo') } + it { is_expected.to run.with_params(['foo', 'bar']).and_return('foo bar') } + it { is_expected.to run.with_params(['foo', 'bar baz']).and_return('foo bar\ baz') } + + it { + expect(subject).to run.with_params(['~`!@#$', '%^&*()_-=', '[]\{}|;\':"', ',./<>?']) + .and_return('\~\`\!@\#\$ \%\^\&\*\(\)_-\= \[\]\\\\\{\}\|\;\\\':\" ,./\<\>\?') + } + + context 'with UTF8 and double byte characters' do + it { is_expected.to run.with_params(['μńƒ', '8', 'ŧĕχń']).and_return('\\μ\\Å„\\ʒ 8 \\ŧ\\ĕ\\χ\\Å„') } + it { is_expected.to run.with_params(['ć‚¹ćƒšćƒ¼', 'ć‚¹ć‚’å«ć‚€ćƒ†', ' ć‚­ć‚¹ćƒˆ']).and_return('\\ス\\ペ\\ー \\ス\\悒\\含\\悀\\惆 \\ \\悭\\ス\\惈') } + end + end + + describe 'stringification' do + it { is_expected.to run.with_params([10, false, 'foo']).and_return('10 false foo') } + end +end diff --git a/spec/functions/shell_split_spec.rb b/spec/functions/shell_split_spec.rb new file mode 100644 index 000000000..0ad9b0bcd --- /dev/null +++ b/spec/functions/shell_split_spec.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'shell_split' do + it { is_expected.not_to be_nil } + + describe 'signature validation' do + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params('foo', 'bar').and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + end + + describe 'stringification' do + it { is_expected.to run.with_params(10).and_return(['10']) } + it { is_expected.to run.with_params(false).and_return(['false']) } + end + + describe 'shell line spliting' do + it { is_expected.to run.with_params('foo').and_return(['foo']) } + it { is_expected.to run.with_params('foo bar').and_return(['foo', 'bar']) } + + it { + expect(subject).to run.with_params('\~\`\!@\#\$\%\^\&\*\(\)_\+-\=\[\]\\\\\{\}\|\;\\\':\",./\<\>\?') + .and_return(['~`!@#$%^&*()_+-=[]\{}|;\':",./<>?']) + } + + it { + expect(subject).to run.with_params('\~\`\!@\#\$ \%\^\&\*\(\)_\+-\= \[\]\\\\\{\}\|\;\\\':\" ,./\<\>\?') + .and_return(['~`!@#$', '%^&*()_+-=', '[]\{}|;\':"', ',./<>?']) + } + + context 'with UTF8 and double byte characters' do + it { is_expected.to run.with_params('\\μ\\Å„\\ʒ 8 \\ŧ\\ĕ\\χ\\Å„').and_return(['μńƒ', '8', 'ŧĕχń']) } + it { is_expected.to run.with_params('\\ス\\ペ\\ー \\ス\\悒\\含\\悀\\惆 \\ \\悭\\ス\\惈').and_return(['ć‚¹ćƒšćƒ¼', 'ć‚¹ć‚’å«ć‚€ćƒ†', ' ć‚­ć‚¹ćƒˆ']) } + end + end +end diff --git a/spec/functions/shuffle_spec.rb b/spec/functions/shuffle_spec.rb old mode 100755 new mode 100644 index ebc3a732d..97459ab95 --- a/spec/functions/shuffle_spec.rb +++ b/spec/functions/shuffle_spec.rb @@ -1,15 +1,19 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'shuffle' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { - pending("Current implementation ignores parameters after the first.") - is_expected.to run.with_params([], 'extra').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) + pending('Current implementation ignores parameters after the first.') + expect(subject).to run.with_params([], 'extra').and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } - it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } - it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } - it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } + + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, %r{Requires either array or string to work}) } + it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, %r{Requires either array or string to work}) } + it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, %r{Requires either array or string to work}) } context 'when running with a specific seed' do # make tests deterministic @@ -18,16 +22,40 @@ it { is_expected.to run.with_params([]).and_return([]) } it { is_expected.to run.with_params(['a']).and_return(['a']) } it { is_expected.to run.with_params(['one']).and_return(['one']) } - it { is_expected.to run.with_params(['one', 'two', 'three']).and_return(['two', 'one', 'three']) } - it { is_expected.to run.with_params(['one', 'two', 'three', 'four']).and_return(['four', 'three', 'two', 'one']) } - it { is_expected.to run.with_params('').and_return('') } - it { is_expected.to run.with_params('a').and_return('a') } - it { is_expected.to run.with_params('abc').and_return('bac') } - it { is_expected.to run.with_params('abcd').and_return('dcba') } + if Puppet::PUPPETVERSION[0].to_i < 8 + it { is_expected.to run.with_params(['one', 'two', 'three']).and_return(['two', 'one', 'three']) } + it { is_expected.to run.with_params(['one', 'two', 'three', 'four']).and_return(['four', 'three', 'two', 'one']) } + + it { is_expected.to run.with_params('').and_return('') } + it { is_expected.to run.with_params('a').and_return('a') } + it { is_expected.to run.with_params('abc').and_return('bac') } + it { is_expected.to run.with_params('abcd').and_return('dcba') } + + context 'with UTF8 and double byte characters' do + it { is_expected.to run.with_params('ůţƒ8 ŧέχŧ ÅŸÅ§Ņ‘Ć­Å„Ä£').and_return('ģńş ůχţέƒŧí8ґŧŧ ') } + it { is_expected.to run.with_params('ę—„ęœ¬čŖžć®ę–‡å­—åˆ—').and_return('å­—ęœ¬ę—„čŖžę–‡åˆ—ć®') } + end + + context 'when using a class extending String' do + it { is_expected.to run.with_params(AlsoString.new('asdfghjkl')).and_return('lkhdsfajg') } + end + else + it { is_expected.to run.with_params(['one', 'two', 'three']).and_return(['one', 'three', 'two']) } + it { is_expected.to run.with_params(['one', 'two', 'three', 'four']).and_return(['one', 'three', 'two', 'four']) } + + it { is_expected.to run.with_params('b').and_return('b') } + it { is_expected.to run.with_params('abc').and_return('acb') } + it { is_expected.to run.with_params('abcd').and_return('acbd') } + + context 'with UTF8 and double byte characters' do + it { is_expected.to run.with_params('ůţƒ8 ŧέχŧ ÅŸÅ§Ņ‘Ć­Å„Ä£').and_return('ŧńş ģχţέƒůí8ґŧŧ ') } + it { is_expected.to run.with_params('ę—„ęœ¬čŖžć®ę–‡å­—åˆ—').and_return('ę—„åˆ—čŖžå­—ęœ¬ę–‡ć®') } + end - context 'when using a class extending String' do - it { is_expected.to run.with_params(AlsoString.new('asdfghjkl')).and_return('lkhdsfajg') } + context 'when using a class extending String' do + it { is_expected.to run.with_params(AlsoString.new('asdfghjkl')).and_return('lakfdgjsh') } + end end end end diff --git a/spec/functions/size_spec.rb b/spec/functions/size_spec.rb deleted file mode 100755 index c0047ee21..000000000 --- a/spec/functions/size_spec.rb +++ /dev/null @@ -1,35 +0,0 @@ -require 'spec_helper' - -describe 'size' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { - pending("Current implementation ignores parameters after the first.") - is_expected.to run.with_params([], 'extra').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) - } - it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /Unknown type given/) } - it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, /Unknown type given/) } - it { is_expected.to run.with_params('1').and_raise_error(Puppet::ParseError, /Requires either string, array or hash to work/) } - it { is_expected.to run.with_params('1.0').and_raise_error(Puppet::ParseError, /Requires either string, array or hash to work/) } - it { is_expected.to run.with_params([]).and_return(0) } - it { is_expected.to run.with_params(['a']).and_return(1) } - it { is_expected.to run.with_params(['one', 'two', 'three']).and_return(3) } - it { is_expected.to run.with_params(['one', 'two', 'three', 'four']).and_return(4) } - - it { is_expected.to run.with_params({}).and_return(0) } - it { is_expected.to run.with_params({'1' => '2'}).and_return(1) } - it { is_expected.to run.with_params({'1' => '2', '4' => '4'}).and_return(2) } - - it { is_expected.to run.with_params('').and_return(0) } - it { is_expected.to run.with_params('a').and_return(1) } - it { is_expected.to run.with_params('abc').and_return(3) } - it { is_expected.to run.with_params('abcd').and_return(4) } - - context 'when using a class extending String' do - it 'should call its size method' do - value = AlsoString.new('asdfghjkl') - value.expects(:size).returns('foo') - expect(subject).to run.with_params(value).and_return('foo') - end - end -end diff --git a/spec/functions/sort_by_spec.rb b/spec/functions/sort_by_spec.rb new file mode 100644 index 000000000..6a14f2977 --- /dev/null +++ b/spec/functions/sort_by_spec.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'stdlib::sort_by' do + it { is_expected.not_to be_nil } + + describe 'raise exception with inappropriate parameters' do + it { is_expected.to run.with_params.and_raise_error(ArgumentError, Regexp.new('expects 1 argument, got none')) } + it { is_expected.to run.with_params([]).and_raise_error(ArgumentError, Regexp.new('expects a block')) } + it { is_expected.to run.with_params(:undef).and_raise_error(ArgumentError, Regexp.new("rejected: parameter 'ary' expects an Array value, got Undef")) } + it { is_expected.to run.with_params(true).and_raise_error(ArgumentError, Regexp.new("rejected: parameter 'ary' expects an Array value, got Boolean")) } + it { is_expected.to run.with_params(1).and_raise_error(ArgumentError, Regexp.new("rejected: parameter 'ary' expects an Array value, got Integer")) } + it { is_expected.to run.with_params({}).with_lambda { 1 }.and_raise_error(ArgumentError, Regexp.new('block expects between 1 and 2 arguments, got none')) } + end + + # Puppet's each iterator considers Integers, Strings, Arrays and Hashes to be Iterable. + unordered_array = ['The', 'quick', 'brown', 'fox', 'jumps', 'over', 'the', 'lazy', 'dog'] + ordered_array = ['The', 'brown', 'dog', 'fox', 'jumps', 'lazy', 'over', 'quick', 'the'] + unordered_hash = { 'The' => 'quick', 'brown' => 'fox', 'jumps' => 'over', 'the' => 'lazy', 'dog' => '.' } + ordered_hash = { 'dog' => '.', 'brown' => 'fox', 'the' => 'lazy', 'jumps' => 'over', 'The' => 'quick' } + unordered_string = 'The quick brown fox jumps over the lazy dog.' + ordered_string = ' .Tabcdeeefghhijklmnoooopqrrstuuvwxyz' + + describe 'with sane input' do + it 'does sort Array' do + expect(subject).to run \ + .with_params(unordered_array) \ + .with_lambda { |e| e } \ + .and_return(ordered_array) + end + + it 'does sort Hash by entry' do + expect(subject).to run \ + .with_params(unordered_hash) \ + .with_lambda { |e| e[1] } \ + .and_return(ordered_hash) + end + + it 'does sort Hash by key-value pairs' do + expect(subject).to run \ + .with_params(unordered_hash) \ + .with_lambda { |_, v| v } \ + .and_return(ordered_hash) + end + + it 'does sort String' do + expect(subject).to run \ + .with_params(unordered_string) \ + .with_lambda { |e| e } \ + .and_return(ordered_string) + end + end +end diff --git a/spec/functions/sort_spec.rb b/spec/functions/sort_spec.rb deleted file mode 100755 index 9abd039c1..000000000 --- a/spec/functions/sort_spec.rb +++ /dev/null @@ -1,24 +0,0 @@ -require 'spec_helper' - -describe 'sort' do - describe 'signature validation' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params([], 'extra').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { pending('stricter input checking'); is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, /requires string or array/) } - it { pending('stricter input checking'); is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /requires string or array/) } - it { pending('stricter input checking'); is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, /requires string or array/) } - end - - context 'when called with an array' do - it { is_expected.to run.with_params([]).and_return([]) } - it { is_expected.to run.with_params(['a']).and_return(['a']) } - it { is_expected.to run.with_params(['c', 'b', 'a']).and_return(['a', 'b', 'c']) } - end - - context 'when called with a string' do - it { is_expected.to run.with_params('').and_return('') } - it { is_expected.to run.with_params('a').and_return('a') } - it { is_expected.to run.with_params('cbda').and_return('abcd') } - end -end diff --git a/spec/functions/squeeze_spec.rb b/spec/functions/squeeze_spec.rb old mode 100755 new mode 100644 index 7f09c30ff..04f45bcfb --- a/spec/functions/squeeze_spec.rb +++ b/spec/functions/squeeze_spec.rb @@ -1,9 +1,11 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'squeeze' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('', '', '').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params('', '', '').and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } it { is_expected.to run.with_params(1).and_raise_error(NoMethodError) } it { is_expected.to run.with_params({}).and_raise_error(NoMethodError) } it { is_expected.to run.with_params(true).and_raise_error(NoMethodError) } @@ -16,28 +18,36 @@ it { is_expected.to run.with_params('aaaaaaaaabbbbbbbbbbcccccccccc', 'b-c').and_return('aaaaaaaaabc') } end + context 'with UTF8 and double byte characters' do + it { is_expected.to run.with_params('įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­').and_return('įŗ­') } + it { is_expected.to run.with_params('čŖžčŖžčŖžčŖžčŖžčŖžčŖž', 'čŖž').and_return('čŖž') } + it { is_expected.to run.with_params('įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­čŖžčŖžčŖžčŖžĀ©Ā©Ā©Ā©Ā©', 'Ā©').and_return('įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­įŗ­čŖžčŖžčŖžčŖžĀ©') } + end + context 'when squeezing values in an array' do it { - is_expected.to run \ + expect(subject).to run \ .with_params(['', 'a', 'aaaaaaaaa', 'aaaaaaaaabbbbbbbbbbcccccccccc']) \ - .and_return( ['', 'a', 'a', 'abc']) + .and_return(['', 'a', 'a', 'abc']) } + it { - is_expected.to run \ + expect(subject).to run \ .with_params(['', 'a', 'aaaaaaaaa', 'aaaaaaaaabbbbbbbbbbcccccccccc'], 'a') \ - .and_return( ['', 'a', 'a', 'abbbbbbbbbbcccccccccc']) + .and_return(['', 'a', 'a', 'abbbbbbbbbbcccccccccc']) } + it { - is_expected.to run \ + expect(subject).to run \ .with_params(['', 'a', 'aaaaaaaaa', 'aaaaaaaaabbbbbbbbbbcccccccccc'], 'b-c') \ - .and_return( ['', 'a', 'aaaaaaaaa', 'aaaaaaaaabc']) + .and_return(['', 'a', 'aaaaaaaaa', 'aaaaaaaaabc']) } end context 'when using a class extending String' do - it 'should call its squeeze method' do + it 'calls its squeeze method' do value = AlsoString.new('aaaaaaaaa') - value.expects(:squeeze).returns('foo') + expect_any_instance_of(AlsoString).to receive(:squeeze).and_return('foo') # rubocop:disable RSpec/AnyInstance expect(subject).to run.with_params(value).and_return('foo') end end diff --git a/spec/functions/startswith_spec.rb b/spec/functions/startswith_spec.rb new file mode 100644 index 000000000..ebd00553e --- /dev/null +++ b/spec/functions/startswith_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'stdlib::start_with' do + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(ArgumentError, %r{expects 2 arguments, got none}i) } + it { is_expected.to run.with_params('').and_raise_error(ArgumentError, %r{expects 2 arguments, got 1}) } + + it { is_expected.to run.with_params('', 'foo').and_return(false) } + it { is_expected.to run.with_params('foobar', 'foo').and_return(true) } + it { is_expected.to run.with_params('foObar', ['bar', 'baz']).and_return(false) } +end diff --git a/spec/functions/stdlib_deferrable_epp_spec.rb b/spec/functions/stdlib_deferrable_epp_spec.rb new file mode 100644 index 000000000..022ac031a --- /dev/null +++ b/spec/functions/stdlib_deferrable_epp_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'stdlib::deferrable_epp' do + context 'call epp on non-deferred input' do + let(:pre_condition) do + 'function epp($str, $data) { return "rendered"}' + end + + it { + expect(subject).to run.with_params('mymod/template.epp', { 'foo' => 'bar' }).and_return('rendered') + } + end + + context 'defers rendering with deferred input' do + let(:pre_condition) do + <<~END + function epp($str, $data) { fail("should not have invoked epp()") } + function find_template($str) { return "path" } + function file($path) { return "foo: <%= foo %>" } + END + end + + it { + foo = Puppet::Pops::Types::TypeFactory.deferred.create('join', [1, 2, 3]) + # This kind_of matcher requires https://github.com/puppetlabs/rspec-puppet/pull/24 + expect(subject).to run.with_params('mymod/template.epp', { 'foo' => foo }) # .and_return(kind_of Puppet::Pops::Types::PuppetObject) + } + end +end diff --git a/spec/functions/stdlib_ensure_spec.rb b/spec/functions/stdlib_ensure_spec.rb new file mode 100644 index 000000000..b81d744e0 --- /dev/null +++ b/spec/functions/stdlib_ensure_spec.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'stdlib::ensure' do + context 'work without resource' do + it { is_expected.to run.with_params(true).and_return('present') } + it { is_expected.to run.with_params(false).and_return('absent') } + end + + context 'work with service resource' do + it { is_expected.to run.with_params('present', 'service').and_return('running') } + it { is_expected.to run.with_params(true, 'service').and_return('running') } + it { is_expected.to run.with_params('absent', 'service').and_return('stopped') } + it { is_expected.to run.with_params(false, 'service').and_return('stopped') } + end + + ['directory', 'link', 'mounted', 'file'].each do |resource| + context "work with #{resource} resource" do + it { is_expected.to run.with_params('present', resource).and_return(resource) } + it { is_expected.to run.with_params(true, resource).and_return(resource) } + it { is_expected.to run.with_params('absent', resource).and_return('absent') } + it { is_expected.to run.with_params(false, resource).and_return('absent') } + end + end + context 'work with package resource' do + it { is_expected.to run.with_params('present', 'package').and_return('installed') } + it { is_expected.to run.with_params(true, 'package').and_return('installed') } + it { is_expected.to run.with_params('absent', 'package').and_return('absent') } + it { is_expected.to run.with_params(false, 'package').and_return('absent') } + end +end diff --git a/spec/functions/str2bool_spec.rb b/spec/functions/str2bool_spec.rb old mode 100755 new mode 100644 index 7d8c47c19..9259910b1 --- a/spec/functions/str2bool_spec.rb +++ b/spec/functions/str2bool_spec.rb @@ -1,22 +1,26 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'str2bool' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { - pending("Current implementation ignores parameters after the first.") - is_expected.to run.with_params('true', 'extra').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) + pending('Current implementation ignores parameters after the first.') + expect(subject).to run.with_params('true', 'extra').and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } - it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, /Unknown type of boolean given/) } + + it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, %r{Unknown type of boolean given}) } describe 'when testing values that mean "true"' do - [ 'TRUE','1', 't', 'y', 'true', 'yes', true ].each do |value| + ['TRUE', '1', 't', 'y', 'true', 'yes', true].each do |value| it { is_expected.to run.with_params(value).and_return(true) } end end describe 'when testing values that mean "false"' do - [ 'FALSE','', '0', 'f', 'n', 'false', 'no', false, 'undef', 'undefined' ].each do |value| + ['FALSE', '', '0', 'f', 'n', 'false', 'no', false, 'undef', 'undefined'].each do |value| it { is_expected.to run.with_params(value).and_return(false) } end end diff --git a/spec/functions/str2resource_spec.rb b/spec/functions/str2resource_spec.rb new file mode 100644 index 000000000..1c8582f0b --- /dev/null +++ b/spec/functions/str2resource_spec.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'stdlib::str2resource' do + context 'when default' do + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(ArgumentError, %r{stdlib::str2resource}) } + end + + context 'when testing simple resource definitions exist' do + let :pre_condition do + <<-PRECOND + file { 'foo': } + file { '/foo': } + file { 'foot': } + user { 'foo': } + PRECOND + end + + file_foo = Puppet::Resource.new(:file, 'foo') + user_foo = Puppet::Resource.new(:user, 'foo') + + it { is_expected.to run.with_params('File[foo]').and_return(file_foo) } + it { is_expected.not_to run.with_params('File[\'foo\']') } + it { is_expected.not_to run.with_params('File["foo"]') } + + it { is_expected.to run.with_params('User[foo]').and_return(user_foo) } + end + + context 'when someone tries a compound definition' do + let :pre_condition do + 'user { "foo, bar": }' + end + + user_foo_bar = Puppet::Resource.new(:user, 'foo, bar') + + it { is_expected.to run.with_params('User[foo, bar]').and_return(user_foo_bar) } + end + + context 'when testing simple resource definitions no exist' do + it { is_expected.not_to run.with_params('File[foo]') } + end +end diff --git a/spec/functions/str2saltedpbkdf2_spec.rb b/spec/functions/str2saltedpbkdf2_spec.rb new file mode 100644 index 000000000..907b18509 --- /dev/null +++ b/spec/functions/str2saltedpbkdf2_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'str2saltedpbkdf2' do + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(ArgumentError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params('Pa55w0rd', 2).and_raise_error(ArgumentError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params(1, 'Using s0m3 s@lt', 50_000).and_raise_error(ArgumentError, %r{first argument must be a string}) } + it { is_expected.to run.with_params('Pa55w0rd', 1, 50_000).and_raise_error(ArgumentError, %r{second argument must be a string}) } + it { is_expected.to run.with_params('Pa55w0rd', 'U', 50_000).and_raise_error(ArgumentError, %r{second argument must be at least 8 bytes long}) } + it { is_expected.to run.with_params('Pa55w0rd', 'Using s0m3 s@lt', '50000').and_raise_error(ArgumentError, %r{third argument must be an integer}) } + it { is_expected.to run.with_params('Pa55w0rd', 'Using s0m3 s@lt', 1).and_raise_error(ArgumentError, %r{third argument must be between 40,000 and 70,000}) } + + context 'when running with "Pa55w0rd", "Using s0m3 s@lt",and "50000" as params' do + # rubocop:disable Layout/LineLength + it { + expect(subject).to run.with_params('Pa55w0rd', 'Using s0m3 s@lt', 50_000) + .and_return('password_hex' => '3577f79f7d2e73df1cf1eecc36da16fffcd3650126d79e797a8b227492d13de4cdd0656933b43118b7361692f755e5b3c1e0536f826d12442400f3467bcc8fb4ac2235d5648b0f1b0906d0712aecd265834319b5a42e98af2ced81597fd78d1ac916f6eff6122c3577bb120a9f534e2a5c9a58c7d1209e3914c967c6a467b594', + 'salt_hex' => '5573696e672073306d332073406c74', + 'iterations' => 50_000) + } + # rubocop:enable Layout/LineLength + end +end diff --git a/spec/functions/str2saltedsha512_spec.rb b/spec/functions/str2saltedsha512_spec.rb old mode 100755 new mode 100644 index 2e1e818b5..3b468fdb6 --- a/spec/functions/str2saltedsha512_spec.rb +++ b/spec/functions/str2saltedsha512_spec.rb @@ -1,17 +1,47 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'str2saltedsha512' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('password', 2).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /Requires a String argument/) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params('password', 2).and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, %r{Requires a String argument}) } context 'when running with a specific seed' do # make tests deterministic before(:each) { srand(2) } - it { is_expected.to run.with_params('').and_return('0f8a612f4eeed08e47b3875d00f33c5688f7926298f2d9b5fe19d1323f910bc78b6f7b5892596d2fabaa65e7a8d99b3768c102610cf0432c4827eee01f09451e3fae4f7a') } - it { is_expected.to run.with_params('password').and_return('0f8a612f43134376566c5707718d600effcfb17581fc9d3fa64d7f447dfda317c174ffdb498d2c5bd5c2075dab41c9d7ada5afbdc6b55354980eb5ba61802371e6b64956') } - it { is_expected.to run.with_params('verylongpassword').and_return('0f8a612f7a448537540e062daa8621f9bae326ca8ccb899e1bdb10e7c218cebfceae2530b856662565fdc4d81e986fc50cfbbc46d50436610ed9429ff5e43f2c45b5d039') } + if Puppet::PUPPETVERSION[0].to_i < 8 + it { + expect(subject).to run.with_params('') + .and_return('0f8a612f4eeed08e47b3875d00f33c5688f7926298f2d9b5fe19d1323f910bc78b6f7b5892596d2fabaa65e7a8d99b3768c102610cf0432c4827eee01f09451e3fae4f7a') + } + + it { + expect(subject).to run.with_params('password') + .and_return('0f8a612f43134376566c5707718d600effcfb17581fc9d3fa64d7f447dfda317c174ffdb498d2c5bd5c2075dab41c9d7ada5afbdc6b55354980eb5ba61802371e6b64956') + } + + it { + expect(subject).to run.with_params('verylongpassword') + .and_return('0f8a612f7a448537540e062daa8621f9bae326ca8ccb899e1bdb10e7c218cebfceae2530b856662565fdc4d81e986fc50cfbbc46d50436610ed9429ff5e43f2c45b5d039') + } + else + it { + expect(subject).to run.with_params('') + .and_return('a85c9d6f8c1eb1a625fd59e3cbca7dc7ab04ff1758d19ab99f098446e14a0a2a42e11afd1f4d6f17adfe2c772a3e6a821ee66a2564711431e14da96a3bff44593cf158ab') + } + + it { + expect(subject).to run.with_params('password') + .and_return('a85c9d6ff4e4dd6655ec2922ee9752550f2df4dc370e9739dd94899f62be6a42cc31fbfce3d62be35e0e8482696c931f63fb9286cf7b13d283660720c55f2a6304d06958') + } + + it { + expect(subject).to run.with_params('verylongpassword') + .and_return('a85c9d6fb810d0b8311c9a065c026e3179ae91fee3dbaf556f297e2fda2a8e3d8dd363977f9ef5c9b5da0cd518a5151a4e537928533291d68c9539d4d4b83da53b22a869') + } + end end end diff --git a/spec/functions/strftime_spec.rb b/spec/functions/strftime_spec.rb deleted file mode 100755 index e76774aa3..000000000 --- a/spec/functions/strftime_spec.rb +++ /dev/null @@ -1,26 +0,0 @@ -require 'spec_helper' - -describe 'strftime' do - it "should exist" do - expect(Puppet::Parser::Functions.function("strftime")).to eq("function_strftime") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_strftime([]) }.to( raise_error(Puppet::ParseError)) - end - - it "using %s should be higher then when I wrote this test" do - result = scope.function_strftime(["%s"]) - expect(result.to_i).to(be > 1311953157) - end - - it "using %s should be lower then 1.5 trillion" do - result = scope.function_strftime(["%s"]) - expect(result.to_i).to(be < 1500000000) - end - - it "should return a date when given %Y-%m-%d" do - result = scope.function_strftime(["%Y-%m-%d"]) - expect(result).to match(/^\d{4}-\d{2}-\d{2}$/) - end -end diff --git a/spec/functions/strip_spec.rb b/spec/functions/strip_spec.rb deleted file mode 100755 index 689b6dd0c..000000000 --- a/spec/functions/strip_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -require 'spec_helper' - -describe 'strip' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { - pending("Current implementation ignores parameters after the first.") - is_expected.to run.with_params('', '').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) - } - it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, /Requires either array or string to work with/) } - it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /Requires either array or string to work with/) } - it { is_expected.to run.with_params('').and_return('') } - it { is_expected.to run.with_params(' ').and_return('') } - it { is_expected.to run.with_params(' ').and_return('') } - it { is_expected.to run.with_params("\t").and_return('') } - it { is_expected.to run.with_params("\t ").and_return('') } - it { is_expected.to run.with_params('one').and_return('one') } - it { is_expected.to run.with_params(' one').and_return('one') } - it { is_expected.to run.with_params(' one').and_return('one') } - it { is_expected.to run.with_params("\tone").and_return('one') } - it { is_expected.to run.with_params("\t one").and_return('one') } - it { is_expected.to run.with_params('one ').and_return('one') } - it { is_expected.to run.with_params(' one ').and_return('one') } - it { is_expected.to run.with_params(' one ').and_return('one') } - it { is_expected.to run.with_params("\tone ").and_return('one') } - it { is_expected.to run.with_params("\t one ").and_return('one') } - it { is_expected.to run.with_params("one \t").and_return('one') } - it { is_expected.to run.with_params(" one \t").and_return('one') } - it { is_expected.to run.with_params(" one \t").and_return('one') } - it { is_expected.to run.with_params("\tone \t").and_return('one') } - it { is_expected.to run.with_params("\t one \t").and_return('one') } - it { is_expected.to run.with_params(' o n e ').and_return('o n e') } - it { is_expected.to run.with_params(AlsoString.new(' one ')).and_return('one') } -end diff --git a/spec/functions/suffix_spec.rb b/spec/functions/suffix_spec.rb old mode 100755 new mode 100644 index b48a4ebf6..04d42739a --- a/spec/functions/suffix_spec.rb +++ b/spec/functions/suffix_spec.rb @@ -1,44 +1,35 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'suffix' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { - pending("Current implementation ignores parameters after the second.") - is_expected.to run.with_params([], 'a', '').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) + pending('Current implementation ignores parameters after the second.') + expect(subject).to run.with_params([], 'a', '').and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } - it { is_expected.to run.with_params('', '').and_raise_error(Puppet::ParseError, /expected first argument to be an Array/) } - it { is_expected.to run.with_params([], 2).and_raise_error(Puppet::ParseError, /expected second argument to be a String/) } + + it { is_expected.to run.with_params('', '').and_raise_error(Puppet::ParseError, %r{expected first argument to be an Array}) } + it { is_expected.to run.with_params([], 2).and_raise_error(Puppet::ParseError, %r{expected second argument to be a String}) } it { is_expected.to run.with_params([]).and_return([]) } it { is_expected.to run.with_params(['one', 2]).and_return(['one', '2']) } it { is_expected.to run.with_params([], '').and_return([]) } it { is_expected.to run.with_params([''], '').and_return(['']) } it { is_expected.to run.with_params(['one'], 'post').and_return(['onepost']) } it { is_expected.to run.with_params(['one', 'two', 'three'], 'post').and_return(['onepost', 'twopost', 'threepost']) } + it { is_expected.to run.with_params(['ỗńέ', 'ńשׂǿ', 'ŧҺř℮ə'], 'Ń€į»•ÅÅ£').and_return(['į»—Å„Ī­Ń€į»•ÅÅ£', 'Å„×©×‚ĒæŃ€į»•ÅÅ£', 'Å§ŅŗÅ™ā„®É™Ń€į»•ÅÅ£']) } + + it { is_expected.to run.with_params({}).and_return({}) } + it { is_expected.to run.with_params('key1' => 'value1', 2 => 3).and_return('key1' => 'value1', '2' => 3) } + it { is_expected.to run.with_params({}, '').and_return({}) } + it { is_expected.to run.with_params({ 'key' => 'value' }, '').and_return('key' => 'value') } + it { is_expected.to run.with_params({ 'key' => 'value' }, 'post').and_return('keypost' => 'value') } + it { - pending("implementation of Hash functionality matching prefix") - is_expected.to run.with_params({}).and_return({}) - } - it { - pending("implementation of Hash functionality matching prefix") - is_expected.to run.with_params({ 'key1' => 'value1', 2 => 3}).and_return({ 'key1' => 'value1', '2' => 3 }) - } - it { - pending("implementation of Hash functionality matching prefix") - is_expected.to run.with_params({}, '').and_return({}) - } - it { - pending("implementation of Hash functionality matching prefix") - is_expected.to run.with_params({ 'key' => 'value' }, '').and_return({ 'key' => 'value' }) - } - it { - pending("implementation of Hash functionality matching prefix") - is_expected.to run.with_params({ 'key' => 'value' }, 'post').and_return({ 'keypost' => 'value' }) - } - it { - pending("implementation of Hash functionality matching prefix") - is_expected.to run \ - .with_params({ 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3' }, 'pre') \ - .and_return({ 'key1post' => 'value1', 'key2post' => 'value2', 'key3post' => 'value3' }) + expect(subject).to run \ + .with_params({ 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3' }, 'post') \ + .and_return('key1post' => 'value1', 'key2post' => 'value2', 'key3post' => 'value3') } end diff --git a/spec/functions/swapcase_spec.rb b/spec/functions/swapcase_spec.rb old mode 100755 new mode 100644 index c175a1588..6f3141b41 --- a/spec/functions/swapcase_spec.rb +++ b/spec/functions/swapcase_spec.rb @@ -1,23 +1,30 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'swapcase' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { - pending("Current implementation ignores parameters after the first.") - is_expected.to run.with_params('a', '').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) + pending('Current implementation ignores parameters after the first.') + expect(subject).to run.with_params('a', '').and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } - it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } - it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } - it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } + + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, %r{Requires either array or string to work}) } + it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, %r{Requires either array or string to work}) } + it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, %r{Requires either array or string to work}) } + describe 'with strings as inputs' do it { is_expected.to run.with_params('').and_return('') } it { is_expected.to run.with_params('one').and_return('ONE') } it { is_expected.to run.with_params('ONE').and_return('one') } it { is_expected.to run.with_params('oNe').and_return('OnE') } end + describe 'with arrays as inputs' do it { is_expected.to run.with_params([]).and_return([]) } + describe 'only containing strings' do it { is_expected.to run.with_params(['']).and_return(['']) } it { is_expected.to run.with_params(['one']).and_return(['ONE']) } @@ -27,6 +34,7 @@ it { is_expected.to run.with_params(['ONE', 'OnE']).and_return(['one', 'oNe']) } it { is_expected.to run.with_params(['oNe', 'one']).and_return(['OnE', 'ONE']) } end + describe 'containing mixed types' do it { is_expected.to run.with_params(['OnE', {}]).and_return(['oNe', {}]) } it { is_expected.to run.with_params(['OnE', 1]).and_return(['oNe', 1]) } @@ -34,7 +42,8 @@ it { is_expected.to run.with_params(['OnE', ['two']]).and_return(['oNe', ['two']]) } end end - it "should accept objects which extend String" do - is_expected.to run.with_params(AlsoString.new("OnE")).and_return('oNe') + + it 'accepts objects which extend String' do + expect(subject).to run.with_params(AlsoString.new('OnE')).and_return('oNe') end end diff --git a/spec/functions/time_spec.rb b/spec/functions/time_spec.rb old mode 100755 new mode 100644 index d157939e9..079bb0d30 --- a/spec/functions/time_spec.rb +++ b/spec/functions/time_spec.rb @@ -1,21 +1,23 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'time' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params('a', '').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.not_to be_nil } context 'when running at a specific time' do - before(:each) { + before(:each) do # get a value before stubbing the function test_time = Time.utc(2006, 10, 13, 8, 15, 11) - Time.expects(:new).with().returns(test_time).once - } - it { is_expected.to run.with_params().and_return(1160727311) } - it { is_expected.to run.with_params('').and_return(1160727311) } - it { is_expected.to run.with_params([]).and_return(1160727311) } - it { is_expected.to run.with_params({}).and_return(1160727311) } - it { is_expected.to run.with_params('foo').and_return(1160727311) } - it { is_expected.to run.with_params('UTC').and_return(1160727311) } - it { is_expected.to run.with_params('America/New_York').and_return(1160727311) } + allow(Time).to receive(:now).and_return(test_time) + end + + it { is_expected.to run.with_params.and_return(1_160_727_311) } + it { is_expected.to run.with_params('').and_return(1_160_727_311) } + + describe('Timezone is irrelevant') do + it { is_expected.to run.with_params('UTC').and_return(1_160_727_311) } + it { is_expected.to run.with_params('America/New_York').and_return(1_160_727_311) } + end end end diff --git a/spec/functions/to_bytes_spec.rb b/spec/functions/to_bytes_spec.rb old mode 100755 new mode 100644 index 2be23ff2d..b86be5361 --- a/spec/functions/to_bytes_spec.rb +++ b/spec/functions/to_bytes_spec.rb @@ -1,12 +1,14 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'to_bytes' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('1', 'extras').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params([]).and_raise_error(TypeError, /(can't convert|no implicit conversion of) Array (in)?to String/) } - it { is_expected.to run.with_params({}).and_raise_error(TypeError, /(can't convert|no implicit conversion of) Hash (in)?to String/) } - it { is_expected.to run.with_params(true).and_raise_error(TypeError, /(can't convert|no implicit conversion of) (TrueClass|true) (in)?to String/) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params('1', 'extras').and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params([]).and_raise_error(TypeError, %r{(can't convert|no implicit conversion of) Array (in)?to String}) } + it { is_expected.to run.with_params({}).and_raise_error(TypeError, %r{(can't convert|no implicit conversion of) Hash (in)?to String}) } + it { is_expected.to run.with_params(true).and_raise_error(TypeError, %r{(can't convert|no implicit conversion of) (TrueClass|true) (in)?to String}) } describe 'when passing numbers' do it { is_expected.to run.with_params(0).and_return(0) } @@ -28,22 +30,20 @@ describe 'with a unit' do it { is_expected.to run.with_params('1k').and_return(1024) } it { is_expected.to run.with_params('-1kB').and_return(-1024) } - it { is_expected.to run.with_params('1k').and_return(1024) } - it { is_expected.to run.with_params('1M').and_return(1024*1024) } - it { is_expected.to run.with_params('1G').and_return(1024*1024*1024) } - it { is_expected.to run.with_params('1T').and_return(1024*1024*1024*1024) } - it { is_expected.to run.with_params('1P').and_return(1024*1024*1024*1024*1024) } - it { is_expected.to run.with_params('1E').and_return(1024*1024*1024*1024*1024*1024) } - it { is_expected.to run.with_params('1.5e3M').and_return(1572864000) } + it { is_expected.to run.with_params('1M').and_return(1024 * 1024) } + it { is_expected.to run.with_params('1G').and_return(1024 * 1024 * 1024) } + it { is_expected.to run.with_params('1T').and_return(1024 * 1024 * 1024 * 1024) } + it { is_expected.to run.with_params('1P').and_return(1024 * 1024 * 1024 * 1024 * 1024) } + it { is_expected.to run.with_params('1E').and_return(1024 * 1024 * 1024 * 1024 * 1024 * 1024) } + it { is_expected.to run.with_params('1.5e3M').and_return(1_572_864_000) } - it { is_expected.to run.with_params('4k').and_return(4*1024) } - it { is_expected.to run.with_params('-4kB').and_return(4*-1024) } - it { is_expected.to run.with_params('4k').and_return(4*1024) } - it { is_expected.to run.with_params('4M').and_return(4*1024*1024) } - it { is_expected.to run.with_params('4G').and_return(4*1024*1024*1024) } - it { is_expected.to run.with_params('4T').and_return(4*1024*1024*1024*1024) } - it { is_expected.to run.with_params('4P').and_return(4*1024*1024*1024*1024*1024) } - it { is_expected.to run.with_params('4E').and_return(4*1024*1024*1024*1024*1024*1024) } + it { is_expected.to run.with_params('4k').and_return(4 * 1024) } + it { is_expected.to run.with_params('-4kB').and_return(4 * -1024) } + it { is_expected.to run.with_params('4M').and_return(4 * 1024 * 1024) } + it { is_expected.to run.with_params('4G').and_return(4 * 1024 * 1024 * 1024) } + it { is_expected.to run.with_params('4T').and_return(4 * 1024 * 1024 * 1024 * 1024) } + it { is_expected.to run.with_params('4P').and_return(4 * 1024 * 1024 * 1024 * 1024 * 1024) } + it { is_expected.to run.with_params('4E').and_return(4 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024) } # these are so wrong it { is_expected.to run.with_params('1.0001 k').and_return(1024) } @@ -51,12 +51,12 @@ end describe 'with a unknown unit' do - it { is_expected.to run.with_params('1KB').and_raise_error(Puppet::ParseError, /Unknown prefix/) } - it { is_expected.to run.with_params('1K').and_raise_error(Puppet::ParseError, /Unknown prefix/) } - it { is_expected.to run.with_params('1mb').and_raise_error(Puppet::ParseError, /Unknown prefix/) } - it { is_expected.to run.with_params('1m').and_raise_error(Puppet::ParseError, /Unknown prefix/) } - it { is_expected.to run.with_params('1%').and_raise_error(Puppet::ParseError, /Unknown prefix/) } - it { is_expected.to run.with_params('1 p').and_raise_error(Puppet::ParseError, /Unknown prefix/) } + it { is_expected.to run.with_params('1KB').and_raise_error(Puppet::ParseError, %r{Unknown prefix}) } + it { is_expected.to run.with_params('1K').and_raise_error(Puppet::ParseError, %r{Unknown prefix}) } + it { is_expected.to run.with_params('1mb').and_raise_error(Puppet::ParseError, %r{Unknown prefix}) } + it { is_expected.to run.with_params('1m').and_raise_error(Puppet::ParseError, %r{Unknown prefix}) } + it { is_expected.to run.with_params('1%').and_raise_error(Puppet::ParseError, %r{Unknown prefix}) } + it { is_expected.to run.with_params('1 p').and_raise_error(Puppet::ParseError, %r{Unknown prefix}) } end end diff --git a/spec/functions/to_json_pretty_spec.rb b/spec/functions/to_json_pretty_spec.rb new file mode 100644 index 000000000..f1a54e54b --- /dev/null +++ b/spec/functions/to_json_pretty_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'stdlib::to_json_pretty' do + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params([]).and_return("[\n\n]\n") } + it { is_expected.to run.with_params(['one']).and_return("[\n \"one\"\n]\n") } + it { is_expected.to run.with_params(['one', 'two']).and_return("[\n \"one\",\n \"two\"\n]\n") } + it { is_expected.to run.with_params({}).and_return("{\n}\n") } + it { is_expected.to run.with_params('key' => 'value').and_return("{\n \"key\": \"value\"\n}\n") } + + it { + expect(subject).to run.with_params('one' => { 'oneA' => 'A', 'oneB' => { 'oneB1' => '1', 'oneB2' => '2' } }, 'two' => ['twoA', 'twoB']) + .and_return("{\n \"one\": {\n \"oneA\": \"A\",\n \"oneB\": {\n \"oneB1\": \"1\",\n \"oneB2\": \"2\"\n }\n },\n \"two\": [\n \"twoA\",\n \"twoB\"\n ]\n}\n") # rubocop:disable Layout/LineLength : Unable to reduce line to required length + } + + it { is_expected.to run.with_params({ 'one' => '1', 'two' => nil }, true).and_return("{\n \"one\": \"1\"\n}\n") } + it { is_expected.to run.with_params(['one', 'two', nil, 'three'], true).and_return("[\n \"one\",\n \"two\",\n \"three\"\n]\n") } + it { is_expected.to run.with_params(['one', 'two', nil, 'three'], true, 'indent' => '@@@@').and_return("[\n@@@@\"one\",\n@@@@\"two\",\n@@@@\"three\"\n]\n") } + + it { + pending('Current implementation only elides nil values for arrays of depth=1') + expect(subject).to run.with_params([[nil], 'two', nil, 'three'], true).and_return("[\n [\n\n ],\n \"two\",\n \"three\"\n]\n") + } + + it { + pending('Current implementation only elides nil values for hashes of depth=1') + expect(subject).to run.with_params({ 'omg' => { 'lol' => nil }, 'what' => nil }, true).and_return("{\n}\n") + } +end diff --git a/spec/functions/to_json_spec.rb b/spec/functions/to_json_spec.rb new file mode 100644 index 000000000..06de89658 --- /dev/null +++ b/spec/functions/to_json_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'stdlib::to_json' do + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params('').and_return('""') } + it { is_expected.to run.with_params(true).and_return('true') } + it { is_expected.to run.with_params('one').and_return('"one"') } + it { is_expected.to run.with_params([]).and_return('[]') } + it { is_expected.to run.with_params(['one']).and_return('["one"]') } + it { is_expected.to run.with_params(['one', 'two']).and_return('["one","two"]') } + it { is_expected.to run.with_params({}).and_return('{}') } + it { is_expected.to run.with_params('key' => 'value').and_return('{"key":"value"}') } + + it { + expect(subject).to run.with_params('one' => { 'oneA' => 'A', 'oneB' => { 'oneB1' => '1', 'oneB2' => '2' } }, 'two' => ['twoA', 'twoB']) + .and_return('{"one":{"oneA":"A","oneB":{"oneB1":"1","oneB2":"2"}},"two":["twoA","twoB"]}') + } + + it { is_expected.to run.with_params('‰').and_return('"‰"') } + it { is_expected.to run.with_params('竹').and_return('"竹"') } + it { is_expected.to run.with_params('Ü').and_return('"Ü"') } + it { is_expected.to run.with_params('āˆ‡').and_return('"āˆ‡"') } +end diff --git a/spec/functions/to_python_spec.rb b/spec/functions/to_python_spec.rb new file mode 100644 index 000000000..5dede9fcd --- /dev/null +++ b/spec/functions/to_python_spec.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'stdlib::to_python' do + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params('').and_return('""') } + it { is_expected.to run.with_params(nil).and_return('None') } + it { is_expected.to run.with_params(true).and_return('True') } + it { is_expected.to run.with_params(false).and_return('False') } + it { is_expected.to run.with_params('one').and_return('"one"') } + it { is_expected.to run.with_params(42).and_return('42') } + it { is_expected.to run.with_params([]).and_return('[]') } + it { is_expected.to run.with_params(['one']).and_return('["one"]') } + it { is_expected.to run.with_params(['one', 'two']).and_return('["one", "two"]') } + it { is_expected.to run.with_params({}).and_return('{}') } + it { is_expected.to run.with_params('key' => 'value').and_return('{"key": "value"}') } + + it { + expect(subject).to run.with_params('one' => { 'oneA' => 'A', 'oneB' => { 'oneB1' => '1', 'oneB2' => '2' } }, 'two' => ['twoA', 'twoB']) + .and_return('{"one": {"oneA": "A", "oneB": {"oneB1": "1", "oneB2": "2"}}, "two": ["twoA", "twoB"]}') + } + + it { is_expected.to run.with_params('‰').and_return('"‰"') } + it { is_expected.to run.with_params('竹').and_return('"竹"') } + it { is_expected.to run.with_params('Ü').and_return('"Ü"') } + it { is_expected.to run.with_params('āˆ‡').and_return('"āˆ‡"') } +end diff --git a/spec/functions/to_ruby_spec.rb b/spec/functions/to_ruby_spec.rb new file mode 100644 index 000000000..846bd1b33 --- /dev/null +++ b/spec/functions/to_ruby_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'stdlib::to_ruby' do + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params('').and_return('""') } + it { is_expected.to run.with_params(nil).and_return('nil') } + it { is_expected.to run.with_params(true).and_return('true') } + it { is_expected.to run.with_params('one').and_return('"one"') } + it { is_expected.to run.with_params(42).and_return('42') } + it { is_expected.to run.with_params([]).and_return('[]') } + it { is_expected.to run.with_params(['one']).and_return('["one"]') } + it { is_expected.to run.with_params(['one', 'two']).and_return('["one", "two"]') } + it { is_expected.to run.with_params({}).and_return('{}') } + it { is_expected.to run.with_params('key' => 'value').and_return('{"key" => "value"}') } + + it { + expect(subject).to run.with_params('one' => { 'oneA' => 'A', 'oneB' => { 'oneB1' => '1', 'oneB2' => '2' } }, 'two' => ['twoA', 'twoB']) + .and_return('{"one" => {"oneA" => "A", "oneB" => {"oneB1" => "1", "oneB2" => "2"}}, "two" => ["twoA", "twoB"]}') + } + + it { is_expected.to run.with_params('‰').and_return('"‰"') } + it { is_expected.to run.with_params('竹').and_return('"竹"') } + it { is_expected.to run.with_params('Ü').and_return('"Ü"') } + it { is_expected.to run.with_params('āˆ‡').and_return('"āˆ‡"') } +end diff --git a/spec/functions/to_toml_spec.rb b/spec/functions/to_toml_spec.rb new file mode 100644 index 000000000..7347e0f2d --- /dev/null +++ b/spec/functions/to_toml_spec.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'stdlib::to_toml' do + context 'fails on invalid params' do + it { is_expected.not_to be_nil } + + [ + nil, + '', + 'foobar', + 1, + true, + false, + [], + ].each do |value| + it { is_expected.to run.with_params(value).and_raise_error(ArgumentError) } + end + end + + context 'returns TOML string on valid params' do + it { is_expected.to run.with_params({}).and_return('') } + it { is_expected.to run.with_params(foo: 'bar').and_return("foo = \"bar\"\n") } + it { is_expected.to run.with_params(foo: { bar: 'baz' }).and_return("[foo]\nbar = \"baz\"\n") } + it { is_expected.to run.with_params(foo: ['bar', 'baz']).and_return("foo = [\"bar\", \"baz\"]\n") } + it { is_expected.to run.with_params(foo: [{ bar: {}, baz: {} }]).and_return("[[foo]]\n[foo.bar]\n[foo.baz]\n") } + end +end diff --git a/spec/functions/to_yaml_spec.rb b/spec/functions/to_yaml_spec.rb new file mode 100644 index 000000000..3d8dfcd5d --- /dev/null +++ b/spec/functions/to_yaml_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'stdlib::to_yaml' do + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params('').and_return("--- ''\n") } + it { is_expected.to run.with_params(true).and_return(%r{--- true\n}) } + it { is_expected.to run.with_params('one').and_return(%r{--- one\n}) } + it { is_expected.to run.with_params([]).and_return("--- []\n") } + it { is_expected.to run.with_params(['one']).and_return("---\n- one\n") } + it { is_expected.to run.with_params(['one', 'two']).and_return("---\n- one\n- two\n") } + it { is_expected.to run.with_params({}).and_return("--- {}\n") } + it { is_expected.to run.with_params('key' => 'value').and_return("---\nkey: value\n") } + + it { + expect(subject).to run.with_params('one' => { 'oneA' => 'A', 'oneB' => { 'oneB1' => '1', 'oneB2' => '2' } }, 'two' => ['twoA', 'twoB']) + .and_return("---\none:\n oneA: A\n oneB:\n oneB1: '1'\n oneB2: '2'\ntwo:\n- twoA\n- twoB\n") + } + + it { is_expected.to run.with_params('‰').and_return("--- \"‰\"\n") } + it { is_expected.to run.with_params('āˆ‡').and_return("--- \"āˆ‡\"\n") } + + it { is_expected.to run.with_params({ 'foo' => { 'bar' => true, 'baz' => false } }, 'indentation' => 4).and_return("---\nfoo:\n bar: true\n baz: false\n") } +end diff --git a/spec/functions/try_get_value_spec.rb b/spec/functions/try_get_value_spec.rb deleted file mode 100644 index 38c0efdd2..000000000 --- a/spec/functions/try_get_value_spec.rb +++ /dev/null @@ -1,100 +0,0 @@ -require 'spec_helper' - -describe 'try_get_value' do - - let(:data) do - { - 'a' => { - 'g' => '2', - 'e' => [ - 'f0', - 'f1', - { - 'x' => { - 'y' => 'z' - } - }, - 'f3', - ] - }, - 'b' => true, - 'c' => false, - 'd' => '1', - } - end - - context 'single values' do - it 'should exist' do - is_expected.not_to eq(nil) - end - - it 'should be able to return a single value' do - is_expected.to run.with_params('test').and_return('test') - end - - it 'should use the default value if data is a single value and path is present' do - is_expected.to run.with_params('test', 'path', 'default').and_return('default') - end - - it 'should return default if there is no data' do - is_expected.to run.with_params(nil, nil, 'default').and_return('default') - end - - it 'should be able to use data structures as default values' do - is_expected.to run.with_params('test', 'path', data).and_return(data) - end - end - - context 'structure values' do - it 'should be able to extracts a single hash value' do - is_expected.to run.with_params(data, 'd', 'default').and_return('1') - end - - it 'should be able to extract a deeply nested hash value' do - is_expected.to run.with_params(data, 'a/g', 'default').and_return('2') - end - - it 'should return the default value if the path is not found' do - is_expected.to run.with_params(data, 'missing', 'default').and_return('default') - end - - it 'should return the default value if the path is too long' do - is_expected.to run.with_params(data, 'a/g/c/d', 'default').and_return('default') - end - - it 'should support an array index in the path' do - is_expected.to run.with_params(data, 'a/e/1', 'default').and_return('f1') - end - - it 'should return the default value if an array index is not a number' do - is_expected.to run.with_params(data, 'a/b/c', 'default').and_return('default') - end - - it 'should return the default value if and index is out of array length' do - is_expected.to run.with_params(data, 'a/e/5', 'default').and_return('default') - end - - it 'should be able to path though both arrays and hashes' do - is_expected.to run.with_params(data, 'a/e/2/x/y', 'default').and_return('z') - end - - it 'should be able to return "true" value' do - is_expected.to run.with_params(data, 'b', 'default').and_return(true) - is_expected.to run.with_params(data, 'm', true).and_return(true) - end - - it 'should be able to return "false" value' do - is_expected.to run.with_params(data, 'c', 'default').and_return(false) - is_expected.to run.with_params(data, 'm', false).and_return(false) - end - - it 'should return "nil" if value is not found and no default value is provided' do - is_expected.to run.with_params(data, 'a/1').and_return(nil) - end - - it 'should be able to use a custom path separator' do - is_expected.to run.with_params(data, 'a::g', 'default', '::').and_return('2') - is_expected.to run.with_params(data, 'a::c', 'default', '::').and_return('default') - end - end -end diff --git a/spec/functions/type3x_spec.rb b/spec/functions/type3x_spec.rb deleted file mode 100644 index c3eb1deee..000000000 --- a/spec/functions/type3x_spec.rb +++ /dev/null @@ -1,41 +0,0 @@ -require 'spec_helper' - -describe 'type3x' do - it "should exist" do - expect(Puppet::Parser::Functions.function("type3x")).to eq("function_type3x") - end - - it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_type3x([]) }.to( raise_error(Puppet::ParseError)) - end - - it "should return string when given a string" do - result = scope.function_type3x(["aaabbbbcccc"]) - expect(result).to(eq('string')) - end - - it "should return array when given an array" do - result = scope.function_type3x([["aaabbbbcccc","asdf"]]) - expect(result).to(eq('array')) - end - - it "should return hash when given a hash" do - result = scope.function_type3x([{"a"=>1,"b"=>2}]) - expect(result).to(eq('hash')) - end - - it "should return integer when given an integer" do - result = scope.function_type3x(["1"]) - expect(result).to(eq('integer')) - end - - it "should return float when given a float" do - result = scope.function_type3x(["1.34"]) - expect(result).to(eq('float')) - end - - it "should return boolean when given a boolean" do - result = scope.function_type3x([true]) - expect(result).to(eq('boolean')) - end -end diff --git a/spec/functions/type_of_spec.rb b/spec/functions/type_of_spec.rb index cc9ef781c..a722aa688 100644 --- a/spec/functions/type_of_spec.rb +++ b/spec/functions/type_of_spec.rb @@ -1,25 +1,27 @@ +# frozen_string_literal: true + require 'spec_helper' -if ENV["FUTURE_PARSER"] == 'yes' - describe 'type_of' do +if ENV['FUTURE_PARSER'] == 'yes' + describe 'stdlib::type_of' do pending 'teach rspec-puppet to load future-only functions under 3.7.5' do - it { is_expected.not_to eq(nil) } + it { is_expected.not_to be_nil } end end end if Puppet.version.to_f >= 4.0 - describe 'type_of' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(ArgumentError) } + describe 'stdlib::type_of' do + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(ArgumentError) } it { is_expected.to run.with_params('', '').and_raise_error(ArgumentError) } it 'gives the type of a string' do - expect(subject.call({}, 'hello world')).to be_kind_of(Puppet::Pops::Types::PStringType) + expect(subject.call({}, 'hello world')).to be_a(Puppet::Pops::Types::PStringType) end it 'gives the type of an integer' do - expect(subject.call({}, 5)).to be_kind_of(Puppet::Pops::Types::PIntegerType) + expect(subject.call({}, 5)).to be_a(Puppet::Pops::Types::PIntegerType) end end end diff --git a/spec/functions/type_spec.rb b/spec/functions/type_spec.rb deleted file mode 100755 index 4288df09b..000000000 --- a/spec/functions/type_spec.rb +++ /dev/null @@ -1,42 +0,0 @@ -require 'spec_helper' - -describe 'type' do - it "should exist" do - expect(Puppet::Parser::Functions.function("type")).to eq("function_type") - end - - it "should give a deprecation warning when called" do - scope.expects(:warning).with("type() DEPRECATED: This function will cease to function on Puppet 4; please use type3x() before upgrading to puppet 4 for backwards-compatibility, or migrate to the new parser's typing system.") - scope.function_type(["aoeu"]) - end - - it "should return string when given a string" do - result = scope.function_type(["aaabbbbcccc"]) - expect(result).to(eq('string')) - end - - it "should return array when given an array" do - result = scope.function_type([["aaabbbbcccc","asdf"]]) - expect(result).to(eq('array')) - end - - it "should return hash when given a hash" do - result = scope.function_type([{"a"=>1,"b"=>2}]) - expect(result).to(eq('hash')) - end - - it "should return integer when given an integer" do - result = scope.function_type(["1"]) - expect(result).to(eq('integer')) - end - - it "should return float when given a float" do - result = scope.function_type(["1.34"]) - expect(result).to(eq('float')) - end - - it "should return boolean when given a boolean" do - result = scope.function_type([true]) - expect(result).to(eq('boolean')) - end -end diff --git a/spec/functions/union_spec.rb b/spec/functions/union_spec.rb old mode 100755 new mode 100644 index cfd38b602..da552b8f9 --- a/spec/functions/union_spec.rb +++ b/spec/functions/union_spec.rb @@ -1,13 +1,15 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'union' do describe 'argument checking' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('one', []).and_raise_error(Puppet::ParseError, /Every parameter must be an array/) } - it { is_expected.to run.with_params([], 'two').and_raise_error(Puppet::ParseError, /Every parameter must be an array/) } - it { is_expected.to run.with_params({}, {}).and_raise_error(Puppet::ParseError, /Every parameter must be an array/) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params('one', []).and_raise_error(Puppet::ParseError, %r{Every parameter must be an array}) } + it { is_expected.to run.with_params([], 'two').and_raise_error(Puppet::ParseError, %r{Every parameter must be an array}) } + it { is_expected.to run.with_params({}, {}).and_raise_error(Puppet::ParseError, %r{Every parameter must be an array}) } end it { is_expected.to run.with_params([], []).and_return([]) } @@ -20,5 +22,6 @@ it { is_expected.to run.with_params(['one', 'two', 'three'], ['two', 'two', 'three']).and_return(['one', 'two', 'three']) } it { is_expected.to run.with_params(['one', 'two'], ['two', 'three'], ['one', 'three']).and_return(['one', 'two', 'three']) } it { is_expected.to run.with_params(['one', 'two'], ['three', 'four'], ['one', 'two', 'three'], ['four']).and_return(['one', 'two', 'three', 'four']) } - it 'should not confuse types' do is_expected.to run.with_params(['1', '2', '3'], [1, 2]).and_return(['1', '2', '3', 1, 2]) end + it { is_expected.to run.with_params(['ốńə', 'ţשׂợ'], ['Å§Ä„Ńįŗæį»‡', 'Ę’į»ŸÅ³Å—'], ['ốńə', 'ţשׂợ', 'Å§Ä„Ńįŗæį»‡'], ['Ę’į»ŸÅ³Å—']).and_return(['ốńə', 'ţשׂợ', 'Å§Ä„Ńįŗæį»‡', 'Ę’į»ŸÅ³Å—']) } + it 'does not confuse types' do is_expected.to run.with_params(['1', '2', '3'], [1, 2]).and_return(['1', '2', '3', 1, 2]) end end diff --git a/spec/functions/unique_spec.rb b/spec/functions/unique_spec.rb deleted file mode 100755 index 24257a018..000000000 --- a/spec/functions/unique_spec.rb +++ /dev/null @@ -1,27 +0,0 @@ -require 'spec_helper' - -describe 'unique' do - describe 'signature validation' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { - pending("Current implementation ignores parameters after the first.") - is_expected.to run.with_params([], 'extra').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) - } - it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } - it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } - it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } - end - - context 'when called with an array' do - it { is_expected.to run.with_params([]).and_return([]) } - it { is_expected.to run.with_params(['a']).and_return(['a']) } - it { is_expected.to run.with_params(['a', 'b', 'a']).and_return(['a', 'b']) } - end - - context 'when called with a string' do - it { is_expected.to run.with_params('').and_return('') } - it { is_expected.to run.with_params('a').and_return('a') } - it { is_expected.to run.with_params('aaba').and_return('ab') } - end -end diff --git a/spec/functions/unix2dos_spec.rb b/spec/functions/unix2dos_spec.rb index 8537a26fa..9224615ac 100644 --- a/spec/functions/unix2dos_spec.rb +++ b/spec/functions/unix2dos_spec.rb @@ -1,40 +1,47 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'unix2dos' do - context 'Checking parameter validity' do - it { is_expected.not_to eq(nil) } + context 'when checking parameter validity' do + it { is_expected.not_to be_nil } + it do - is_expected.to run.with_params.and_raise_error(ArgumentError, /Wrong number of arguments/) + expect(subject).to run.with_params.and_raise_error(ArgumentError, %r{Wrong number of arguments}) end + it do - is_expected.to run.with_params('one', 'two').and_raise_error(ArgumentError, /Wrong number of arguments/) + expect(subject).to run.with_params('one', 'two').and_raise_error(ArgumentError, %r{Wrong number of arguments}) end + it do - is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError) + expect(subject).to run.with_params([]).and_raise_error(Puppet::ParseError) end + it do - is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError) + expect(subject).to run.with_params({}).and_raise_error(Puppet::ParseError) end + it do - is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError) + expect(subject).to run.with_params(1).and_raise_error(Puppet::ParseError) end end - context 'Converting from unix to dos format' do + context 'when converting from unix to dos format' do sample_text = "Hello\nWorld\n" desired_output = "Hello\r\nWorld\r\n" - it 'should output dos format' do - should run.with_params(sample_text).and_return(desired_output) + it 'outputs dos format' do + expect(subject).to run.with_params(sample_text).and_return(desired_output) end end - context 'Converting from dos to dos format' do + context 'when converting from dos to dos format' do sample_text = "Hello\r\nWorld\r\n" desired_output = "Hello\r\nWorld\r\n" - it 'should output dos format' do - should run.with_params(sample_text).and_return(desired_output) + it 'outputs dos format' do + expect(subject).to run.with_params(sample_text).and_return(desired_output) end end end diff --git a/spec/functions/upcase_spec.rb b/spec/functions/upcase_spec.rb deleted file mode 100755 index 3b7b02d47..000000000 --- a/spec/functions/upcase_spec.rb +++ /dev/null @@ -1,26 +0,0 @@ -require 'spec_helper' - -describe 'upcase' do - describe 'signature validation' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('', '').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /Requires an array, hash or object that responds to upcase/) } - it { is_expected.to run.with_params([1]).and_raise_error(Puppet::ParseError, /Requires an array, hash or object that responds to upcase/) } - end - - describe 'normal string handling' do - it { is_expected.to run.with_params("abc").and_return("ABC") } - it { is_expected.to run.with_params("Abc").and_return("ABC") } - it { is_expected.to run.with_params("ABC").and_return("ABC") } - end - - describe 'handling classes derived from String' do - it { is_expected.to run.with_params(AlsoString.new("ABC")).and_return("ABC") } - end - - describe 'strings in arrays handling' do - it { is_expected.to run.with_params([]).and_return([]) } - it { is_expected.to run.with_params(["One", "twO"]).and_return(["ONE", "TWO"]) } - end -end diff --git a/spec/functions/uriescape_spec.rb b/spec/functions/uriescape_spec.rb old mode 100755 new mode 100644 index f05ec088c..5d7606121 --- a/spec/functions/uriescape_spec.rb +++ b/spec/functions/uriescape_spec.rb @@ -1,36 +1,47 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'uriescape' do - describe 'signature validation' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { - pending("Current implementation ignores parameters after the first.") - is_expected.to run.with_params('', '').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) - } - it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } - it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } - it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, /Requires either array or string to work/) } - end + # URI.escape has been fully removed as of Ruby 3. Therefore, it will not work as it stand on Puppet 8. + if Puppet::Util::Package.versioncmp(Puppet.version, '8.0.0').negative? + describe 'signature validation' do + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + + it { + pending('Current implementation ignores parameters after the first.') + expect(subject).to run.with_params('', '').and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) + } - describe 'handling normal strings' do - it 'should call ruby\'s URI.escape function' do - URI.expects(:escape).with('uri_string').returns('escaped_uri_string').once - is_expected.to run.with_params('uri_string').and_return('escaped_uri_string') + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, %r{Requires either array or string to work}) } + it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, %r{Requires either array or string to work}) } + it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, %r{Requires either array or string to work}) } end - end - describe 'handling classes derived from String' do - it 'should call ruby\'s URI.escape function' do - uri_string = AlsoString.new('uri_string') - URI.expects(:escape).with(uri_string).returns('escaped_uri_string').once - is_expected.to run.with_params(uri_string).and_return("escaped_uri_string") + describe 'handling normal strings' do + it 'calls ruby\'s URI::DEFAULT_PARSER.escape function' do + expect(URI::DEFAULT_PARSER).to receive(:escape).with('uri_string').and_return('escaped_uri_string').once + expect(subject).to run.with_params('uri_string').and_return('escaped_uri_string') + end end - end - describe 'strings in arrays handling' do - it { is_expected.to run.with_params([]).and_return([]) } - it { is_expected.to run.with_params(["one}", "two"]).and_return(["one%7D", "two"]) } - it { is_expected.to run.with_params(["one}", 1, true, {}, "two"]).and_return(["one%7D", 1, true, {}, "two"]) } + describe 'handling classes derived from String' do + it 'calls ruby\'s URI::DEFAULT_PARSER.escape function' do + uri_string = AlsoString.new('uri_string') + expect(URI::DEFAULT_PARSER).to receive(:escape).with(uri_string).and_return('escaped_uri_string').once + expect(subject).to run.with_params(uri_string).and_return('escaped_uri_string') + end + end + + describe 'strings in arrays handling' do + it { is_expected.to run.with_params([]).and_return([]) } + it { is_expected.to run.with_params(['one}', 'two']).and_return(['one%7D', 'two']) } + it { is_expected.to run.with_params(['one}', 1, true, {}, 'two']).and_return(['one%7D', 1, true, {}, 'two']) } + end + else + describe 'raising errors in Puppet 8' do + it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError, %r{This function is not available in Puppet 8. URI.escape no longer exists as of Ruby 3+.}) } + end end end diff --git a/spec/functions/validate_absolute_path_spec.rb b/spec/functions/validate_absolute_path_spec.rb deleted file mode 100755 index 4a8404d81..000000000 --- a/spec/functions/validate_absolute_path_spec.rb +++ /dev/null @@ -1,62 +0,0 @@ -require 'spec_helper' - -describe 'validate_absolute_path' do - describe 'signature validation' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - end - - describe "valid paths handling" do - %w{ - C:/ - C:\\ - C:\\WINDOWS\\System32 - C:/windows/system32 - X:/foo/bar - X:\\foo\\bar - \\\\host\\windows - //host/windows - / - /var/tmp - /var/opt/../lib/puppet - }.each do |path| - it { is_expected.to run.with_params(path) } - it { is_expected.to run.with_params(['/tmp', path]) } - end - end - - describe 'invalid path handling' do - context 'garbage inputs' do - [ - nil, - [ nil ], - [ nil, nil ], - { 'foo' => 'bar' }, - { }, - '', - ].each do |path| - it { is_expected.to run.with_params(path).and_raise_error(Puppet::ParseError, /is not an absolute path/) } - it { is_expected.to run.with_params([path]).and_raise_error(Puppet::ParseError, /is not an absolute path/) } - it { is_expected.to run.with_params(['/tmp', path]).and_raise_error(Puppet::ParseError, /is not an absolute path/) } - end - end - - context 'relative paths' do - %w{ - relative1 - . - .. - ./foo - ../foo - etc/puppetlabs/puppet - opt/puppet/bin - relative\\windows - }.each do |path| - it { is_expected.to run.with_params(path).and_raise_error(Puppet::ParseError, /is not an absolute path/) } - it { is_expected.to run.with_params([path]).and_raise_error(Puppet::ParseError, /is not an absolute path/) } - it { is_expected.to run.with_params(['/tmp', path]).and_raise_error(Puppet::ParseError, /is not an absolute path/) } - end - end - end -end - diff --git a/spec/functions/validate_array_spec.rb b/spec/functions/validate_array_spec.rb deleted file mode 100755 index 4ee7754f8..000000000 --- a/spec/functions/validate_array_spec.rb +++ /dev/null @@ -1,27 +0,0 @@ -require 'spec_helper' - -describe 'validate_array' do - describe 'signature validation' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - - describe 'valid inputs' do - it { is_expected.to run.with_params([]) } - it { is_expected.to run.with_params(['one']) } - it { is_expected.to run.with_params([], ['two']) } - it { is_expected.to run.with_params(['one'], ['two']) } - end - - describe 'invalid inputs' do - it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, /is not an Array/) } - it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /is not an Array/) } - it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, /is not an Array/) } - it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, /is not an Array/) } - it { is_expected.to run.with_params([], {}).and_raise_error(Puppet::ParseError, /is not an Array/) } - it { is_expected.to run.with_params([], 1).and_raise_error(Puppet::ParseError, /is not an Array/) } - it { is_expected.to run.with_params([], true).and_raise_error(Puppet::ParseError, /is not an Array/) } - it { is_expected.to run.with_params([], 'one').and_raise_error(Puppet::ParseError, /is not an Array/) } - end - end -end - diff --git a/spec/functions/validate_augeas_spec.rb b/spec/functions/validate_augeas_spec.rb old mode 100755 new mode 100644 index 4236649d6..d238859bd --- a/spec/functions/validate_augeas_spec.rb +++ b/spec/functions/validate_augeas_spec.rb @@ -1,21 +1,21 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'validate_augeas' do - unless Puppet.features.augeas? - skip "ruby-augeas not installed" - else + if Puppet.features.augeas? describe 'signature validation' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('', '', [], '', 'extra').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params('').and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params('', '', [], '', 'extra').and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } it { is_expected.to run.with_params('one', 'one', 'MSG to User', '4th arg').and_raise_error(NoMethodError) } end describe 'valid inputs' do inputs = [ - [ "root:x:0:0:root:/root:/bin/bash\n", 'Passwd.lns' ], - [ "proc /proc proc nodev,noexec,nosuid 0 0\n", 'Fstab.lns'], + ["root:x:0:0:root:/root:/bin/bash\n", 'Passwd.lns'], + ["proc /proc proc nodev,noexec,nosuid 0 0\n", 'Fstab.lns'], ] inputs.each do |input| @@ -28,32 +28,32 @@ # don't specify an error message to display. This is the behvior in # 2.2.x and prior. inputs = [ - [ "root:x:0:0:root\n", 'Passwd.lns' ], - [ "127.0.1.1\n", 'Hosts.lns' ], + ["root:x:0:0:root\n", 'Passwd.lns'], + ["127.0.1.1\n", 'Hosts.lns'], ] inputs.each do |input| - it { is_expected.to run.with_params(*input).and_raise_error(Puppet::ParseError, /validate_augeas.*?matched less than it should/) } + it { is_expected.to run.with_params(*input).and_raise_error(Puppet::ParseError, %r{validate_augeas.*?matched less than it should}) } end end - describe "when specifying nice error messages" do + describe 'when specifying nice error messages' do # The intent here is to make sure the function returns the 4th argument # in the exception thrown inputs = [ - [ "root:x:0:0:root\n", 'Passwd.lns', [], 'Failed to validate passwd content' ], - [ "127.0.1.1\n", 'Hosts.lns', [], 'Wrong hosts content' ], + ["root:x:0:0:root\n", 'Passwd.lns', [], 'Failed to validate passwd content'], + ["127.0.1.1\n", 'Hosts.lns', [], 'Wrong hosts content'], ] inputs.each do |input| - it { is_expected.to run.with_params(*input).and_raise_error(Puppet::ParseError, /#{input[3]}/) } + it { is_expected.to run.with_params(*input).and_raise_error(Puppet::ParseError, %r{#{input[3]}}) } end end - describe "matching additional tests" do + describe 'matching additional tests' do inputs = [ - [ "root:x:0:0:root:/root:/bin/bash\n", 'Passwd.lns', ['$file/foobar']], - [ "root:x:0:0:root:/root:/bin/bash\n", 'Passwd.lns', ['$file/root/shell[.="/bin/sh"]', 'foobar']], + ["root:x:0:0:root:/root:/bin/bash\n", 'Passwd.lns', ['$file/foobar']], + ["root:x:0:0:root:/root:/bin/bash\n", 'Passwd.lns', ['$file/root/shell[.="/bin/sh"]', 'foobar']], ] inputs.each do |input| @@ -61,15 +61,17 @@ end end - describe "failing additional tests" do + describe 'failing additional tests' do inputs = [ - [ "foobar:x:0:0:root:/root:/bin/bash\n", 'Passwd.lns', ['$file/foobar']], - [ "root:x:0:0:root:/root:/bin/sh\n", 'Passwd.lns', ['$file/root/shell[.="/bin/sh"]', 'foobar']], + ["foobar:x:0:0:root:/root:/bin/bash\n", 'Passwd.lns', ['$file/foobar']], + ["root:x:0:0:root:/root:/bin/sh\n", 'Passwd.lns', ['$file/root/shell[.="/bin/sh"]', 'foobar']], ] inputs.each do |input| - it { is_expected.to run.with_params(*input).and_raise_error(Puppet::ParseError, /testing path/) } + it { is_expected.to run.with_params(*input).and_raise_error(Puppet::ParseError, %r{testing path}) } end end + else + skip 'ruby-augeas not installed' end end diff --git a/spec/functions/validate_bool_spec.rb b/spec/functions/validate_bool_spec.rb deleted file mode 100755 index d9cdf572e..000000000 --- a/spec/functions/validate_bool_spec.rb +++ /dev/null @@ -1,25 +0,0 @@ -require 'spec_helper' - -describe 'validate_bool' do - describe 'signature validation' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - end - - describe 'acceptable values' do - it { is_expected.to run.with_params(true) } - it { is_expected.to run.with_params(false) } - it { is_expected.to run.with_params(true, false, false, true) } - end - - describe 'validation failures' do - it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, /is not a boolean/) } - it { is_expected.to run.with_params(true, 'one').and_raise_error(Puppet::ParseError, /is not a boolean/) } - it { is_expected.to run.with_params('one', false).and_raise_error(Puppet::ParseError, /is not a boolean/) } - it { is_expected.to run.with_params("true").and_raise_error(Puppet::ParseError, /is not a boolean/) } - it { is_expected.to run.with_params("false").and_raise_error(Puppet::ParseError, /is not a boolean/) } - it { is_expected.to run.with_params(true, "false").and_raise_error(Puppet::ParseError, /is not a boolean/) } - it { is_expected.to run.with_params("true", false).and_raise_error(Puppet::ParseError, /is not a boolean/) } - it { is_expected.to run.with_params("true", false, false, false, false, false).and_raise_error(Puppet::ParseError, /is not a boolean/) } - end -end diff --git a/spec/functions/validate_cmd_spec.rb b/spec/functions/validate_cmd_spec.rb old mode 100755 new mode 100644 index ab0cbc9a7..e3e6155cc --- a/spec/functions/validate_cmd_spec.rb +++ b/spec/functions/validate_cmd_spec.rb @@ -1,35 +1,49 @@ +# frozen_string_literal: true + require 'spec_helper' -describe 'validate_cmd' do - let(:touch) { File.exists?('/usr/bin/touch') ? '/usr/bin/touch' : '/bin/touch' } +describe 'validate_cmd', unless: Puppet::Util::Platform.windows? do + let(:touch) { File.exist?('/usr/bin/touch') ? '/usr/bin/touch' : '/bin/touch' } describe 'signature validation' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('', '', '', 'extra').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params('').and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params('', '', '', 'extra').and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { pending('should implement stricter type checking') - is_expected.to run.with_params([], '', '').and_raise_error(Puppet::ParseError, /content must be a string/) + expect(subject).to run.with_params([], '', '').and_raise_error(Puppet::ParseError, %r{content must be a string}) } + it { pending('should implement stricter type checking') - is_expected.to run.with_params('', [], '').and_raise_error(Puppet::ParseError, /checkscript must be a string/) + expect(subject).to run.with_params('', [], '').and_raise_error(Puppet::ParseError, %r{checkscript must be a string}) } + it { pending('should implement stricter type checking') - is_expected.to run.with_params('', '', []).and_raise_error(Puppet::ParseError, /custom error message must be a string/) + expect(subject).to run.with_params('', '', []).and_raise_error(Puppet::ParseError, %r{custom error message must be a string}) } end context 'when validation fails' do context 'with % placeholder' do - it { is_expected.to run.with_params('', "#{touch} % /no/such/file").and_raise_error(Puppet::ParseError, /Execution of '#{touch} \S+ \/no\/such\/file' returned 1:.*(cannot touch|o such file or)/) } - it { is_expected.to run.with_params('', "#{touch} % /no/such/file", 'custom error').and_raise_error(Puppet::ParseError, /custom error/) } + it { + expect(subject).to run + .with_params('', "#{touch} % /no/such/file").and_raise_error(Puppet::ParseError, %r{Execution of '#{touch} \S+ /no/such/file' returned 1:.*(cannot touch|o such file or)}) + } + + it { is_expected.to run.with_params('', "#{touch} % /no/such/file", 'custom error').and_raise_error(Puppet::ParseError, %r{custom error}) } end + context 'without % placeholder' do - it { is_expected.to run.with_params('', "#{touch} /no/such/file").and_raise_error(Puppet::ParseError, /Execution of '#{touch} \/no\/such\/file \S+' returned 1:.*(cannot touch|o such file or)/) } - it { is_expected.to run.with_params('', "#{touch} /no/such/file", 'custom error').and_raise_error(Puppet::ParseError, /custom error/) } + it { + expect(subject).to run + .with_params('', "#{touch} /no/such/file").and_raise_error(Puppet::ParseError, %r{Execution of '#{touch} /no/such/file \S+' returned 1:.*(cannot touch|o such file or)}) + } + + it { is_expected.to run.with_params('', "#{touch} /no/such/file", 'custom error').and_raise_error(Puppet::ParseError, %r{custom error}) } end end end diff --git a/spec/functions/validate_domain_name_spec.rb b/spec/functions/validate_domain_name_spec.rb new file mode 100644 index 000000000..2c3958dac --- /dev/null +++ b/spec/functions/validate_domain_name_spec.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'stdlib::validate_domain_name' do + describe 'signature validation' do + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(ArgumentError, %r{wrong number of arguments}i) } + end + + describe 'valid inputs' do + it { is_expected.to run.with_params('com', 'com.') } + it { is_expected.to run.with_params('x.com', 'x.com.') } + it { is_expected.to run.with_params('foo.example.com', 'foo.example.com.') } + it { is_expected.to run.with_params('2foo.example.com', '2foo.example.com.') } + it { is_expected.to run.with_params('www.2foo.example.com', 'www.2foo.example.com.') } + it { is_expected.to run.with_params('domain.tld', 'puppet.com') } + it { is_expected.to run.with_params('www.example.2com') } + it { is_expected.to run.with_params('10.10.10.10.10') } + end + + describe 'invalid inputs' do + it { is_expected.to run.with_params([]).and_raise_error(ArgumentError, %r{got Array}) } + it { is_expected.to run.with_params({}).and_raise_error(ArgumentError, %r{got Hash}) } + it { is_expected.to run.with_params(1).and_raise_error(ArgumentError, %r{got Integer}) } + it { is_expected.to run.with_params(true).and_raise_error(ArgumentError, %r{got Boolean}) } + + it { is_expected.to run.with_params('foo.example.com', []).and_raise_error(ArgumentError, %r{got Array}) } + it { is_expected.to run.with_params('foo.example.com', {}).and_raise_error(ArgumentError, %r{got Hash}) } + it { is_expected.to run.with_params('foo.example.com', 1).and_raise_error(ArgumentError, %r{got Integer}) } + it { is_expected.to run.with_params('foo.example.com', true).and_raise_error(ArgumentError, %r{got Boolean}) } + + it { is_expected.to run.with_params('').and_raise_error(ArgumentError, %r{got ''}) } + it { is_expected.to run.with_params('invalid domain').and_raise_error(ArgumentError, %r{got 'invalid domain'}) } + it { is_expected.to run.with_params('-foo.example.com').and_raise_error(ArgumentError, %r{got '-foo\.example\.com'}) } + end +end diff --git a/spec/functions/validate_email_address_spec.rb b/spec/functions/validate_email_address_spec.rb new file mode 100644 index 000000000..95a384508 --- /dev/null +++ b/spec/functions/validate_email_address_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'stdlib::validate_email_address' do + describe 'signature validation' do + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(ArgumentError, %r{wrong number of arguments}i) } + end + + describe 'valid inputs' do + it { is_expected.to run.with_params('bob@gmail.com') } + it { is_expected.to run.with_params('alice+puppetlabs.com@gmail.com') } + end + + describe 'invalid inputs' do + it { is_expected.to run.with_params({}).and_raise_error(ArgumentError, %r{got Hash}) } + it { is_expected.to run.with_params(1).and_raise_error(ArgumentError, %r{got Integer}) } + it { is_expected.to run.with_params(true).and_raise_error(ArgumentError, %r{got Boolean}) } + it { is_expected.to run.with_params('one').and_raise_error(ArgumentError, %r{got 'one'}) } + it { is_expected.to run.with_params('bob@gmail.com', {}).and_raise_error(ArgumentError, %r{got Hash}) } + it { is_expected.to run.with_params('bob@gmail.com', true).and_raise_error(ArgumentError, %r{got Boolean}) } + it { is_expected.to run.with_params('bob@gmail.com', 'one').and_raise_error(ArgumentError, %r{got 'one'}) } + end +end diff --git a/spec/functions/validate_hash_spec.rb b/spec/functions/validate_hash_spec.rb deleted file mode 100755 index 2e8e59fb8..000000000 --- a/spec/functions/validate_hash_spec.rb +++ /dev/null @@ -1,26 +0,0 @@ -require 'spec_helper' - -describe 'validate_hash' do - describe 'signature validation' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - - describe 'valid inputs' do - it { is_expected.to run.with_params({}) } - it { is_expected.to run.with_params({'key' => 'value'}) } - it { is_expected.to run.with_params({}, {'key' => 'value'}) } - it { is_expected.to run.with_params({'key1' => 'value1'}, {'key2' => 'value2'}) } - end - - describe 'invalid inputs' do - it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError, /is not a Hash/) } - it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /is not a Hash/) } - it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, /is not a Hash/) } - it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, /is not a Hash/) } - it { is_expected.to run.with_params({}, []).and_raise_error(Puppet::ParseError, /is not a Hash/) } - it { is_expected.to run.with_params({}, 1).and_raise_error(Puppet::ParseError, /is not a Hash/) } - it { is_expected.to run.with_params({}, true).and_raise_error(Puppet::ParseError, /is not a Hash/) } - it { is_expected.to run.with_params({}, 'one').and_raise_error(Puppet::ParseError, /is not a Hash/) } - end - end -end diff --git a/spec/functions/validate_integer_spec.rb b/spec/functions/validate_integer_spec.rb deleted file mode 100755 index 4c0a9d7d4..000000000 --- a/spec/functions/validate_integer_spec.rb +++ /dev/null @@ -1,90 +0,0 @@ -require 'spec_helper' - -describe 'validate_integer' do - describe 'signature validation' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params(1, 2, 3, 4).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - - [ true, 'true', false, 'false', 'iAmAString', '1test', '1 test', 'test 1', 'test 1 test', 7.0, -7.0, {}, { 'key' => 'value' }, { 1=> 2 }, '', :undef , 'x'].each do |invalid| - it { is_expected.to run.with_params(invalid).and_raise_error(Puppet::ParseError, /to be an Integer/) } - it { is_expected.to run.with_params(invalid, 10).and_raise_error(Puppet::ParseError, /to be an Integer/) } - it { is_expected.to run.with_params(invalid, 10, -10).and_raise_error(Puppet::ParseError, /to be an Integer/) } - it { is_expected.to run.with_params([0, 1, 2, invalid, 3, 4], 10, -10).and_raise_error(Puppet::ParseError, /to be an Integer/) } - end - - context 'when running on modern rubies', :unless => RUBY_VERSION == '1.8.7' do - it { is_expected.to run.with_params([0, 1, 2, {1=>2}, 3, 4], 10, -10).and_raise_error(Puppet::ParseError, /to be an Integer/) } - end - - context 'when running on ruby, which munges hashes weirdly', :if => RUBY_VERSION == '1.8.7' do - it { is_expected.to run.with_params([0, 1, 2, {1=>2}, 3, 4], 10, -10).and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params([0, 1, 2, {0=>2}, 3, 4], 10, -10).and_raise_error(Puppet::ParseError) } - end - - it { is_expected.to run.with_params(1, '').and_raise_error(Puppet::ParseError, /to be unset or an Integer/) } - it { is_expected.to run.with_params(1, 2, '').and_raise_error(Puppet::ParseError, /to be unset or an Integer/) } - it { is_expected.to run.with_params(1, 2, 3).and_raise_error(Puppet::ParseError, /second argument to be larger than third argument/) } - end - - context 'with no range constraints' do - it { is_expected.to run.with_params(1) } - it { is_expected.to run.with_params(-1) } - it { is_expected.to run.with_params('1') } - it { is_expected.to run.with_params('-1') } - it { is_expected.to run.with_params([1, 2, 3, 4]) } - it { is_expected.to run.with_params([1, '2', '3', 4]) } - end - - context "with a maximum limit of 10" do - describe 'rejects numbers greater than the limit' do - it { is_expected.to run.with_params(11, 10).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } - it { is_expected.to run.with_params(100, 10).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } - it { is_expected.to run.with_params(2**65, 10).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } - it { is_expected.to run.with_params([1,2,10,100], 10).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } - end - - describe 'accepts numbers less or equal to the limit' do - it { is_expected.to run.with_params(10, 10) } - it { is_expected.to run.with_params(1, 10) } - it { is_expected.to run.with_params(-1, 10) } - it { is_expected.to run.with_params('1', 10) } - it { is_expected.to run.with_params('-1', 10) } - it { is_expected.to run.with_params([1, 2, 3, 4], 10) } - it { is_expected.to run.with_params([1, '2', '3', 4], 10) } - end - - context "with a minimum limit of -10" do - describe 'rejects numbers greater than the upper limit' do - it { is_expected.to run.with_params(11, 10, -10).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } - it { is_expected.to run.with_params(100, 10, -10).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } - it { is_expected.to run.with_params(2**65, 10, -10).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } - it { is_expected.to run.with_params([1,2,10,100], 10, -10).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } - end - - describe 'rejects numbers smaller than the lower limit' do - it { is_expected.to run.with_params(-11, 10, -10).and_raise_error(Puppet::ParseError, /to be greater or equal/) } - it { is_expected.to run.with_params(-100, 10, -10).and_raise_error(Puppet::ParseError, /to be greater or equal/) } - it { is_expected.to run.with_params(-2**65, 10, -10).and_raise_error(Puppet::ParseError, /to be greater or equal/) } - it { is_expected.to run.with_params([-10, 1,2,10,-100], 10, -10).and_raise_error(Puppet::ParseError, /to be greater or equal/) } - end - - describe 'accepts numbers between and including the limits' do - it { is_expected.to run.with_params(10, 10, -10) } - it { is_expected.to run.with_params(-10, 10, -10) } - it { is_expected.to run.with_params(1, 10, -10) } - it { is_expected.to run.with_params(-1, 10, -10) } - it { is_expected.to run.with_params('1', 10, -10) } - it { is_expected.to run.with_params('-1', 10, -10) } - it { is_expected.to run.with_params([1, 2, 3, 4], 10, -10) } - it { is_expected.to run.with_params([1, '2', '3', 4], 10, -10) } - end - end - end - - it { is_expected.to run.with_params(10, 10, 10) } - - describe 'empty upper limit is interpreted as infinity' do - it { is_expected.to run.with_params(11, '', 10) } - end -end diff --git a/spec/functions/validate_ip_address_spec.rb b/spec/functions/validate_ip_address_spec.rb deleted file mode 100644 index b56ce51c2..000000000 --- a/spec/functions/validate_ip_address_spec.rb +++ /dev/null @@ -1,46 +0,0 @@ -require 'spec_helper' - -describe 'validate_ip_address' do - describe 'signature validation' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - end - - describe 'valid inputs' do - it { is_expected.to run.with_params('0.0.0.0') } - it { is_expected.to run.with_params('8.8.8.8') } - it { is_expected.to run.with_params('127.0.0.1') } - it { is_expected.to run.with_params('10.10.10.10') } - it { is_expected.to run.with_params('194.232.104.150') } - it { is_expected.to run.with_params('244.24.24.24') } - it { is_expected.to run.with_params('255.255.255.255') } - it { is_expected.to run.with_params('1.2.3.4', '5.6.7.8') } - it { is_expected.to run.with_params('3ffe:0505:0002::') } - it { is_expected.to run.with_params('3ffe:0505:0002::', '3ffe:0505:0002::2') } - it { is_expected.to run.with_params('::1/64') } - it { is_expected.to run.with_params('fe80::a00:27ff:fe94:44d6/64') } - context 'with netmasks' do - it { is_expected.to run.with_params('8.8.8.8/0') } - it { is_expected.to run.with_params('8.8.8.8/16') } - it { is_expected.to run.with_params('8.8.8.8/32') } - it { is_expected.to run.with_params('8.8.8.8/255.255.0.0') } - end - end - - describe 'invalid inputs' do - it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, /is not a string/) } - it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /is not a string/) } - it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, /is not a string/) } - it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, /is not a valid IP/) } - it { is_expected.to run.with_params('0.0.0').and_raise_error(Puppet::ParseError, /is not a valid IP/) } - it { is_expected.to run.with_params('0.0.0.256').and_raise_error(Puppet::ParseError, /is not a valid IP/) } - it { is_expected.to run.with_params('0.0.0.0.0').and_raise_error(Puppet::ParseError, /is not a valid IP/) } - it { is_expected.to run.with_params('1.2.3.4', {}).and_raise_error(Puppet::ParseError, /is not a string/) } - it { is_expected.to run.with_params('1.2.3.4', 1).and_raise_error(Puppet::ParseError, /is not a string/) } - it { is_expected.to run.with_params('1.2.3.4', true).and_raise_error(Puppet::ParseError, /is not a string/) } - it { is_expected.to run.with_params('1.2.3.4', 'one').and_raise_error(Puppet::ParseError, /is not a valid IP/) } - it { is_expected.to run.with_params('::1', {}).and_raise_error(Puppet::ParseError, /is not a string/) } - it { is_expected.to run.with_params('::1', true).and_raise_error(Puppet::ParseError, /is not a string/) } - it { is_expected.to run.with_params('::1', 'one').and_raise_error(Puppet::ParseError, /is not a valid IP/) } - end -end diff --git a/spec/functions/validate_ipv4_address_spec.rb b/spec/functions/validate_ipv4_address_spec.rb deleted file mode 100755 index b6170d438..000000000 --- a/spec/functions/validate_ipv4_address_spec.rb +++ /dev/null @@ -1,40 +0,0 @@ -require 'spec_helper' - -describe 'validate_ipv4_address' do - describe 'signature validation' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - - describe 'valid inputs' do - it { is_expected.to run.with_params('0.0.0.0') } - it { is_expected.to run.with_params('8.8.8.8') } - it { is_expected.to run.with_params('127.0.0.1') } - it { is_expected.to run.with_params('10.10.10.10') } - it { is_expected.to run.with_params('194.232.104.150') } - it { is_expected.to run.with_params('244.24.24.24') } - it { is_expected.to run.with_params('255.255.255.255') } - it { is_expected.to run.with_params('1.2.3.4', '5.6.7.8') } - context 'with netmasks' do - it { is_expected.to run.with_params('8.8.8.8/0') } - it { is_expected.to run.with_params('8.8.8.8/16') } - it { is_expected.to run.with_params('8.8.8.8/32') } - it { is_expected.to run.with_params('8.8.8.8/255.255.0.0') } - end - end - - describe 'invalid inputs' do - it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, /is not a string/) } - it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /is not a string/) } - it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, /is not a string/) } - it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, /is not a valid IPv4/) } - it { is_expected.to run.with_params('0.0.0').and_raise_error(Puppet::ParseError, /is not a valid IPv4/) } - it { is_expected.to run.with_params('0.0.0.256').and_raise_error(Puppet::ParseError, /is not a valid IPv4/) } - it { is_expected.to run.with_params('0.0.0.0.0').and_raise_error(Puppet::ParseError, /is not a valid IPv4/) } - it { is_expected.to run.with_params('affe::beef').and_raise_error(Puppet::ParseError, /is not a valid IPv4/) } - it { is_expected.to run.with_params('1.2.3.4', {}).and_raise_error(Puppet::ParseError, /is not a string/) } - it { is_expected.to run.with_params('1.2.3.4', 1).and_raise_error(Puppet::ParseError, /is not a string/) } - it { is_expected.to run.with_params('1.2.3.4', true).and_raise_error(Puppet::ParseError, /is not a string/) } - it { is_expected.to run.with_params('1.2.3.4', 'one').and_raise_error(Puppet::ParseError, /is not a valid IPv4/) } - end - end -end diff --git a/spec/functions/validate_ipv6_address_spec.rb b/spec/functions/validate_ipv6_address_spec.rb deleted file mode 100755 index 7aaf0060a..000000000 --- a/spec/functions/validate_ipv6_address_spec.rb +++ /dev/null @@ -1,32 +0,0 @@ -require 'spec_helper' - -describe 'validate_ipv6_address' do - describe 'signature validation' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - - describe 'valid inputs' do - it { is_expected.to run.with_params('3ffe:0505:0002::') } - it { is_expected.to run.with_params('3ffe:0505:0002::', '3ffe:0505:0002::2') } - it { is_expected.to run.with_params('::1/64') } - it { is_expected.to run.with_params('fe80::a00:27ff:fe94:44d6/64') } - end - - describe 'invalid inputs' do - it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, /is not a string/) } - it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, /is not a string/) } - it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, /is not a valid IPv6/) } - it { is_expected.to run.with_params('0.0.0').and_raise_error(Puppet::ParseError, /is not a valid IPv6/) } - it { is_expected.to run.with_params('0.0.0.256').and_raise_error(Puppet::ParseError, /is not a valid IPv6/) } - it { is_expected.to run.with_params('0.0.0.0.0').and_raise_error(Puppet::ParseError, /is not a valid IPv6/) } - it { is_expected.to run.with_params('affe:beef').and_raise_error(Puppet::ParseError, /is not a valid IPv6/) } - it { is_expected.to run.with_params('::1', {}).and_raise_error(Puppet::ParseError, /is not a string/) } - it { is_expected.to run.with_params('::1', true).and_raise_error(Puppet::ParseError, /is not a string/) } - it { is_expected.to run.with_params('::1', 'one').and_raise_error(Puppet::ParseError, /is not a valid IPv6/) } - context 'unless running on ruby 1.8.7', :if => RUBY_VERSION != '1.8.7' do - it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /is not a string/) } - it { is_expected.to run.with_params('::1', 1).and_raise_error(Puppet::ParseError, /is not a string/) } - end - end - end -end diff --git a/spec/functions/validate_legacy_spec.rb b/spec/functions/validate_legacy_spec.rb new file mode 100644 index 000000000..e607b32f5 --- /dev/null +++ b/spec/functions/validate_legacy_spec.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require 'spec_helper' + +if Puppet::Util::Package.versioncmp(Puppet.version, '4.4.0') >= 0 + describe 'validate_legacy' do + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(ArgumentError) } + + describe 'when passing the type assertion' do + it 'passes with a deprecation warning' do + expect(subject.func).to receive(:call_function).with('deprecation', 'validate_legacy', include('deprecated')).once + expect(scope).not_to receive(:function_validate_foo) + expect(Puppet).not_to receive(:notice) + expect(subject).to run.with_params('Integer', 'validate_foo', 5) + end + end + + describe 'when failing the type assertion' do + it 'fails with a helpful message' do + expect(subject.func).to receive(:call_function).with('deprecation', 'validate_legacy', include('deprecated')).once + expect(scope).not_to receive(:function_validate_foo) + expect(subject.func).to receive(:call_function).with('fail', 'validate_legacy(Integer, ...) expects an Integer value, got String').once + expect(subject).to run.with_params('Integer', 'validate_foo', '5') + end + end + + describe 'when passing in undef' do + it 'passes without failure' do + expect(subject.func).to receive(:call_function).with('deprecation', 'validate_legacy', include('deprecated')).once + expect(scope).not_to receive(:function_validate_foo) + expect(Puppet).not_to receive(:notice) + expect(subject).to run.with_params('Optional[Integer]', 'validate_foo', :undef) + end + end + + describe 'when passing in multiple arguments' do + it 'passes with a deprecation message' do + expect(subject.func).to receive(:call_function).with('deprecation', 'validate_legacy', include('deprecated')).once + expect(scope).not_to receive(:function_validate_foo) + expect(Puppet).not_to receive(:notice) + expect(subject).to run.with_params('Optional[Integer]', 'validate_foo', :undef, 1, 'foo') + end + end + end +end diff --git a/spec/functions/validate_numeric_spec.rb b/spec/functions/validate_numeric_spec.rb deleted file mode 100755 index 9b8eb0eeb..000000000 --- a/spec/functions/validate_numeric_spec.rb +++ /dev/null @@ -1,89 +0,0 @@ -require 'spec_helper' - -describe 'validate_numeric' do - describe 'signature validation' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params(1, 2, 3, 4).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - - [ true, 'true', false, 'false', 'iAmAString', '1test', '1 test', 'test 1', 'test 1 test', {}, { 'key' => 'value' }, { 1=> 2 }, '', :undef , 'x'].each do |invalid| - it { is_expected.to run.with_params(invalid).and_raise_error(Puppet::ParseError, /to be a Numeric/) } - it { is_expected.to run.with_params(invalid, 10.0).and_raise_error(Puppet::ParseError, /to be a Numeric/) } - it { is_expected.to run.with_params(invalid, 10.0, -10.0).and_raise_error(Puppet::ParseError, /to be a Numeric/) } - end - - context 'when running on modern rubies', :unless => RUBY_VERSION == '1.8.7' do - it { is_expected.to run.with_params([0, 1, 2, {1=>2}, 3, 4], 10, -10).and_raise_error(Puppet::ParseError, /to be a Numeric/) } - end - - context 'when running on ruby, which munges hashes weirdly', :if => RUBY_VERSION == '1.8.7' do - it { is_expected.to run.with_params([0, 1, 2, {1=>2}, 3, 4], 10, -10).and_raise_error(Puppet::ParseError) } - it { is_expected.to run.with_params([0, 1, 2, {0=>2}, 3, 4], 10, -10).and_raise_error(Puppet::ParseError) } - end - - it { is_expected.to run.with_params(1, '').and_raise_error(Puppet::ParseError, /to be unset or a Numeric/) } - it { is_expected.to run.with_params(1, 2, '').and_raise_error(Puppet::ParseError, /to be unset or a Numeric/) } - it { is_expected.to run.with_params(1, 2, 3).and_raise_error(Puppet::ParseError, /second argument to be larger than third argument/) } - end - - context 'with no range constraints' do - it { is_expected.to run.with_params(1) } - it { is_expected.to run.with_params(-1) } - it { is_expected.to run.with_params('1') } - it { is_expected.to run.with_params('-1') } - it { is_expected.to run.with_params([1, 2, 3, 4]) } - it { is_expected.to run.with_params([1, '2', '3', 4]) } - end - - context "with a maximum limit of 10.0" do - describe 'rejects numbers greater than the limit' do - it { is_expected.to run.with_params(11, 10.0).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } - it { is_expected.to run.with_params(100, 10.0).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } - it { is_expected.to run.with_params(2**65, 10.0).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } - it { is_expected.to run.with_params([1,2,10.0,100], 10.0).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } - end - - describe 'accepts numbers less or equal to the limit' do - it { is_expected.to run.with_params(10.0, 10.0) } - it { is_expected.to run.with_params(1, 10.0) } - it { is_expected.to run.with_params(-1, 10.0) } - it { is_expected.to run.with_params('1', 10.0) } - it { is_expected.to run.with_params('-1', 10.0) } - it { is_expected.to run.with_params([1, 2, 3, 4], 10.0) } - it { is_expected.to run.with_params([1, '2', '3', 4], 10.0) } - end - - context "with a minimum limit of -10.0" do - describe 'rejects numbers greater than the upper limit' do - it { is_expected.to run.with_params(11, 10.0, -10.0).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } - it { is_expected.to run.with_params(100, 10.0, -10.0).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } - it { is_expected.to run.with_params(2**65, 10.0, -10.0).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } - it { is_expected.to run.with_params([1,2,10.0,100], 10.0, -10.0).and_raise_error(Puppet::ParseError, /to be smaller or equal/) } - end - - describe 'rejects numbers smaller than the lower limit' do - it { is_expected.to run.with_params(-11, 10.0, -10.0).and_raise_error(Puppet::ParseError, /to be greater or equal/) } - it { is_expected.to run.with_params(-100, 10.0, -10.0).and_raise_error(Puppet::ParseError, /to be greater or equal/) } - it { is_expected.to run.with_params(-2**65, 10.0, -10.0).and_raise_error(Puppet::ParseError, /to be greater or equal/) } - it { is_expected.to run.with_params([-10.0, 1,2,10.0,-100], 10.0, -10.0).and_raise_error(Puppet::ParseError, /to be greater or equal/) } - end - - describe 'accepts numbers between and including the limits' do - it { is_expected.to run.with_params(10.0, 10.0, -10.0) } - it { is_expected.to run.with_params(-10.0, 10.0, -10.0) } - it { is_expected.to run.with_params(1, 10.0, -10.0) } - it { is_expected.to run.with_params(-1, 10.0, -10.0) } - it { is_expected.to run.with_params('1', 10.0, -10.0) } - it { is_expected.to run.with_params('-1', 10.0, -10.0) } - it { is_expected.to run.with_params([1, 2, 3, 4], 10.0, -10.0) } - it { is_expected.to run.with_params([1, '2', '3', 4], 10.0, -10.0) } - end - end - end - - it { is_expected.to run.with_params(10.0, 10.0, 10.0) } - - describe 'empty upper limit is interpreted as infinity' do - it { is_expected.to run.with_params(11, '', 10.0) } - end -end diff --git a/spec/functions/validate_re_spec.rb b/spec/functions/validate_re_spec.rb deleted file mode 100755 index 3f9014370..000000000 --- a/spec/functions/validate_re_spec.rb +++ /dev/null @@ -1,61 +0,0 @@ -require 'spec_helper' - -describe 'validate_re' do - describe 'signature validation' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('', '', '', 'extra').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - - describe 'valid inputs' do - it { is_expected.to run.with_params('', '') } - it { is_expected.to run.with_params('', ['']) } - it { is_expected.to run.with_params('', [''], 'custom error') } - it { is_expected.to run.with_params('one', '^one') } - it { is_expected.to run.with_params('one', [ '^one', '^two' ]) } - it { is_expected.to run.with_params('one', [ '^one', '^two' ], 'custom error') } - end - - describe 'invalid inputs' do - it { - pending('should implement stricter type checking') - is_expected.to run.with_params([], '').and_raise_error(Puppet::ParseError, /is not a String/) - } - it { - pending('should implement stricter type checking') - is_expected.to run.with_params('', {}).and_raise_error(Puppet::ParseError, /is not an Array/) - } - it { - pending('should implement stricter type checking') - is_expected.to run.with_params('', '', []).and_raise_error(Puppet::ParseError, /is not a String/) - } - it { - pending('should implement stricter type checking') - is_expected.to run.with_params(nil, nil).and_raise_error(Puppet::ParseError, /is not a String/) - } - it { is_expected.to run.with_params('', []).and_raise_error(Puppet::ParseError, /does not match/) } - it { is_expected.to run.with_params('one', 'two').and_raise_error(Puppet::ParseError, /does not match/) } - it { is_expected.to run.with_params('', 'two').and_raise_error(Puppet::ParseError, /does not match/) } - it { is_expected.to run.with_params('', ['two']).and_raise_error(Puppet::ParseError, /does not match/) } - it { is_expected.to run.with_params('', ['two'], 'custom error').and_raise_error(Puppet::ParseError, /custom error/) } - it { is_expected.to run.with_params('notone', '^one').and_raise_error(Puppet::ParseError, /does not match/) } - it { is_expected.to run.with_params('notone', [ '^one', '^two' ]).and_raise_error(Puppet::ParseError, /does not match/) } - it { is_expected.to run.with_params('notone', [ '^one', '^two' ], 'custom error').and_raise_error(Puppet::ParseError, /custom error/) } - - describe 'non-string inputs' do - [ - 1, # Fixnum - 3.14, # Float - nil, # NilClass - true, # TrueClass - false, # FalseClass - ["10"], # Array - :key, # Symbol - {:key=>"val"}, # Hash - ].each do |input| - it { is_expected.to run.with_params(input, '.*').and_raise_error(Puppet::ParseError, /needs to be a String/) } - end - end - end - end -end diff --git a/spec/functions/validate_slength_spec.rb b/spec/functions/validate_slength_spec.rb deleted file mode 100755 index 5a8fa6a84..000000000 --- a/spec/functions/validate_slength_spec.rb +++ /dev/null @@ -1,61 +0,0 @@ -require 'spec_helper' - -describe 'validate_slength' do - describe 'signature validation' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('', 2, 3, 'extra').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('', '').and_raise_error(Puppet::ParseError, /second argument to be a positive Numeric/) } - it { is_expected.to run.with_params('', -1).and_raise_error(Puppet::ParseError, /second argument to be a positive Numeric/) } - it { is_expected.to run.with_params('', 1, '').and_raise_error(Puppet::ParseError, /third argument to be unset or a positive Numeric/) } - it { is_expected.to run.with_params('', 1, -1).and_raise_error(Puppet::ParseError, /third argument to be unset or a positive Numeric/) } - it { is_expected.to run.with_params('', 1, 2).and_raise_error(Puppet::ParseError, /argument to be equal to or larger than third argument/) } - end - - context "with a maximum length of 10" do - describe 'rejects strings longer than the limit' do - it { is_expected.to run.with_params('1234567890a', 10).and_raise_error(Puppet::ParseError, /Expected length/) } - it { is_expected.to run.with_params('1234567890abcdef', 10).and_raise_error(Puppet::ParseError, /Expected length/) } - it { is_expected.to run.with_params([ 'one', '1234567890abcdef' ], 10).and_raise_error(Puppet::ParseError, /Expected length/) } - end - - describe 'accepts strings shorter or equal to the limit' do - it { is_expected.to run.with_params('1234567890', 10) } - it { is_expected.to run.with_params('12345', 10) } - it { is_expected.to run.with_params([ 'one', 'two' ], 10) } - end - - context "with a minimum length of 5" do - describe 'rejects strings longer than the upper limit' do - it { is_expected.to run.with_params('1234567890a', 10, 5).and_raise_error(Puppet::ParseError, /Expected length/) } - it { is_expected.to run.with_params('1234567890abcdef', 10, 5).and_raise_error(Puppet::ParseError, /Expected length/) } - end - - describe 'rejects numbers shorter than the lower limit' do - it { is_expected.to run.with_params('one', 10, 5).and_raise_error(Puppet::ParseError, /Expected length/) } - it { is_expected.to run.with_params(['12345678', 'two'], 10, 5).and_raise_error(Puppet::ParseError, /Expected length/) } - end - - describe 'accepts strings of length between and including the limits' do - it { is_expected.to run.with_params('12345', 10, 5) } - it { is_expected.to run.with_params('123456', 10, 5) } - it { is_expected.to run.with_params('1234567', 10, 5) } - it { is_expected.to run.with_params('12345678', 10, 5) } - it { is_expected.to run.with_params('123456789', 10, 5) } - it { is_expected.to run.with_params('1234567890', 10, 5) } - it { is_expected.to run.with_params(['1233456', '12345678'], 10, 5) } - end - end - end - - describe 'corner cases' do - it { pending('this should work'); is_expected.to run.with_params('', 0, 0) } - it { is_expected.to run.with_params('1234567890', 10, 10) } - end - - describe 'empty upper limit is interpreted as infinity' do - it { pending('not implemented'); is_expected.to run.with_params('1234567890ab', '', 10) } - it { pending('not implemented'); is_expected.to run.with_params('12345678', '', 10).and_raise_error(Puppet::ParseError, /Expected length/) } - end -end diff --git a/spec/functions/validate_string_spec.rb b/spec/functions/validate_string_spec.rb deleted file mode 100755 index f0c500eb1..000000000 --- a/spec/functions/validate_string_spec.rb +++ /dev/null @@ -1,21 +0,0 @@ -require 'spec_helper' - -describe 'validate_string' do - describe 'signature validation' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - - describe 'valid inputs' do - it { is_expected.to run.with_params('') } - it { is_expected.to run.with_params('one') } - it { is_expected.to run.with_params('one', 'two') } - end - - describe 'invalid inputs' do - it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError, /is not a string/) } - it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, /is not a string/) } - it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /is not a string/) } - it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, /is not a string/) } - end - end -end diff --git a/spec/functions/validate_x509_rsa_key_pair_spec.rb b/spec/functions/validate_x509_rsa_key_pair_spec.rb new file mode 100644 index 000000000..a9e102b7f --- /dev/null +++ b/spec/functions/validate_x509_rsa_key_pair_spec.rb @@ -0,0 +1,179 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'validate_x509_rsa_key_pair' do + let(:valid_cert) do + <<~DOC + -----BEGIN CERTIFICATE----- + MIIC9jCCAeCgAwIBAgIRAK11n3X7aypJ7FPM8UFyAeowCwYJKoZIhvcNAQELMBIx + EDAOBgNVBAoTB0FjbWUgQ28wHhcNMTUxMTIzMjIzOTU4WhcNMTYxMTIyMjIzOTU4 + WjASMRAwDgYDVQQKEwdBY21lIENvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB + CgKCAQEAz9bY/piKahD10AiJSfbI2A8NG5UwRz0r9T/WfvNVdhgrsGFgNQjvpUoZ + nNJpQIHBbgMOiXqfATFjJl5FjEkSf7GUHohlGVls9MX2JmVvknzsiitd75H/EJd+ + N+k915lix8Vqmj8d1CTlbF/8tEjzANI67Vqw5QTuqebO7rkIUvRg6yiRfSo75FK1 + RinCJyl++kmleBwQZBInQyg95GvJ5JTqMzBs67DeeyzskDhTeTePRYVF2NwL8QzY + htvLIBERTNsyU5i7nkxY5ptUwgFUwd93LH4Q19tPqL5C5RZqXxhE51thOOwafm+a + W/cRkqYqV+tv+j1jJ3WICyF1JNW0BQIDAQABo0swSTAOBgNVHQ8BAf8EBAMCAKAw + EwYDVR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAUBgNVHREEDTALggls + b2NhbGhvc3QwCwYJKoZIhvcNAQELA4IBAQAzRo0hpVTrFQZLIXpwvKwZVGvJdCkV + P95DTsSk/VTGV+/YtxrRqks++hJZnctm2PbnTsCAoIP3AMx+vicCKiKrxvpsLU8/ + +6cowUbcuGMdSQktwDqbAgEhQlLsETll06w1D/KC+ejOc4+LRn3GQcEyGDtMk/EX + IeAvBZHr4/kVXWnfo6kzCLcku1f8yE/yDEFClZe9XV1Lk/s+3YfXVtNnMJJ1giZI + QVOe6CkmuQq+4AtIeW8aLkvlfp632jag1F77a1y+L268koKkj0hBMrtcErVQaxmq + xym0+soR4Tk4pTIGckeFglrLxkP2JpM/yTwSEAVlmG9vgTliYKyR0uMl + -----END CERTIFICATE----- + DOC + end + + let(:valid_key) do + <<~DOC + -----BEGIN RSA PRIVATE KEY----- + MIIEogIBAAKCAQEAz9bY/piKahD10AiJSfbI2A8NG5UwRz0r9T/WfvNVdhgrsGFg + NQjvpUoZnNJpQIHBbgMOiXqfATFjJl5FjEkSf7GUHohlGVls9MX2JmVvknzsiitd + 75H/EJd+N+k915lix8Vqmj8d1CTlbF/8tEjzANI67Vqw5QTuqebO7rkIUvRg6yiR + fSo75FK1RinCJyl++kmleBwQZBInQyg95GvJ5JTqMzBs67DeeyzskDhTeTePRYVF + 2NwL8QzYhtvLIBERTNsyU5i7nkxY5ptUwgFUwd93LH4Q19tPqL5C5RZqXxhE51th + OOwafm+aW/cRkqYqV+tv+j1jJ3WICyF1JNW0BQIDAQABAoIBADAiZ/r+xP+vkd5u + O61/lCBFzBlZQecdybJw6HJaVK6XBndA9hESUr4LHUdui6W+51ddKd65IV4bXAUk + zCKjQb+FFvLDT/bA+TTvLATUdTSN7hJJ3OWBAHuNOlQklof6JCB0Hi4+89+P8/pX + eKUgR/cmuTMDT/iaXdPHeqFbBQyA1ZpQFRjN5LyyJMS/9FkywuNc5wlpsArtc51T + gIKENUZCuPhosR+kMFc2iuTNvqZWPhvouSrmhi2O6nSqV+oy0+irlqSpCF2GsCI8 + 72TtLpq94Grrq0BEH5avouV+Lp4k83vO65OKCQKUFQlxz3Xkxm2U3J7KzxqnRtM3 + /b+cJ/kCgYEA6/yOnaEYhH/7ijhZbPn8RujXZ5VGJXKJqIuaPiHMmHVS5p1j6Bah + 2PcnqJA2IlLs3UloN+ziAxAIH6KCBiwlQ/uPBNMMaJsIjPNBEy8axjndKhKUpidg + R0OJ7RQqMShOJ8akrSfWdPtXC/GBuwCYE//t77GgZaIMO3FcT9EKA48CgYEA4Xcx + Fia0Jg9iyAhNmUOXI6hWcGENavMx01+x7XFhbnMjIKTZevFfTnTkrX6HyLXyGtMU + gHOn+k4PE/purI4ARrKO8m5wYEKqSIt4dBMTkIXXirfQjXgfjR8E4T/aPe5fOFZo + 7OYuxLRtzmG1C2sW4txwKAKX1LaWcVx/RLSttSsCgYBbcj8Brk+F6OJcqYFdzXGJ + OOlf5mSMVlopyg83THmwCqbZXtw8L6kAHqZrl5airmfDSJLuOQlMDoZXW+3u3mSC + d5TwVahVUN57YDgzaumBLyMZDqIz0MZqVy23hTzkV64Rk9R0lR9xrYQJyMhw4sYL + 2f0mCTsSpzz+O+t9so+i2QKBgEC38gMlwPhb2kMI/x1LZYr6uzUu5qcYf+jowy4h + KZKGwkKQj0zXFEB1FV8nvtpCP+irRmtIx6L13SYi8LnfWPzyLE4ynVdES5TfVAgd + obQOdzx+XwL8xDHCAaiWp5K3ZeXKB/xYZnxYPlzLdyh76Ond1OPnOqX4c16+6llS + c7pZAoGATd9NckT0XtXLEsF3IraDivq8dP6bccX2DNfS8UeEvRRrRwpFpSRrmuGb + jbG4yzoIX4RjQfj/z48hwhJB+cKiN9WwcPsFXtHe7v3F6BRwK0JUfrCiXad8/SGZ + KAf7Dfqi608zBdnPWHacre2Y35gPHB00nFQOLS6u46aBNSq07YA= + -----END RSA PRIVATE KEY----- + DOC + end + + let(:another_valid_key) do + <<~DOC + -----BEGIN RSA PRIVATE KEY----- + MIIEpAIBAAKCAQEAoISxYJBTPAeAzFnm+lE/ljLlmGal2Xr3vwZKkvJiuKA/m4QJ + 0ZNdtkBSDOVuG2dXVv6W4sChRtsCdvuVe7bjTYvlU8TWM3VEJDL9l9cRXScxxlKQ + Xwb35y1yV35NJfaK/jzm9KcErtQQs1RxvGlWRaohmLM8uQcuhjZfMsSlQoHQD5LX + sbPtk82RPyxYc1dj2vsaoi1VvuP2+jv4xLQOmNJY1bT5GTurqiltmxEtWhNNmGg0 + 2wtK00ifqLVO5HNc3gXQCDM2M99Sbmn1YtbrgsU9xMYfcPmvQvb+YoKskyoqck+c + HR//hi7vslbxABrny15LBkEfRc4TickphSGYXwIDAQABAoIBAATEzGw8/WwMIQRx + K06GeWgh7PZBHm4+m/ud2TtSXiJ0CE+7dXs3cJJIiOd/LW08/bhE6gCkjmYHfaRB + Ryicv1X/cPmzIFX5BuQ4a5ZGOmrVDkKBE27vSxAgJoR46RvWnjx9XLMp/xaekDxz + psldK8X4DvV1ZbltgDFWji947hvyqUtHdKnkQnc5j7aCIFJf9GMfzaeeDPMaL8WF + mVL4iy9EAOjNOHBshZj/OHyU5FbJ8ROwZQlCOiLCdFegftSIXt8EYDnjB3BdsALH + N6hquqrD7xDKyRbTD0K7lqxUubuMwTQpi61jZD8TBTXEPyFVAnoMpXkc0Y+np40A + YiIsR+kCgYEAyrc4Bh6fb9gt49IXGXOSRZ5i5+TmJho4kzIONrJ7Ndclwx9wzHfh + eGBodWaw5CxxQGMf4vEiaZrpAiSFeDffBLR+Wa2TFE5aWkdYkR34maDjO00m4PE1 + S+YsZoGw7rGmmj+KS4qv2T26FEHtUI+F31RC1FPohLsQ22Jbn1ORipsCgYEAyrYB + J2Ncf2DlX1C0GfxyUHQOTNl0V5gpGvpbZ0WmWksumYz2kSGOAJkxuDKd9mKVlAcz + czmN+OOetuHTNqds2JJKKJy6hJbgCdd9aho3dId5Xs4oh4YwuFQiG8R/bJZfTlXo + 99Qr02L7MmDWYLmrR3BA/93UPeorHPtjqSaYU40CgYEAtmGfWwokIglaSDVVqQVs + 3YwBqmcrla5TpkMLvLRZ2/fktqfL4Xod9iKu+Klajv9ZKTfFkXWno2HHL7FSD/Yc + hWwqnV5oDIXuDnlQOse/SeERb+IbD5iUfePpoJQgbrCQlwiB0TNGwOojR2SFMczf + Ai4aLlQLx5dSND9K9Y7HS+8CgYEAixlHQ2r4LuQjoTs0ytwi6TgqE+vn3K+qDTwc + eoods7oBWRaUn1RCKAD3UClToZ1WfMRQNtIYrOAsqdveXpOWqioAP0wE5TTOuZIo + GiWxRgIsc7TNtOmNBv+chCdbNP0emxdyjJUIGb7DFnfCw47EjHnn8Guc13uXaATN + B2ZXgoUCgYAGa13P0ggUf5BMJpBd8S08jKRyvZb1CDXcUCuGtk2yEx45ern9U5WY + zJ13E5z9MKKO8nkGBqrRfjJa8Xhxk4HKNFuzHEet5lvNE7IKCF4YQRb0ZBhnb/78 + +4ZKjFki1RrWRNSw9TdvrK6qaDKgTtCTtfRVXAYQXUgq7lSFOTtL3A== + -----END RSA PRIVATE KEY----- + DOC + end + let(:valid_cert_but_indented) do + valid_cert.gsub(%r{^}, ' ') + end + + let(:valid_key_but_indented) do + valid_key.gsub(%r{^}, ' ') + end + + let(:malformed_cert) do + truncate_middle(valid_cert) + end + + let(:malformed_key) do + truncate_middle(valid_key) + end + + let(:bad_cert) do + 'foo' + end + + let(:bad_key) do + 'bar' + end + + context 'with function signature validation' do + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params(0, 1, 2, 3).and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + end + + context 'with valid input' do + describe 'valid certificate and key' do + it { is_expected.to run.with_params(valid_cert, valid_key) } + end + end + + context 'with bad input' do + describe 'valid certificate, valid but indented key' do + it { is_expected.to run.with_params(valid_cert, valid_key_but_indented).and_raise_error(Puppet::ParseError, %r{Not a valid RSA key}) } + end + + describe 'valid certificate, malformed key' do + it { is_expected.to run.with_params(valid_cert, malformed_key).and_raise_error(Puppet::ParseError, %r{Not a valid RSA key}) } + end + + describe 'valid certificate, bad key' do + it { is_expected.to run.with_params(valid_cert, bad_key).and_raise_error(Puppet::ParseError, %r{Not a valid RSA key}) } + end + + describe 'valid but indented certificate, valid key' do + it { is_expected.to run.with_params(valid_cert_but_indented, valid_key).and_raise_error(Puppet::ParseError, %r{Not a valid x509 certificate}) } + end + + describe 'malformed certificate, valid key' do + it { is_expected.to run.with_params(malformed_cert, valid_key).and_raise_error(Puppet::ParseError, %r{Not a valid x509 certificate}) } + end + + describe 'bad certificate, valid key' do + it { is_expected.to run.with_params(bad_cert, valid_key).and_raise_error(Puppet::ParseError, %r{Not a valid x509 certificate}) } + end + + describe 'validate certificate and key; certficate not signed by key' do + it { is_expected.to run.with_params(valid_cert, another_valid_key).and_raise_error(Puppet::ParseError, %r{Certificate signature does not match supplied key}) } + end + + describe 'valid cert and key but arguments in wrong order' do + it { is_expected.to run.with_params(valid_key, valid_cert).and_raise_error(Puppet::ParseError, %r{Not a valid x509 certificate}) } + end + + describe 'non-string arguments' do + it { is_expected.to run.with_params({}, {}).and_raise_error(Puppet::ParseError, %r{is not a string}) } + it { is_expected.to run.with_params(1, 1).and_raise_error(Puppet::ParseError, %r{is not a string}) } + it { is_expected.to run.with_params(true, true).and_raise_error(Puppet::ParseError, %r{is not a string}) } + it { is_expected.to run.with_params('foo', {}).and_raise_error(Puppet::ParseError, %r{is not a string}) } + it { is_expected.to run.with_params(1, 'bar').and_raise_error(Puppet::ParseError, %r{is not a string}) } + it { is_expected.to run.with_params('baz', true).and_raise_error(Puppet::ParseError, %r{is not a string}) } + end + end + + def truncate_middle(string) + chars_to_truncate = 48 + middle = (string.length / 2).floor + start_pos = middle - (chars_to_truncate / 2) + end_pos = middle + (chars_to_truncate / 2) + + string[0..start_pos] + string[end_pos..] + end +end diff --git a/spec/functions/values_at_spec.rb b/spec/functions/values_at_spec.rb old mode 100755 new mode 100644 index a8348f395..14e15e1c5 --- a/spec/functions/values_at_spec.rb +++ b/spec/functions/values_at_spec.rb @@ -1,48 +1,58 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'values_at' do describe 'signature validation' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { - pending("Current implementation ignores parameters after the first two.") - is_expected.to run.with_params([], 0, 1).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) + pending('Current implementation ignores parameters after the first two.') + expect(subject).to run.with_params([], 0, 1).and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } - it { is_expected.to run.with_params('', 1).and_raise_error(Puppet::ParseError, /Requires array/i) } - it { is_expected.to run.with_params({}, 1).and_raise_error(Puppet::ParseError, /Requires array/i) } - it { is_expected.to run.with_params(true, 1).and_raise_error(Puppet::ParseError, /Requires array/i) } - it { is_expected.to run.with_params(1, 1).and_raise_error(Puppet::ParseError, /Requires array/i) } - it { is_expected.to run.with_params([0,1,2], 'two').and_raise_error(Puppet::ParseError, /Unknown format of given index/) } - it { is_expected.to run.with_params([0,1,2], []).and_raise_error(Puppet::ParseError, /provide at least one positive index/) } - it { is_expected.to run.with_params([0,1,2], '-1-1').and_raise_error(Puppet::ParseError, /Unknown format of given index/) } - it { is_expected.to run.with_params([0,1,2], '2-1').and_raise_error(Puppet::ParseError, /Stop index in given indices range is smaller than the start index/) } + + it { is_expected.to run.with_params('', 1).and_raise_error(Puppet::ParseError, %r{Requires array}i) } + it { is_expected.to run.with_params({}, 1).and_raise_error(Puppet::ParseError, %r{Requires array}i) } + it { is_expected.to run.with_params(true, 1).and_raise_error(Puppet::ParseError, %r{Requires array}i) } + it { is_expected.to run.with_params(1, 1).and_raise_error(Puppet::ParseError, %r{Requires array}i) } + it { is_expected.to run.with_params([0, 1, 2], 'two').and_raise_error(Puppet::ParseError, %r{Unknown format of given index}) } + it { is_expected.to run.with_params([0, 1, 2], []).and_raise_error(Puppet::ParseError, %r{provide at least one positive index}) } + it { is_expected.to run.with_params([0, 1, 2], '-1-1').and_raise_error(Puppet::ParseError, %r{Unknown format of given index}) } + it { is_expected.to run.with_params([0, 1, 2], '2-1').and_raise_error(Puppet::ParseError, %r{Stop index in given indices range is smaller than the start index}) } end context 'when requesting a single item' do - it { is_expected.to run.with_params([0, 1, 2], -1).and_raise_error(Puppet::ParseError, /Unknown format of given index/) } + it { is_expected.to run.with_params([0, 1, 2], -1).and_raise_error(Puppet::ParseError, %r{Unknown format of given index}) } it { is_expected.to run.with_params([0, 1, 2], 0).and_return([0]) } it { is_expected.to run.with_params([0, 1, 2], 1).and_return([1]) } it { is_expected.to run.with_params([0, 1, 2], [1]).and_return([1]) } it { is_expected.to run.with_params([0, 1, 2], '1').and_return([1]) } it { is_expected.to run.with_params([0, 1, 2], '1-1').and_return([1]) } it { is_expected.to run.with_params([0, 1, 2], 2).and_return([2]) } - it { is_expected.to run.with_params([0, 1, 2], 3).and_raise_error(Puppet::ParseError, /index exceeds array size/) } + it { is_expected.to run.with_params([0, 1, 2], 3).and_raise_error(Puppet::ParseError, %r{index exceeds array size}) } + end + + context 'when requesting a single item using UTF8 and double byte characters' do + it { is_expected.to run.with_params(['įŗ©', 'β', 'с', 'ď'], 0).and_return(['įŗ©']) } + it { is_expected.to run.with_params(['ꖇ', '字', '恮', '値'], 2).and_return(['恮']) } end context 'when requesting multiple items' do - it { is_expected.to run.with_params([0, 1, 2], [1, -1]).and_raise_error(Puppet::ParseError, /Unknown format of given index/) } + it { is_expected.to run.with_params([0, 1, 2], [1, -1]).and_raise_error(Puppet::ParseError, %r{Unknown format of given index}) } it { is_expected.to run.with_params([0, 1, 2], [0, 2]).and_return([0, 2]) } it { is_expected.to run.with_params([0, 1, 2], ['0-2', 1, 2]).and_return([0, 1, 2, 1, 2]) } - it { is_expected.to run.with_params([0, 1, 2], [3, 2]).and_raise_error(Puppet::ParseError, /index exceeds array size/) } + it { is_expected.to run.with_params([0, 1, 2], [3, 2]).and_raise_error(Puppet::ParseError, %r{index exceeds array size}) } describe 'different range syntaxes' do it { is_expected.to run.with_params([0, 1, 2], '0-2').and_return([0, 1, 2]) } it { is_expected.to run.with_params([0, 1, 2], '0..2').and_return([0, 1, 2]) } it { is_expected.to run.with_params([0, 1, 2], '0...2').and_return([0, 1]) } + it { pending('fix this bounds check') - is_expected.to run.with_params([0, 1, 2], '0...3').and_return([0, 1, 2]) + expect(subject).to run.with_params([0, 1, 2], '0...3').and_return([0, 1, 2]) } end end diff --git a/spec/functions/values_spec.rb b/spec/functions/values_spec.rb deleted file mode 100755 index 4abf0bd74..000000000 --- a/spec/functions/values_spec.rb +++ /dev/null @@ -1,19 +0,0 @@ -require 'spec_helper' - -describe 'values' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { - pending("Current implementation ignores parameters after the first.") - is_expected.to run.with_params({}, 'extra').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) - } - it { is_expected.to run.with_params('').and_raise_error(Puppet::ParseError, /Requires hash to work with/) } - it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /Requires hash to work with/) } - it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError, /Requires hash to work with/) } - it { is_expected.to run.with_params({}).and_return([]) } - it { is_expected.to run.with_params({ 'key' => 'value' }).and_return(['value']) } - it 'should return the array of values' do - result = subject.call([{ 'key1' => 'value1', 'key2' => 'value2', 'duplicate_value_key' => 'value2' }]) - expect(result).to match_array(['value1', 'value2', 'value2']) - end -end diff --git a/spec/functions/xml_encode_spec.rb b/spec/functions/xml_encode_spec.rb new file mode 100644 index 000000000..18a20a0c0 --- /dev/null +++ b/spec/functions/xml_encode_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'stdlib::xml_encode' do + let(:string) { 'this is "my" complicated ' } + + it 'exists' do + expect(subject).not_to be_nil + end + + describe 'for XML text' do + let(:expected_result) { 'this is "my" complicated <String>' } + + context 'with `type` parameter not explicity set' do + it { is_expected.to run.with_params(string).and_return(expected_result) } + end + + context 'with `type` parameter set to `text`' do + it { is_expected.to run.with_params(string, 'text').and_return(expected_result) } + end + end + + describe 'for XML attributes' do + it { is_expected.to run.with_params(string, 'attr').and_return('"this is "my" complicated <String>"') } + end +end diff --git a/spec/functions/zip_spec.rb b/spec/functions/zip_spec.rb old mode 100755 new mode 100644 index abca7ee86..f3e576435 --- a/spec/functions/zip_spec.rb +++ b/spec/functions/zip_spec.rb @@ -1,15 +1,27 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'zip' do - it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.not_to be_nil } + it { is_expected.to run.with_params.and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { - pending("Current implementation ignores parameters after the third.") - is_expected.to run.with_params([], [], true, []).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) + pending('Current implementation ignores parameters after the third.') + expect(subject).to run.with_params([], [], true, []).and_raise_error(Puppet::ParseError, %r{wrong number of arguments}i) } + it { is_expected.to run.with_params([], []).and_return([]) } - it { is_expected.to run.with_params([1,2,3], [4,5,6]).and_return([[1,4], [2,5], [3,6]]) } - it { is_expected.to run.with_params([1,2,3], [4,5,6], false).and_return([[1,4], [2,5], [3,6]]) } - it { is_expected.to run.with_params([1,2,3], [4,5,6], true).and_return([1, 4, 2, 5, 3, 6]) } + it { is_expected.to run.with_params([1, 2, 3], [4, 5, 6]).and_return([[1, 4], [2, 5], [3, 6]]) } + it { is_expected.to run.with_params([1, 2, 3], [4, 5, 6], false).and_return([[1, 4], [2, 5], [3, 6]]) } + it { is_expected.to run.with_params([1, 2, 3], [4, 5, 6], true).and_return([1, 4, 2, 5, 3, 6]) } + it { is_expected.to run.with_params([1, 2, 'four'], [true, true, false]).and_return([[1, true], [2, true], ['four', false]]) } + it { is_expected.to run.with_params([1, 2, 3], [4, 5]).and_return([[1, 4], [2, 5], [3, nil]]) } + it { is_expected.to run.with_params('A string', [4, 5]).and_raise_error(Puppet::ParseError, %r{Requires array}i) } + + context 'with UTF8 and double byte characters' do + it { is_expected.to run.with_params(['įŗ§', 'ь', 'ć'], ['đ', 'ề', 'ʒ']).and_return([['įŗ§', 'đ'], ['ь', 'ề'], ['ć', 'ʒ']]) } + it { is_expected.to run.with_params(['ペ', '含', '値'], ['惃', 'ꖇ', '悤']).and_return([['ペ', '惃'], ['含', 'ꖇ'], ['値', '悤']]) } + end end diff --git a/spec/monkey_patches/alias_should_to_must.rb b/spec/monkey_patches/alias_should_to_must.rb old mode 100755 new mode 100644 index 505e24092..beb36bff1 --- a/spec/monkey_patches/alias_should_to_must.rb +++ b/spec/monkey_patches/alias_should_to_must.rb @@ -1,9 +1,10 @@ -#! /usr/bin/env ruby -S rspec -require 'rspec' +# frozen_string_literal: true +require 'rspec' +# class Object class Object # This is necessary because the RAL has a 'should' # method. - alias :must :should - alias :must_not :should_not + alias must should + alias must_not should_not end diff --git a/spec/monkey_patches/publicize_methods.rb b/spec/monkey_patches/publicize_methods.rb old mode 100755 new mode 100644 index 3ae59f978..91eca2f60 --- a/spec/monkey_patches/publicize_methods.rb +++ b/spec/monkey_patches/publicize_methods.rb @@ -1,11 +1,12 @@ -#! /usr/bin/env ruby -S rspec +# frozen_string_literal: true + # Some monkey-patching to allow us to test private methods. class Class - def publicize_methods(*methods) - saved_private_instance_methods = methods.empty? ? self.private_instance_methods : methods + def publicize_methods(*methods) + saved_private_instance_methods = methods.empty? ? private_instance_methods : methods - self.class_eval { public(*saved_private_instance_methods) } - yield - self.class_eval { private(*saved_private_instance_methods) } - end + class_eval { public(*saved_private_instance_methods) } + yield + class_eval { private(*saved_private_instance_methods) } + end end diff --git a/spec/puppetlabs_spec_helper_clone.rb b/spec/puppetlabs_spec_helper_clone.rb deleted file mode 100644 index 6a94a3b47..000000000 --- a/spec/puppetlabs_spec_helper_clone.rb +++ /dev/null @@ -1,34 +0,0 @@ -#This file pulls in only the minimum necessary to let unmigrated specs still work - -# Define the main module namespace for use by the helper modules -module PuppetlabsSpec - # FIXTURE_DIR represents the standard locations of all fixture data. Normally - # this represents /spec/fixtures. This will be used by the fixtures - # library to find relative fixture data. - FIXTURE_DIR = File.join("spec", "fixtures") unless defined?(FIXTURE_DIR) -end - -# Require all necessary helper libraries so they can be used later -require 'puppetlabs_spec_helper/puppetlabs_spec/files' -require 'puppetlabs_spec_helper/puppetlabs_spec/fixtures' -#require 'puppetlabs_spec_helper/puppetlabs_spec/puppet_internals' -require 'puppetlabs_spec_helper/puppetlabs_spec/matchers' - -RSpec.configure do |config| - # Include PuppetlabsSpec helpers so they can be called at convenience - config.extend PuppetlabsSpec::Files - config.extend PuppetlabsSpec::Fixtures - config.include PuppetlabsSpec::Fixtures - - config.parser = 'future' if ENV['FUTURE_PARSER'] == 'yes' - config.strict_variables = true if ENV['STRICT_VARIABLES'] == 'yes' - config.stringify_facts = false if ENV['STRINGIFY_FACTS'] == 'no' - config.trusted_node_data = true if ENV['TRUSTED_NODE_DATA'] == 'yes' - config.ordering = ENV['ORDERING'] if ENV['ORDERING'] - - # This will cleanup any files that were created with tmpdir or tmpfile - config.after :each do - PuppetlabsSpec::Files.cleanup - end -end - diff --git a/spec/spec.opts b/spec/spec.opts deleted file mode 100644 index 91cd6427e..000000000 --- a/spec/spec.opts +++ /dev/null @@ -1,6 +0,0 @@ ---format -s ---colour ---loadby -mtime ---backtrace diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb old mode 100755 new mode 100644 index 416036b5a..ae7c1f681 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,49 +1,75 @@ -#! /usr/bin/env ruby -S rspec -dir = File.expand_path(File.dirname(__FILE__)) -$LOAD_PATH.unshift File.join(dir, 'lib') +# frozen_string_literal: true -# So everyone else doesn't have to include this base constant. -module PuppetSpec - FIXTURE_DIR = File.join(dir = File.expand_path(File.dirname(__FILE__)), "fixtures") unless defined?(FIXTURE_DIR) +RSpec.configure do |c| + c.mock_with :rspec end -require 'puppet' -require 'rspec-puppet' require 'puppetlabs_spec_helper/module_spec_helper' -require 'monkey_patches/alias_should_to_must' -require 'mocha/api' -#require 'puppetlabs_spec_helper/module_spec_helper' -require 'puppetlabs_spec_helper_clone' - -# hack to enable all the expect syntax (like allow_any_instance_of) in rspec-puppet examples -RSpec::Mocks::Syntax.enable_expect(RSpec::Puppet::ManifestMatchers) - -RSpec.configure do |config| - config.module_path = File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'modules') - config.manifest_dir = File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'manifests') - config.environmentpath = spec_path = File.expand_path(File.join(Dir.pwd, 'spec')) - - config.add_setting :puppet_future - #config.puppet_future = (ENV['FUTURE_PARSER'] == 'yes' or Puppet.version.to_f >= 4.0) - config.puppet_future = Puppet.version.to_f >= 4.0 - - config.before :each do - # Ensure that we don't accidentally cache facts and environment between - # test cases. This requires each example group to explicitly load the - # facts being exercised with something like - # Facter.collection.loader.load(:ipaddress) - Facter.clear - Facter.clear_messages - - RSpec::Mocks.setup +require 'rspec-puppet-facts' + +require 'spec_helper_local' if File.file?(File.join(File.dirname(__FILE__), 'spec_helper_local.rb')) + +include RspecPuppetFacts + +default_facts = { + puppetversion: Puppet.version, + facterversion: Facter.version, +} + +default_fact_files = [ + File.expand_path(File.join(File.dirname(__FILE__), 'default_facts.yml')), + File.expand_path(File.join(File.dirname(__FILE__), 'default_module_facts.yml')), +] + +default_fact_files.each do |f| + next unless File.exist?(f) && File.readable?(f) && File.size?(f) + + begin + require 'deep_merge' + default_facts.deep_merge!(YAML.safe_load(File.read(f), permitted_classes: [], permitted_symbols: [], aliases: true)) + rescue StandardError => e + RSpec.configuration.reporter.message "WARNING: Unable to load #{f}: #{e}" end +end - config.after :each do - RSpec::Mocks.verify - RSpec::Mocks.teardown +# read default_facts and merge them over what is provided by facterdb +default_facts.each do |fact, value| + add_custom_fact fact, value, merge_facts: true +end + +RSpec.configure do |c| + c.default_facts = default_facts + c.before :each do + # set to strictest setting for testing + # by default Puppet runs at warning level + Puppet.settings[:strict] = :warning + Puppet.settings[:strict_variables] = true + end + c.filter_run_excluding(bolt: true) unless ENV['GEM_BOLT'] + c.after(:suite) do + RSpec::Puppet::Coverage.report!(0) + end + + # Filter backtrace noise + backtrace_exclusion_patterns = [ + %r{spec_helper}, + %r{gems}, + ] + + if c.respond_to?(:backtrace_exclusion_patterns) + c.backtrace_exclusion_patterns = backtrace_exclusion_patterns + elsif c.respond_to?(:backtrace_clean_patterns) + c.backtrace_clean_patterns = backtrace_exclusion_patterns end end -# Helper class to test handling of arguments which are derived from string -class AlsoString < String +# Ensures that a module is defined +# @param module_name Name of the module +def ensure_module_defined(module_name) + module_name.split('::').reduce(Object) do |last_module, next_module| + last_module.const_set(next_module, Module.new) unless last_module.const_defined?(next_module, false) + last_module.const_get(next_module, false) + end end + +# 'spec_overrides' from sync.yml will appear below this line diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb old mode 100755 new mode 100644 index eda0d1a14..4ac8d7e0f --- a/spec/spec_helper_acceptance.rb +++ b/spec/spec_helper_acceptance.rb @@ -1,70 +1,6 @@ -#! /usr/bin/env ruby -S rspec -require 'beaker-rspec' -require 'beaker/puppet_install_helper' +# frozen_string_literal: true -UNSUPPORTED_PLATFORMS = [] +require 'puppet_litmus' +require 'spec_helper_acceptance_local' if File.file?(File.join(File.dirname(__FILE__), 'spec_helper_acceptance_local.rb')) -run_puppet_install_helper - -RSpec.configure do |c| - # Project root - proj_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) - - # Readable test descriptions - c.formatter = :documentation - - # Configure all nodes in nodeset - c.before :suite do - if ENV['FUTURE_PARSER'] == 'yes' - default[:default_apply_opts] ||= {} - default[:default_apply_opts].merge!({:parser => 'future'}) - end - - copy_root_module_to(default, :source => proj_root, :module_name => 'stdlib') - end -end - -def is_future_parser_enabled? - if default[:type] == 'aio' - return true - elsif default[:default_apply_opts] - return default[:default_apply_opts][:parser] == 'future' - end - return false -end - -def get_puppet_version - (on default, puppet('--version')).output.chomp -end - -RSpec.shared_context "with faked facts" do - let(:facts_d) do - puppet_version = get_puppet_version - if fact('osfamily') =~ /windows/i - if fact('kernelmajversion').to_f < 6.0 - 'C:/Documents and Settings/All Users/Application Data/PuppetLabs/facter/facts.d' - else - 'C:/ProgramData/PuppetLabs/facter/facts.d' - end - elsif Puppet::Util::Package.versioncmp(puppet_version, '4.0.0') < 0 and fact('is_pe', '--puppet') == "true" - '/etc/puppetlabs/facter/facts.d' - else - '/etc/facter/facts.d' - end - end - - before :each do - #No need to create on windows, PE creates by default - if fact('osfamily') !~ /windows/i - shell("mkdir -p '#{facts_d}'") - end - end - - after :each do - shell("rm -f '#{facts_d}/fqdn.txt'", :acceptable_exit_codes => [0,1]) - end - - def fake_fact(name, value) - shell("echo #{name}=#{value} > '#{facts_d}/#{name}.txt'") - end -end +PuppetLitmus.configure! diff --git a/spec/spec_helper_local.rb b/spec/spec_helper_local.rb new file mode 100644 index 000000000..877294391 --- /dev/null +++ b/spec/spec_helper_local.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +# automatically load any shared examples or contexts +Dir['./spec/support/**/*.rb'].sort.each { |f| require f } + +# HACK: to enable all the expect syntax (like allow_any_instance_of) in rspec-puppet examples +RSpec::Mocks::Syntax.enable_expect(RSpec::Puppet::ManifestMatchers) + +RSpec.configure do |config| + # supply tests with a possibility to test for the future parser + config.add_setting :puppet_future + config.puppet_future = Puppet.version.to_f >= 4.0 + + config.before :each do + # Ensure that we don't accidentally cache facts and environment between + # test cases. This requires each example group to explicitly load the + # facts being exercised with something like + # Facter.collection.loader.load(:ipaddress) + Facter.clear + Facter.clear_messages + + RSpec::Mocks.setup + end + + config.after :each do + RSpec::Mocks.verify + RSpec::Mocks.teardown + end +end + +# Helper class to test handling of arguments which are derived from string +class AlsoString < String +end diff --git a/spec/support/shared_data.rb b/spec/support/shared_data.rb new file mode 100644 index 000000000..e19f82488 --- /dev/null +++ b/spec/support/shared_data.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +module SharedData + IPV4_PATTERNS = [ + '0.0.0.0', + '1.2.3.4', + '10.10.10.10', + '127.0.0.1', + '192.88.99.0', + '194.232.104.150', + '224.0.0.0', + '244.24.24.24', + '255.255.255.255', + '8.8.8.8', + '8.8.8.8/0', + '8.8.8.8/16', + '8.8.8.8/255.255.0.0', + '8.8.8.8/32', + ].freeze + IPV4_NEGATIVE_PATTERNS = [ + '', + '0000', + '0.0.0.0.', + '0.0.0.0./0.0.0.0.', + '0.0.0.0./1', + '0.0.0.0.0', + '0.0.0.0/0.0.0.0.', + '0.0.0.256', + '0.0.0', + '1.2.3.4.5', + '1.2.3', + '10.010.10.10', + '2001:0db8:85a3:0000:0000:8a2e:0370:73342001:0db8:85a3:0000:0000:8a2e:0370:7334', + '4.4.4', + '77', + '9999.9999.9999.9999', + 'affe::beef', + 'nope', + ].freeze +end diff --git a/spec/type_aliases/base32_spec.rb b/spec/type_aliases/base32_spec.rb new file mode 100644 index 000000000..b882058b0 --- /dev/null +++ b/spec/type_aliases/base32_spec.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::Base32' do + describe 'valid handling' do + ['ASDASDDASD3453453', 'ASDASDDASD3453453=', 'ASDASDDASD3453453==', 'ASDASDDASD3453453===', 'ASDASDDASD3453453====', 'ASDASDDASD3453453=====', 'ASDASDDASD3453453======', 'asdasddasd3453453', + 'asdasddasd3453453=', 'asdasddasd3453453==', 'asdasddasd3453453===', 'asdasddasd3453453====', 'asdasddasd3453453=====', 'asdasddasd3453453======'].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'invalid path handling' do + context 'garbage inputs' do + [ + [nil], + [nil, nil], + { 'foo' => 'bar' }, + {}, + "\nASDASDDASD3453453", + "\nASDASDDASD3453453\n", + "ASDASDDASD3453453\n", + '', + 'asdasd!@#$', + '=asdasd9879876876+/', + 'asda=sd9879876876+/', + 'asdaxsd9879876876+/===', + 'asdads asdasd', + 'asdasddasd3453453=======', + 'asdaSddasd', + 'asdasddasd1', + 'asdasddasd9', + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end + end +end diff --git a/spec/type_aliases/base64_spec.rb b/spec/type_aliases/base64_spec.rb new file mode 100644 index 000000000..0f3d2e3dc --- /dev/null +++ b/spec/type_aliases/base64_spec.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::Base64' do + describe 'valid handling' do + ['asdasdASDSADA342386832/746+=', 'asdasdASDSADA34238683274/6+', 'asdasdASDSADA3423868327/46+=='].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'invalid path handling' do + context 'garbage inputs' do + [ + [nil], + [nil, nil], + { 'foo' => 'bar' }, + {}, + '', + "\nasdasdASDSADA342386832/746+=", + "\nasdasdASDSADA342386832/746+=\n", + "asdasdASDSADA342386832/746+=\n", + 'asdasd!@#$', + '=asdasd9879876876+/', + 'asda=sd9879876876+/', + 'asdaxsd9879876876+/===', + 'asdads asdasd', + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end + end +end diff --git a/spec/type_aliases/createresources_spec.rb b/spec/type_aliases/createresources_spec.rb new file mode 100644 index 000000000..fac70bb77 --- /dev/null +++ b/spec/type_aliases/createresources_spec.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::CreateResources' do + it { is_expected.to allow_value({ 'name' => { 'ensure' => 'present', 'key' => 1 } }) } +end diff --git a/spec/type_aliases/datasize_spec.rb b/spec/type_aliases/datasize_spec.rb new file mode 100644 index 000000000..0f469cc2b --- /dev/null +++ b/spec/type_aliases/datasize_spec.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::Datasize' do + describe 'valid handling' do + ['42b', '42B', '42k', '42K', '42m', '42M', '42g', '42G', '42t', '42T', + '42kb', '42Kb', '42mb', '42Mb', '42gb', '42Gb', '42Tb', '42Tb', + '42kB', '42KB', '42mB', '42MB', '42gB', '42GB', '42TB', '42TB'].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'invalid path handling' do + context 'garbage inputs' do + [ + [nil], + [nil, nil], + { 'foo' => 'bar' }, + {}, + 1024, + '1024', + '1024byte', + '1024bit', + '1024Gig', + '1024Meg', + '1024BM', + '1024bg', + '1024Meb', + 'asdaSddasd', + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end + end +end diff --git a/spec/type_aliases/dns_zone_spec.rb b/spec/type_aliases/dns_zone_spec.rb new file mode 100644 index 000000000..b546a3666 --- /dev/null +++ b/spec/type_aliases/dns_zone_spec.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::Dns::Zone' do + describe 'accepts dns zones' do + [ + '.', + 'com.', + 'example.com.', + '10.10.10.10.10.', + 'xn--5ea.pf.', + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'rejects other values' do + [ + true, + false, + '', + 'iAmAString', + {}, + { 'key' => 'value' }, + { 1 => 2 }, + :undef, + 3, + 'www..com.', + '127.0.0.1', + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end +end diff --git a/spec/type_aliases/email_spec.rb b/spec/type_aliases/email_spec.rb new file mode 100644 index 000000000..307de118a --- /dev/null +++ b/spec/type_aliases/email_spec.rb @@ -0,0 +1,73 @@ +# frozen_string_literal: true + +require 'spec_helper' + +# Test cases are a combination of the test cases used in MediaWiki[1] and a +# Reference found on line[2]. Some of the test cases in the later list have +# been dropped as the regex used in the HTML5 specification[3] (and in this type) +# allows for wilful violation of the RFC's +# +# [1]https://github.com/wikimedia/mediawiki/blob/master/tests/phpunit/integration \ +# /includes/SanitizerValidateEmailTest.php +# [2]https://gist.github.com/cjaoude/fd9910626629b53c4d25 +# [3]https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address + +describe 'Stdlib::Email' do + describe 'valid handling' do + ['email@example.com', + 'EMAIL@example.com', + 'email@EXAMPLE.com', + 'email@192.0.2.1', + '_______@example.com', + 'firstname.lastname@example.com', + 'firstname+lastname@example.com', + 'firstname-lastname@example.com', + '1234567890@example.com', + 'email@subdomain.example.com', + 'email@example-one.com', + 'email@example.name', + 'email@example.museum', + 'email@example.co.jp', + 'email@example', + 'user@example.1234', + 'user@a'].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'invalid handling' do + ['plainaddress', + '#@%^%#$@#$@#.com', + '@example.com', + ' email@example.com', + 'email@example.com ', + "email@example.com\t", + 'user email@example.com', + 'useremail@example com', + 'user,email@example.com', + 'useremail@example,com', + 'useremail@.', + 'useremail@.example.org', + 'useremail@a......', + 'userĆ example.com', + 'Joe Smith ', + 'email.example.com', + 'email@example@example.com', + '恂恄恆恈恊@example.com', + 'email@example.com (Joe Smith)', + 'email@-example.com', + 'email@example..com', + 'random stuff multiline + valid@email.com + more random stuff $^*!', + 'ā€(),:;<>[\]@example.com', + 'justā€notā€right@example.com', + 'this\ is"really"not\allowed@example.com'].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end +end diff --git a/spec/type_aliases/ensure_package_spec.rb b/spec/type_aliases/ensure_package_spec.rb new file mode 100644 index 000000000..0eccb106a --- /dev/null +++ b/spec/type_aliases/ensure_package_spec.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::Ensure::Package' do + describe 'valid handling' do + [ + 'present', + 'absent', + 'purged', + 'disabled', + 'installed', + 'latest', + '1', + '1.1', + '>=6.0', + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'No complex types can match' do + context 'Garbage inputs, no complex or non string types can match' do + [ + 1, + 1.1, + [1.1], + '', + { 'foo' => 'bar' }, + {}, + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end + end +end diff --git a/spec/type_aliases/filemode_spec.rb b/spec/type_aliases/filemode_spec.rb new file mode 100644 index 000000000..8e96c3c6f --- /dev/null +++ b/spec/type_aliases/filemode_spec.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::Filemode' do + describe 'valid modes' do + [ + '7', + '12', + '666', + + '0000', + '0644', + '1644', + '2644', + '4644', + '0123', + '0777', + + 'a=,o-r,u+X,g=w', + 'a=Xr,+0', + 'u=rwx,g+rX', + 'u+s,g-s', + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'invalid modes' do + context 'with garbage inputs' do + [ + true, + false, + :keyword, + nil, + [nil], + [nil, nil], + { 'foo' => 'bar' }, + {}, + '', + "\n0644", + "\n0644\n", + "0644\n", + '惍惃惈', + '55555', + '0x123', + '0649', + + '=8,X', + 'x=r,a=wx', + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end + end +end diff --git a/spec/type_aliases/filesource_spec.rb b/spec/type_aliases/filesource_spec.rb new file mode 100644 index 000000000..38e533ca8 --- /dev/null +++ b/spec/type_aliases/filesource_spec.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::Filesource' do + describe 'valid handling' do + [ + 'https://hello.com', + 'https://notcreative.org', + 'https://canstillaccepthttps.co.uk', + 'http://anhttp.com', + 'http://runningoutofideas.gov', + 'file:///hello/bla', + 'file:///foo/bar.log', + 'puppet:///modules/foo/bar.log', + 'puppet://pm.example.com/modules/foo/bar.log', + 'puppet://192.0.2.1/modules/foo/bar.log', + '/usr2/username/bin:/usr/local/bin:/usr/bin:.', + 'C:/', + 'C:\\', + 'C:\\WINDOWS\\System32', + 'C:/windows/system32', + 'X:/foo/bar', + 'X:\\foo\\bar', + '\\\\host\\windows', + '//host/windows', + '/var/tmp', + '/var/opt/../lib/puppet', + 'puppet:///a_custom_mount_point/foo/bar/foobar.conf', + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'invalid path handling' do + context 'garbage inputs' do + [ + nil, + [nil], + [nil, nil], + { 'foo' => 'bar' }, + {}, + '', + "\nfile:///foo/bar.log", + "\nfile:///foo/bar.log\n", + "file:///foo/bar.log\n", + "\npuppet:///modules/foo/bar.log", + "\npuppet:///modules/foo/bar.log\n", + "puppet:///modules/foo/bar.log\n", + '*/Users//nope', + '\\Users/hc/wksp/stdlib', + 'C:noslashes', + '\\var\\tmp', + 'puppet://bob@pm.example.com/modules/foo/bar.log', + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end + end +end diff --git a/spec/type_aliases/fqdn_spec.rb b/spec/type_aliases/fqdn_spec.rb new file mode 100644 index 000000000..f7d526ee7 --- /dev/null +++ b/spec/type_aliases/fqdn_spec.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::Fqdn' do + describe 'valid handling' do + [ + 'example', + 'example.com', + 'www.example.com', + '10.10.10.10.10', + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'invalid path handling' do + context 'garbage inputs' do + [ + [nil], + [nil, nil], + { 'foo' => 'bar' }, + {}, + '', + "\nexample", + "\nexample\n", + "example\n", + '2001:DB8::1', + 'www www.example.com', + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end + end +end diff --git a/spec/type_aliases/host_spec.rb b/spec/type_aliases/host_spec.rb new file mode 100644 index 000000000..6cfd3d94b --- /dev/null +++ b/spec/type_aliases/host_spec.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::Host' do + describe 'valid handling' do + [ + 'example', + 'example.com', + 'www.example.com', + '2001:0db8:85a3:0000:0000:8a2e:0370:7334', + 'fa76:8765:34ac:0823:ab76:eee9:0987:1111', + '2001:0db8::1', + '224.0.0.0', + '255.255.255.255', + '0.0.0.0', + '192.88.99.0', + '10.10.10.10.10', + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'invalid handling' do + context 'garbage inputs' do + [ + [nil], + [nil, nil], + { 'foo' => 'bar' }, + {}, + '', + 'www www.example.com', + 'bob@example.com', + '%.example.com', + '2001:0d8', + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end + end +end diff --git a/spec/type_aliases/http__method_spec.rb b/spec/type_aliases/http__method_spec.rb new file mode 100644 index 000000000..838660f01 --- /dev/null +++ b/spec/type_aliases/http__method_spec.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::Http::Method' do + describe 'valid HTTP Methods' do + [ + 'HEAD', + 'GET', + 'PUT', + 'DELETE', + 'TRACE', + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'invalid path handling' do + context 'garbage inputs' do + [ + nil, + [nil], + [nil, nil], + { 'foo' => 'bar' }, + {}, + '', + 'https', + '199', + 600, + 1_000, + 'Ok', + 'get', + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end + end +end diff --git a/spec/type_aliases/http__status_spec.rb b/spec/type_aliases/http__status_spec.rb new file mode 100644 index 000000000..384b284c4 --- /dev/null +++ b/spec/type_aliases/http__status_spec.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::Http::Status' do + describe 'valid HTTP Status' do + [ + 200, + 302, + 404, + 418, + 503, + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'invalid path handling' do + context 'garbage inputs' do + [ + nil, + [nil], + [nil, nil], + { 'foo' => 'bar' }, + {}, + '', + 'https', + '199', + 600, + 1_000, + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end + end +end diff --git a/spec/type_aliases/httpstatus_spec.rb b/spec/type_aliases/httpstatus_spec.rb new file mode 100644 index 000000000..2f5d53a2c --- /dev/null +++ b/spec/type_aliases/httpstatus_spec.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::HttpStatus' do + describe 'valid HTTP Status' do + [ + 200, + 302, + 404, + 418, + 503, + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'invalid path handling' do + context 'garbage inputs' do + [ + nil, + [nil], + [nil, nil], + { 'foo' => 'bar' }, + {}, + '', + 'https', + '199', + 600, + 1_000, + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end + end +end diff --git a/spec/type_aliases/httpsurl_spec.rb b/spec/type_aliases/httpsurl_spec.rb new file mode 100644 index 000000000..e1ac0278a --- /dev/null +++ b/spec/type_aliases/httpsurl_spec.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::HTTPSUrl' do + describe 'valid handling' do + ['https://hello.com', 'https://notcreative.org', 'https://notexciting.co.uk', 'https://graphemica.com/ā¤', 'https://graphemica.com/ē·©', 'HTTPS://FOO.com'].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'invalid path handling' do + context 'with garbage inputs' do + [ + nil, + [nil], + [nil, nil], + { 'foo' => 'bar' }, + {}, + '', + "\nhttps://hello.com", + "\nhttps://hello.com\n", + "https://hello.com\n", + 'httds://notquiteright.org', + 'hptts:/nah', + 'https;//notrightbutclose.org', + 'http://graphemica.com/ā¤', + 'http://graphemica.com/ē·©', + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end + end +end diff --git a/spec/type_aliases/httpurl_spec.rb b/spec/type_aliases/httpurl_spec.rb new file mode 100644 index 000000000..97c18a961 --- /dev/null +++ b/spec/type_aliases/httpurl_spec.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::HTTPUrl' do + describe 'valid handling' do + ['https://hello.com', 'https://notcreative.org', 'https://canstillaccepthttps.co.uk', 'http://anhttp.com', 'http://runningoutofideas.gov', + 'http://', 'http://graphemica.com/ā¤', 'http://graphemica.com/ē·©', 'HTTPS://FOO.COM', 'HTTP://BAR.COM'].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'invalid path handling' do + context 'with garbage inputs' do + [ + nil, + [nil], + [nil, nil], + { 'foo' => 'bar' }, + {}, + '', + "\nhttp://hello.com", + "\nhttp://hello.com\n", + "http://hello.com\n", + 'httds://notquiteright.org', + 'hptts:/nah', + 'https;//notrightbutclose.org', + 'hts://graphemica.com/ā¤', + 'https:graphemica.com/ē·©', + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end + end +end diff --git a/spec/type_aliases/ip_address_nosubnet_spec.rb b/spec/type_aliases/ip_address_nosubnet_spec.rb new file mode 100644 index 000000000..a87e14996 --- /dev/null +++ b/spec/type_aliases/ip_address_nosubnet_spec.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::IP::Address::Nosubnet' do + describe 'accepts ipv4 and ipv6 addresses without subnets' do + [ + '224.0.0.0', + '255.255.255.255', + '0.0.0.0', + '192.88.99.0', + '2001:0db8:85a3:0000:0000:8a2e:0370:7334', + 'fa76:8765:34ac:0823:ab76:eee9:0987:1111', + '127.0.0.1', + '8.8.4.4', + '52.10.10.141', + 'FEDC:BA98:7654:3210:FEDC:BA98:7654:3210', + 'FF01:0:0:0:0:0:0:101', + 'FF01::101', + '::', + '12AB::CD30:192.168.0.1', + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'rejects other values' do + [ + '10.1.240.4/24', + 'FF01:0:0:0:0:0:0:101/32', + 'FF01::101/60', + 'nope', + '77', + '4.4.4', + '2001:0db8:85a3:000000:0000:8a2e:0370:7334', + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end +end diff --git a/spec/type_aliases/ip_address_spec.rb b/spec/type_aliases/ip_address_spec.rb new file mode 100644 index 000000000..08d9917b5 --- /dev/null +++ b/spec/type_aliases/ip_address_spec.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::IP::Address' do + describe 'accepts ipv4 and ipv6 addresses' do + [ + '224.0.0.0', + '255.255.255.255', + '0.0.0.0', + '192.88.99.0', + '2001:0db8:85a3:0000:0000:8a2e:0370:7334', + 'fa76:8765:34ac:0823:ab76:eee9:0987:1111', + '127.0.0.1', + '8.8.4.4', + '10.1.240.4/24', + '52.10.10.141', + 'FEDC:BA98:7654:3210:FEDC:BA98:7654:3210', + 'FF01:0:0:0:0:0:0:101', + 'FF01::101', + 'FF01:0:0:0:0:0:0:101/32', + 'FF01::101/60', + '::', + '12AB::CD30:192.168.0.1', + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'rejects other values' do + [ + 'nope', + '77', + '4.4.4', + '2001:0db8:85a3:000000:0000:8a2e:0370:7334', + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end +end diff --git a/spec/type_aliases/ip_address_v4_nosubnet_spec.rb b/spec/type_aliases/ip_address_v4_nosubnet_spec.rb new file mode 100644 index 000000000..f4e750373 --- /dev/null +++ b/spec/type_aliases/ip_address_v4_nosubnet_spec.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::IP::Address::V4::Nosubnet' do + describe 'accepts ipv4 addresses without subnets' do + [ + '127.0.0.1', + '8.8.4.4', + '52.10.10.141', + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'rejects other values' do + [ + '10.1.240.4/24', + '192.168.1', + 'FEDC:BA98:7654:3210:FEDC:BA98:7654:3210', + '12AB::CD30:192.168.0.1', + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end +end diff --git a/spec/type_aliases/ip_address_v4_spec.rb b/spec/type_aliases/ip_address_v4_spec.rb new file mode 100644 index 000000000..8036f0cab --- /dev/null +++ b/spec/type_aliases/ip_address_v4_spec.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::IP::Address::V4' do + describe 'accepts ipv4 addresses' do + [ + '127.0.0.1', + '8.8.4.4', + '10.1.240.4/24', + '52.10.10.141', + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'rejects other values' do + [ + '192.168.1', + 'FEDC:BA98:7654:3210:FEDC:BA98:7654:3210', + '12AB::CD30:192.168.0.1', + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end +end diff --git a/spec/type_aliases/ip_address_v6_alternative_spec.rb b/spec/type_aliases/ip_address_v6_alternative_spec.rb new file mode 100644 index 000000000..74cfdb7bc --- /dev/null +++ b/spec/type_aliases/ip_address_v6_alternative_spec.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::IP::Address::V6::Alternative' do + describe 'accepts ipv6 addresses in alternative format' do + [ + '0:0:0:0:0:0:13.1.68.3', + '0:0:0:0:0:FFFF:129.144.52.38', + '0:0:0:0:0:FFFF:129.144.52.38/60', + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'rejects other values' do + [ + 'nope', + '127.0.0.1', + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end +end diff --git a/spec/type_aliases/ip_address_v6_cidr_spec.rb b/spec/type_aliases/ip_address_v6_cidr_spec.rb new file mode 100644 index 000000000..246fe54b1 --- /dev/null +++ b/spec/type_aliases/ip_address_v6_cidr_spec.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::IP::Address::V6::CIDR' do + describe 'accepts ipv6 addresses in cidr format' do + [ + 'FF01:0:0:0:0:0:0:101/32', + 'FF01::101/60', + '::/0', + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'rejects other values' do + [ + 'FEDC:BA98:7654:3210:FEDC:BA98:7654:3210', + 'FF01:0:0:0:0:0:0:101', + 'FF01::101', + '12AB::CD30:192.168.0.1', + '127.0.0.1', + '10.1.240.4/24', + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end +end diff --git a/spec/type_aliases/ip_address_v6_compressed_spec.rb b/spec/type_aliases/ip_address_v6_compressed_spec.rb new file mode 100644 index 000000000..1ddd9c4d5 --- /dev/null +++ b/spec/type_aliases/ip_address_v6_compressed_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::IP::Address::V6::Compressed' do + describe 'accepts ipv6 addresses in compressed format' do + [ + '1080::8:800:200C:417A', + '1080::8:800:200C:417A/60', + 'FF01::101', + '::1', + '::', + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'rejects other values' do + [ + 'nope', + '127.0.0.1', + 'FEDC::BA98:7654:3210::3210', + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end +end diff --git a/spec/type_aliases/ip_address_v6_full_spec.rb b/spec/type_aliases/ip_address_v6_full_spec.rb new file mode 100644 index 000000000..70aac9cef --- /dev/null +++ b/spec/type_aliases/ip_address_v6_full_spec.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::IP::Address::V6::Full' do + describe 'accepts ipv6 addresses in full format' do + [ + 'FEDC:BA98:7654:3210:FEDC:BA98:7654:3210', + 'FEDC:BA98:7654:3210:FEDC:BA98:7654:3210/60', + '1080:0:0:0:8:800:200C:417A', + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'rejects other values' do + [ + 'nope', + '127.0.0.1', + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end +end diff --git a/spec/type_aliases/ip_address_v6_nosubnet_alternative_spec.rb b/spec/type_aliases/ip_address_v6_nosubnet_alternative_spec.rb new file mode 100644 index 000000000..4a01b7f51 --- /dev/null +++ b/spec/type_aliases/ip_address_v6_nosubnet_alternative_spec.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::IP::Address::V6::Nosubnet::Alternative' do + describe 'accepts ipv6 addresses in alternative format without subnets' do + [ + '0:0:0:0:0:0:13.1.68.3', + '0:0:0:0:0:FFFF:129.144.52.38', + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'rejects other values' do + [ + '0:0:0:0:0:FFFF:129.144.52.38/60', + 'nope', + '127.0.0.1', + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end +end diff --git a/spec/type_aliases/ip_address_v6_nosubnet_compressed_spec.rb b/spec/type_aliases/ip_address_v6_nosubnet_compressed_spec.rb new file mode 100644 index 000000000..b6b7fa89d --- /dev/null +++ b/spec/type_aliases/ip_address_v6_nosubnet_compressed_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::IP::Address::V6::Nosubnet::Compressed' do + describe 'accepts ipv6 addresses in compressed format without subnets' do + [ + '1080::8:800:200C:417A', + 'FF01::101', + '::1', + '::', + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'rejects other values' do + [ + '1080::8:800:200C:417A/60', + 'nope', + '127.0.0.1', + 'FEDC::BA98:7654:3210::3210', + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end +end diff --git a/spec/type_aliases/ip_address_v6_nosubnet_full_spec.rb b/spec/type_aliases/ip_address_v6_nosubnet_full_spec.rb new file mode 100644 index 000000000..8272d4d21 --- /dev/null +++ b/spec/type_aliases/ip_address_v6_nosubnet_full_spec.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::IP::Address::V6::Nosubnet::Full' do + describe 'accepts ipv6 addresses in full format without subnets' do + [ + 'FEDC:BA98:7654:3210:FEDC:BA98:7654:3210', + '1080:0:0:0:8:800:200C:417A', + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'rejects other values' do + [ + 'FEDC:BA98:7654:3210:FEDC:BA98:7654:3210/60', + 'nope', + '127.0.0.1', + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end +end diff --git a/spec/type_aliases/ip_address_v6_spec.rb b/spec/type_aliases/ip_address_v6_spec.rb new file mode 100644 index 000000000..36e9ef7e5 --- /dev/null +++ b/spec/type_aliases/ip_address_v6_spec.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::IP::Address::V6' do + describe 'accepts ipv6 addresses' do + [ + 'FEDC:BA98:7654:3210:FEDC:BA98:7654:3210', + 'FF01:0:0:0:0:0:0:101', + 'FF01::101', + 'FF01:0:0:0:0:0:0:101/32', + 'FF01::101/60', + '::', + '12AB::CD30:192.168.0.1', + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'rejects other values' do + [ + '127.0.0.1', + '10.1.240.4/24', + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end +end diff --git a/spec/type_aliases/mac_spec.rb b/spec/type_aliases/mac_spec.rb new file mode 100644 index 000000000..492b07cd0 --- /dev/null +++ b/spec/type_aliases/mac_spec.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::MAC' do + describe 'valid handling' do + [ + '00:a0:1f:12:7f:a0', + '00:A0:1F:12:7F:A0', + '00-A0-1F-12-7F-A0', + '80:00:02:09:fe:80:00:00:00:00:00:00:00:24:65:ff:ff:91:a3:12', + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'invalid path handling' do + context 'with garbage inputs' do + [ + nil, + [nil], + [nil, nil], + { 'foo' => 'bar' }, + {}, + '', + 'one', + '00:00:00:00:00:0g', + "\n00:a0:1f:12:7f:a0", + "\n00:a0:1f:12:7f:a0\n", + "00:a0:1f:12:7f:a0\n", + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end + end +end diff --git a/spec/type_aliases/objectstore_gsuri_spec.rb b/spec/type_aliases/objectstore_gsuri_spec.rb new file mode 100644 index 000000000..d75812e15 --- /dev/null +++ b/spec/type_aliases/objectstore_gsuri_spec.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::ObjectStore::GSUri' do + describe 'accepts case-sensitive google cloud gs uris' do + [ + 'gs://mybucket/myfile.csv', + 'gs://bucket/path/to/file.tar.gz', + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'rejects other values' do + [ + '', + "\ngs://mybucket/myfile.csv", + "\ngs://mybucket/myfile.csv\n", + "gs://mybucket/myfile.csv\n", + 'GS://mybucket/myfile.csv', + 5, + 'gs//mybucket/myfile.csv', + 'gs:/mybucket/myfile.csv', + 'gs:mybucket/myfile.csv', + 'gs-mybucket/myfile.csv', + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end +end diff --git a/spec/type_aliases/objectstore_s3uri_spec.rb b/spec/type_aliases/objectstore_s3uri_spec.rb new file mode 100644 index 000000000..4c774ed9a --- /dev/null +++ b/spec/type_aliases/objectstore_s3uri_spec.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::ObjectStore::S3Uri' do + describe 'accepts case-sensitive amazon web services s3 uris' do + [ + 's3://bucket-name/path', + 's3://bucket/path/to/file.txt', + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'rejects other values' do + [ + '', + "\ns3://bucket-name/path", + "\ns3://bucket-name/path\n", + "s3://bucket-name/path\n", + 'S3://bucket-name/path', + 3, + 's3:/bucket-name/path', + 's3//bucket-name/path', + 's3:bucket-name/path', + 's3-bucket-name/path', + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end +end diff --git a/spec/type_aliases/objectstore_spec.rb b/spec/type_aliases/objectstore_spec.rb new file mode 100644 index 000000000..f5780e65b --- /dev/null +++ b/spec/type_aliases/objectstore_spec.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::ObjectStore' do + describe 'accepts case-sensitive google cloud gs or amazon web services s3 uris' do + [ + 's3://bucket-name/path', + 's3://bucket/path/to/file.txt', + 'gs://mybucket/myfile.csv', + 'gs://bucket/path/to/file.tar.gz', + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'rejects other values' do + [ + '', + 'S3://bucket/path', + 'GS://bucket/path', + 5, + 3, + 'gs//bucket/path/to/file', + 's3//bucket/path/to/file', + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end +end diff --git a/spec/type_aliases/port__dynamic_spec.rb b/spec/type_aliases/port__dynamic_spec.rb new file mode 100644 index 000000000..69cb0190b --- /dev/null +++ b/spec/type_aliases/port__dynamic_spec.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::Port::Ephemeral' do + describe 'valid ephemeral port' do + [ + 49_152, + 51_337, + 65_000, + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'invalid path handling' do + context 'garbage inputs' do + [ + nil, + [nil], + [nil, nil], + { 'foo' => 'bar' }, + {}, + '', + 'https', + '443', + -1, + 80, + 443, + 1023, + 1337, + 8080, + 28_080, + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end + end +end diff --git a/spec/type_aliases/port__privileged_spec.rb b/spec/type_aliases/port__privileged_spec.rb new file mode 100644 index 000000000..c09bd2bc5 --- /dev/null +++ b/spec/type_aliases/port__privileged_spec.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::Port::Privileged' do + describe 'valid ports' do + [ + 80, + 443, + 1023, + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'invalid path handling' do + context 'garbage inputs' do + [ + nil, + [nil], + [nil, nil], + { 'foo' => 'bar' }, + {}, + '', + 'https', + '443', + -1, + 1337, + 1024, + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end + end +end diff --git a/spec/type_aliases/port__unprivileged_spec.rb b/spec/type_aliases/port__unprivileged_spec.rb new file mode 100644 index 000000000..16c634639 --- /dev/null +++ b/spec/type_aliases/port__unprivileged_spec.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::Port::Unprivileged' do + describe 'valid unprivilegedport' do + [ + 1024, + 1337, + 65_000, + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'invalid path handling' do + context 'garbage inputs' do + [ + nil, + [nil], + [nil, nil], + { 'foo' => 'bar' }, + {}, + '', + 'https', + '443', + -1, + 80, + 443, + 1023, + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end + end +end diff --git a/spec/type_aliases/port__user_spec.rb b/spec/type_aliases/port__user_spec.rb new file mode 100644 index 000000000..a86ff8e47 --- /dev/null +++ b/spec/type_aliases/port__user_spec.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::Port::User' do + describe 'valid user' do + [ + 1024, + 1337, + 49_151, + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'invalid path handling' do + context 'garbage inputs' do + [ + nil, + [nil], + [nil, nil], + { 'foo' => 'bar' }, + {}, + '', + 'https', + '443', + -1, + 80, + 443, + 1023, + 49_152, + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end + end +end diff --git a/spec/type_aliases/port_spec.rb b/spec/type_aliases/port_spec.rb new file mode 100644 index 000000000..3ed3a8d1f --- /dev/null +++ b/spec/type_aliases/port_spec.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::Port' do + describe 'valid ports' do + [ + 80, + 443, + 1337, + 65_000, + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'invalid path handling' do + context 'garbage inputs' do + [ + nil, + [nil], + [nil, nil], + { 'foo' => 'bar' }, + {}, + '', + 'https', + '443', + -1, + 65_536, + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end + end +end diff --git a/spec/type_aliases/unixpath_spec.rb b/spec/type_aliases/unixpath_spec.rb new file mode 100644 index 000000000..2ec64159e --- /dev/null +++ b/spec/type_aliases/unixpath_spec.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::Unixpath' do + describe 'valid handling' do + ['/usr2/username/bin:/usr/local/bin:/usr/bin:.', '/var/tmp', '/Users/helencampbell/workspace/puppetlabs-stdlib', '/var/ůńƒ8', '/var/惍惃惈', '/var//tmp', '/var/../tmp'].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'invalid path handling' do + context 'with garbage inputs' do + [ + nil, + [nil], + [nil, nil], + { 'foo' => 'bar' }, + {}, + '', + "\n/var/tmp", + "\n/var/tmp\n", + "/var/tmp\n", + 'C:/whatever', + '\\var\\tmp', + '\\Users/hc/wksp/stdlib', + '*/Users//nope', + "var\ůńƒ8", + "var\惍惃惈", + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end + end +end diff --git a/spec/type_aliases/windowspath_spec.rb b/spec/type_aliases/windowspath_spec.rb new file mode 100644 index 000000000..f8bd1cc24 --- /dev/null +++ b/spec/type_aliases/windowspath_spec.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::Windowspath' do + describe 'valid handling' do + ['C:\\', 'C:\\WINDOWS\\System32', 'C:/windows/system32', 'X:/foo/bar', 'X:\\foo\\bar', '\\\\host\\windows', 'X:/var/ůńƒ8', 'X:/var/惍惃惈'].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'invalid path handling' do + context 'with garbage inputs' do + [ + nil, + [nil], + [nil, nil], + { 'foo' => 'bar' }, + {}, + "\nC:\\", + "\nC:\\\n", + "C:\\\n", + '', + 'httds://notquiteright.org', + '/usr2/username/bin:/usr/local/bin:/usr/bin:.', + 'C;//notright/here', + 'C:noslashes', + 'C:惍惃惈', + 'C:ůńƒ8', + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end + end +end diff --git a/spec/type_aliases/yes_no_spec.rb b/spec/type_aliases/yes_no_spec.rb new file mode 100644 index 000000000..4adbb0ff5 --- /dev/null +++ b/spec/type_aliases/yes_no_spec.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Stdlib::Yes_no' do + describe 'valid types' do + [ + 'yes', + 'no', + 'YES', + 'Yes', + 'NO', + 'No', + ].each do |value| + describe value.inspect do + it { is_expected.to allow_value(value) } + end + end + end + + describe 'invalid types' do + context 'with garbage inputs' do + [ + true, + false, + :keyword, + nil, + ['yes', 'no'], + { 'foo' => 'bar' }, + {}, + '', + '惍惃惈', + '55555', + '0x123', + 'yess', + 'nooo', + ].each do |value| + describe value.inspect do + it { is_expected.not_to allow_value(value) } + end + end + end + end +end diff --git a/spec/unit/facter/facter_dot_d_spec.rb b/spec/unit/facter/facter_dot_d_spec.rb deleted file mode 100755 index 0afadb25f..000000000 --- a/spec/unit/facter/facter_dot_d_spec.rb +++ /dev/null @@ -1,32 +0,0 @@ -#! /usr/bin/env ruby -S rspec -require 'spec_helper' -require 'facter/facter_dot_d' - -describe Facter::Util::DotD do - - context 'returns a simple fact' do - before :each do - Facter.stubs(:version).returns('1.6.1') - subject.stubs(:entries).returns(['/etc/facter/facts.d/fake_fact.txt']) - File.stubs(:readlines).with('/etc/facter/facts.d/fake_fact.txt').returns(['fake_fact=fake fact']) - subject.create - end - - it 'should return successfully' do - expect(Facter.fact(:fake_fact).value).to eq('fake fact') - end - end - - context 'returns a fact with equals signs' do - before :each do - Facter.stubs(:version).returns('1.6.1') - subject.stubs(:entries).returns(['/etc/facter/facts.d/foo.txt']) - File.stubs(:readlines).with('/etc/facter/facts.d/foo.txt').returns(['foo=1+1=2']) - subject.create - end - - it 'should return successfully' do - expect(Facter.fact(:foo).value).to eq('1+1=2') - end - end -end diff --git a/spec/unit/facter/package_provider_spec.rb b/spec/unit/facter/package_provider_spec.rb index d1aee94b8..3e75c2870 100644 --- a/spec/unit/facter/package_provider_spec.rb +++ b/spec/unit/facter/package_provider_spec.rb @@ -1,37 +1,45 @@ -#! /usr/bin/env ruby -S rspec +# frozen_string_literal: true + require 'spec_helper' require 'puppet/type' require 'puppet/type/package' -describe 'package_provider', :type => :fact do - before { Facter.clear } - after { Facter.clear } - - context "darwin" do - it "should return pkgdmg" do - provider = Puppet::Type.type(:package).provider(:pkgdmg) - Puppet::Type.type(:package).stubs(:defaultprovider).returns provider - - expect(Facter.fact(:package_provider).value).to eq('pkgdmg') - end - end - - context "centos 7" do - it "should return yum" do - provider = Puppet::Type.type(:package).provider(:yum) - Puppet::Type.type(:package).stubs(:defaultprovider).returns provider - - expect(Facter.fact(:package_provider).value).to eq('yum') - end - end - - context "ubuntu" do - it "should return apt" do - provider = Puppet::Type.type(:package).provider(:apt) - Puppet::Type.type(:package).stubs(:defaultprovider).returns provider - - expect(Facter.fact(:package_provider).value).to eq('apt') +describe 'package_provider', type: :fact do + before(:each) { Facter.clear } + after(:each) { Facter.clear } + + ['4.2.2', '3.7.1 (Puppet Enterprise 3.2.1)'].each do |puppetversion| + describe "on puppet ''#{puppetversion}''" do + before :each do + allow(Facter).to receive(:value).and_return(puppetversion) + end + + context 'when darwin' do + it 'returns pkgdmg' do + provider = Puppet::Type.type(:package).provider(:pkgdmg) + allow(Puppet::Type.type(:package)).to receive(:defaultprovider).and_return(provider) + + expect(Facter.fact(:package_provider).value).to eq('pkgdmg') + end + end + + context 'when centos 7' do + it 'returns yum' do + provider = Puppet::Type.type(:package).provider(:yum) + allow(Puppet::Type.type(:package)).to receive(:defaultprovider).and_return(provider) + + expect(Facter.fact(:package_provider).value).to eq('yum') + end + end + + context 'when ubuntu' do + it 'returns apt' do + provider = Puppet::Type.type(:package).provider(:apt) + allow(Puppet::Type.type(:package)).to receive(:defaultprovider).and_return(provider) + + expect(Facter.fact(:package_provider).value).to eq('apt') + end + end end end - end diff --git a/spec/unit/facter/pe_version_spec.rb b/spec/unit/facter/pe_version_spec.rb old mode 100755 new mode 100644 index c11a1cd09..56b3dafe1 --- a/spec/unit/facter/pe_version_spec.rb +++ b/spec/unit/facter/pe_version_spec.rb @@ -1,88 +1,81 @@ -#!/usr/bin/env rspec +# frozen_string_literal: true require 'spec_helper' -describe "PE Version specs" do - before :each do - # Explicitly load the pe_version.rb file which contains generated facts - # that cannot be automatically loaded. Puppet 2.x implements - # Facter.collection.load while Facter 1.x markes Facter.collection.load as - # a private method. - if Facter.collection.respond_to? :load - Facter.collection.load(:pe_version) - else - Facter.collection.loader.load(:pe_version) - end - end - - context "When puppetversion is nil" do +describe 'PE Version specs' do + # we mock calls for the puppetversion fact, it is not normal to expect nil responses when mocking. + RSpec::Mocks.configuration.allow_message_expectations_on_nil = true + context 'when puppetversion is nil' do before :each do - Facter.fact(:puppetversion).stubs(:value).returns(nil) + allow(Facter.fact(:puppetversion)).to receive(:value).and_return(nil) end - - it "pe_version is nil" do + + it 'puppetversion is nil' do expect(Facter.fact(:puppetversion).value).to be_nil + end + + it 'pe_version is nil' do expect(Facter.fact(:pe_version).value).to be_nil end end - context "If PE is installed" do - %w{ 2.6.1 2.10.300 }.each do |version| + context 'when PE is installed' do + ['2.6.1', '2.10.300'].each do |version| puppetversion = "2.7.19 (Puppet Enterprise #{version})" context "puppetversion => #{puppetversion}" do before :each do - Facter.fact(:puppetversion).stubs(:value).returns(puppetversion) + allow(Facter).to receive(:value).with(anything).and_call_original + allow(Facter).to receive(:value).with('puppetversion').and_return(puppetversion) end - (major,minor,patch) = version.split(".") + (major, minor, patch) = version.split('.') - it "Should return true" do - expect(Facter.fact(:is_pe).value).to eq(true) + it 'returns true' do + expect(Facter.fact(:is_pe).value).to be(true) end - it "Should have a version of #{version}" do + it "has a version of #{version}" do expect(Facter.fact(:pe_version).value).to eq(version) end - it "Should have a major version of #{major}" do + it "has a major version of #{major}" do expect(Facter.fact(:pe_major_version).value).to eq(major) end - it "Should have a minor version of #{minor}" do + it "has a minor version of #{minor}" do expect(Facter.fact(:pe_minor_version).value).to eq(minor) end - it "Should have a patch version of #{patch}" do + it "has a patch version of #{patch}" do expect(Facter.fact(:pe_patch_version).value).to eq(patch) end end end end - context "When PE is not installed" do + context 'when PE is not installed' do before :each do - Facter.fact(:puppetversion).stubs(:value).returns("2.7.19") + allow(Facter.fact(:puppetversion)).to receive(:value).and_return('2.7.19') end - it "is_pe is false" do - expect(Facter.fact(:is_pe).value).to eq(false) + it 'is_pe is false' do + expect(Facter.fact(:is_pe).value).to be(false) end - it "pe_version is nil" do + it 'pe_version is nil' do expect(Facter.fact(:pe_version).value).to be_nil end - it "pe_major_version is nil" do + it 'pe_major_version is nil' do expect(Facter.fact(:pe_major_version).value).to be_nil end - it "pe_minor_version is nil" do + it 'pe_minor_version is nil' do expect(Facter.fact(:pe_minor_version).value).to be_nil end - it "Should have a patch version" do + it 'has a patch version' do expect(Facter.fact(:pe_patch_version).value).to be_nil end end - end diff --git a/spec/unit/facter/root_home_spec.rb b/spec/unit/facter/root_home_spec.rb old mode 100755 new mode 100644 index a5c2846ec..e1c97a30e --- a/spec/unit/facter/root_home_spec.rb +++ b/spec/unit/facter/root_home_spec.rb @@ -1,65 +1,21 @@ -#! /usr/bin/env ruby -S rspec +# frozen_string_literal: true + require 'spec_helper' require 'facter/root_home' -describe Facter::Util::RootHome do - context "solaris" do - let(:root_ent) { "root:x:0:0:Super-User:/:/sbin/sh" } - let(:expected_root_home) { "/" } - - it "should return /" do - Facter::Util::Resolution.expects(:exec).with("getent passwd root").returns(root_ent) - expect(Facter::Util::RootHome.get_root_home).to eq(expected_root_home) - end - end - context "linux" do - let(:root_ent) { "root:x:0:0:root:/root:/bin/bash" } - let(:expected_root_home) { "/root" } - - it "should return /root" do - Facter::Util::Resolution.expects(:exec).with("getent passwd root").returns(root_ent) - expect(Facter::Util::RootHome.get_root_home).to eq(expected_root_home) - end - end - context "windows" do - before :each do - Facter::Util::Resolution.expects(:exec).with("getent passwd root").returns(nil) - end - it "should be nil on windows" do - expect(Facter::Util::RootHome.get_root_home).to be_nil - end - end -end - -describe 'root_home', :type => :fact do - before { Facter.clear } - after { Facter.clear } +describe 'root_home', type: :fact do + subject { Facter.fact(:root_home) } - context "macosx" do - before do - Facter.fact(:kernel).stubs(:value).returns("Darwin") - Facter.fact(:osfamily).stubs(:value).returns("Darwin") - end - let(:expected_root_home) { "/var/root" } - sample_dscacheutil = File.read(fixtures('dscacheutil','root')) + before(:each) { Facter.clear } + after(:each) { Facter.clear } - it "should return /var/root" do - Facter::Util::Resolution.stubs(:exec).with("dscacheutil -q user -a name root").returns(sample_dscacheutil) - expect(Facter.fact(:root_home).value).to eq(expected_root_home) - end + context 'when Windows', if: Facter.value(:kernel) == 'Windows' do + it { expect(subject.value).to be_nil } end - context "aix" do - before do - Facter.fact(:kernel).stubs(:value).returns("AIX") - Facter.fact(:osfamily).stubs(:value).returns("AIX") - end - let(:expected_root_home) { "/root" } - sample_lsuser = File.read(fixtures('lsuser','root')) + context 'when non-Windows', if: Facter.value(:kernel) != 'Windows' do + let(:expected) { (Facter.value(:kernel) == 'Darwin') ? '/var/root' : '/root' } - it "should return /root" do - Facter::Util::Resolution.stubs(:exec).with("lsuser -c -a home root").returns(sample_lsuser) - expect(Facter.fact(:root_home).value).to eq(expected_root_home) - end + it { expect(subject.value).to eq(expected) } end end diff --git a/spec/unit/facter/service_provider_spec.rb b/spec/unit/facter/service_provider_spec.rb index ad8a5fc53..4d7d4e104 100644 --- a/spec/unit/facter/service_provider_spec.rb +++ b/spec/unit/facter/service_provider_spec.rb @@ -1,37 +1,37 @@ -#! /usr/bin/env ruby -S rspec +# frozen_string_literal: true + require 'spec_helper' require 'puppet/type' require 'puppet/type/service' -describe 'service_provider', :type => :fact do - before { Facter.clear } - after { Facter.clear } +describe 'service_provider', type: :fact do + before(:each) { Facter.clear } + after(:each) { Facter.clear } - context "macosx" do - it "should return launchd" do + context 'when macosx' do + it 'returns launchd' do provider = Puppet::Type.type(:service).provider(:launchd) - Puppet::Type.type(:service).stubs(:defaultprovider).returns provider + allow(Puppet::Type.type(:service)).to receive(:defaultprovider).and_return(provider) expect(Facter.fact(:service_provider).value).to eq('launchd') end end - context "systemd" do - it "should return systemd" do + context 'when systemd' do + it 'returns systemd' do provider = Puppet::Type.type(:service).provider(:systemd) - Puppet::Type.type(:service).stubs(:defaultprovider).returns provider + allow(Puppet::Type.type(:service)).to receive(:defaultprovider).and_return(provider) expect(Facter.fact(:service_provider).value).to eq('systemd') end end - context "redhat" do - it "should return redhat" do + context 'when redhat' do + it 'returns redhat' do provider = Puppet::Type.type(:service).provider(:redhat) - Puppet::Type.type(:service).stubs(:defaultprovider).returns provider + allow(Puppet::Type.type(:service)).to receive(:defaultprovider).and_return(provider) expect(Facter.fact(:service_provider).value).to eq('redhat') end end - end diff --git a/spec/unit/facter/util/puppet_settings_spec.rb b/spec/unit/facter/util/puppet_settings_spec.rb old mode 100755 new mode 100644 index c278b7984..13d032f51 --- a/spec/unit/facter/util/puppet_settings_spec.rb +++ b/spec/unit/facter/util/puppet_settings_spec.rb @@ -1,35 +1,39 @@ -#! /usr/bin/env ruby -S rspec +# frozen_string_literal: true + require 'spec_helper' require 'facter/util/puppet_settings' describe Facter::Util::PuppetSettings do - - describe "#with_puppet" do - context "Without Puppet loaded" do + describe '#with_puppet' do + context 'without Puppet loaded' do before(:each) do - Module.expects(:const_get).with("Puppet").raises(NameError) + allow(Module).to receive(:const_get).with(:Puppet).and_raise(NameError) end - it 'should be nil' do + it 'is nil' do expect(subject.with_puppet { Puppet[:vardir] }).to be_nil end - it 'should not yield to the block' do - Puppet.expects(:[]).never + + it 'does not yield to the block' do + expect(Puppet).not_to receive(:[]) expect(subject.with_puppet { Puppet[:vardir] }).to be_nil end end - context "With Puppet loaded" do + + context 'with Puppet loaded' do + # module Puppet module Puppet; end - let(:vardir) { "/var/lib/puppet" } + let(:vardir) { '/var/lib/puppet' } before :each do - Puppet.expects(:[]).with(:vardir).returns vardir + allow(Puppet).to receive(:[]).with(:vardir).and_return(vardir) end - it 'should yield to the block' do + it 'yields to the block' do subject.with_puppet { Puppet[:vardir] } end - it 'should return the nodes vardir' do + + it 'returns the nodes vardir' do expect(subject.with_puppet { Puppet[:vardir] }).to eq vardir end end diff --git a/spec/unit/puppet/parser/functions/enclose_ipv6_spec.rb b/spec/unit/puppet/parser/functions/enclose_ipv6_spec.rb new file mode 100644 index 000000000..280b49603 --- /dev/null +++ b/spec/unit/puppet/parser/functions/enclose_ipv6_spec.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'enclose_ipv6' do + let(:node) { Puppet::Node.new('localhost') } + let(:compiler) { Puppet::Parser::Compiler.new(node) } + let(:scope) { Puppet::Parser::Scope.new(compiler) } + + it 'exists' do + expect(Puppet::Parser::Functions.function('enclose_ipv6')).to eq('function_enclose_ipv6') + end + + it 'raises a ParseError if there is less than 1 arguments' do + expect { scope.function_enclose_ipv6([]) }.to(raise_error(Puppet::ParseError)) + end + + it 'raises a ParseError if there is more than 1 arguments' do + expect { scope.function_enclose_ipv6(['argument1', 'argument2']) }.to(raise_error(Puppet::ParseError)) + end + + it 'raises a ParseError when given garbage' do + expect { scope.function_enclose_ipv6(['garbage']) }.to(raise_error(Puppet::ParseError)) + end + + it 'raises a ParseError when given something else than a string or an array' do + expect { scope.function_enclose_ipv6([['1' => '127.0.0.1']]) }.to(raise_error(Puppet::ParseError)) + end + + it 'does not raise a ParseError when given a single ip string' do + expect { scope.function_enclose_ipv6(['127.0.0.1']) }.not_to raise_error + end + + it 'does not raise a ParseError when given * as ip strint g' do + expect { scope.function_enclose_ipv6(['*']) }.not_to raise_error + end + + it 'does not raise a ParseError when given an array of ip strings' do + expect { scope.function_enclose_ipv6([['127.0.0.1', 'fe80::1']]) }.not_to raise_error + end + + it 'does not raise a ParseError when given differently notations of ip addresses' do + expect { scope.function_enclose_ipv6([['127.0.0.1', 'fe80::1', '[fe80::1]']]) }.not_to raise_error + end + + it 'raises a ParseError when given a wrong ipv4 address' do + expect { scope.function_enclose_ipv6(['127..0.0.1']) }.to(raise_error(Puppet::ParseError)) + end + + it 'raises a ParseError when given a ipv4 address with square brackets' do + expect { scope.function_enclose_ipv6(['[127.0.0.1]']) }.to(raise_error(Puppet::ParseError)) + end + + it 'raises a ParseError when given a wrong ipv6 address' do + expect { scope.function_enclose_ipv6(['fe80:::1']) }.to(raise_error(Puppet::ParseError)) + end + + it 'embraces ipv6 adresses within an array of ip addresses' do + result = scope.function_enclose_ipv6([['127.0.0.1', 'fe80::1', '[fe80::2]']]) + expect(result).to(eq(['127.0.0.1', '[fe80::1]', '[fe80::2]'])) + end + + it 'embraces a single ipv6 adresse' do + result = scope.function_enclose_ipv6(['fe80::1']) + expect(result).to(eq(['[fe80::1]'])) + end + + it 'does not embrace a single ipv4 adresse' do + result = scope.function_enclose_ipv6(['127.0.0.1']) + expect(result).to(eq(['127.0.0.1'])) + end +end diff --git a/spec/unit/puppet/provider/file_line/ruby_alter_spec.rb b/spec/unit/puppet/provider/file_line/ruby_alter_spec.rb new file mode 100644 index 000000000..310ac5c97 --- /dev/null +++ b/spec/unit/puppet/provider/file_line/ruby_alter_spec.rb @@ -0,0 +1,389 @@ +# frozen_string_literal: true + +require 'spec_helper' + +provider_class = Puppet::Type.type(:file_line).provider(:ruby) +# Ā These tests fail on windows when run as part of the rake task. Individually they pass +describe provider_class, unless: Puppet::Util::Platform.windows? do + include PuppetlabsSpec::Files + + let :tmpfile do + tmpfilename('file_line_test') + end + let :content do + '' + end + let :params do + {} + end + let :resource do + Puppet::Type::File_line.new({ + name: 'foo', + path: tmpfile, + line: 'foo' + }.merge(params)) + end + let :provider do + provider_class.new(resource) + end + + before :each do + File.write(tmpfile, content) + end + + describe '#create' do + context 'when replacing' do + let :params do + { + line: 'foo = bar', + match: '^foo\s*=.*$', + replace: false + } + end + let(:content) { "foo1\nfoo=blah\nfoo2\nfoo3" } + + it "providor 'be_exists'" do + expect(provider).to be_exists + end + + it 'does not replace the matching line' do + provider.create + expect(File.read(tmpfile).chomp).to eql("foo1\nfoo=blah\nfoo2\nfoo3") + end + + it 'appends the line if no matches are found' do + File.write(tmpfile, "foo1\nfoo2") + expect(provider.exists?).to be false + provider.create + expect(File.read(tmpfile).chomp).to eql("foo1\nfoo2\nfoo = bar") + end + + it 'raises an error with invalid values' do + expect { + @resource = Puppet::Type::File_line.new( + name: 'foo', path: tmpfile, line: 'foo = bar', match: '^foo\s*=.*$', replace: 'asgadga', + ) + }.to raise_error(Puppet::Error, %r{Invalid value "asgadga"\. Valid values are true, false\.}) + end + end + end + + context 'when matching' do + # rubocop:disable RSpec/InstanceVariable : replacing before with let breaks the tests, variables need to be altered within it block : multi + before :each do + @resource = Puppet::Type::File_line.new( + name: 'foo', + path: tmpfile, + line: 'foo = bar', + match: '^foo\s*=.*$', + ) + @provider = provider_class.new(@resource) + end + + describe 'using match' do + it 'raises an error if more than one line matches, and should not have modified the file' do + File.write(tmpfile, "foo1\nfoo=blah\nfoo2\nfoo=baz") + expect { @provider.create }.to raise_error(Puppet::Error, %r{More than one line.*matches}) + expect(File.read(tmpfile)).to eql("foo1\nfoo=blah\nfoo2\nfoo=baz") + end + + it 'replaces all lines that matches' do + @resource = Puppet::Type::File_line.new(name: 'foo', path: tmpfile, line: 'foo = bar', match: '^foo\s*=.*$', multiple: true) + @provider = provider_class.new(@resource) + File.write(tmpfile, "foo1\nfoo=blah\nfoo2\nfoo=baz") + @provider.create + expect(File.read(tmpfile).chomp).to eql("foo1\nfoo = bar\nfoo2\nfoo = bar") + end + + it 'replaces all lines that match, even when some lines are correct' do + @resource = Puppet::Type::File_line.new(name: 'neil', path: tmpfile, line: "\thard\tcore\t0\n", match: '^[ \t]hard[ \t]+core[ \t]+.*', multiple: true) + @provider = provider_class.new(@resource) + File.write(tmpfile, "\thard\tcore\t90\n\thard\tcore\t0\n") + @provider.create + expect(File.read(tmpfile).chomp).to eql("\thard\tcore\t0\n\thard\tcore\t0") + end + + it 'raises an error with invalid values' do + expect { + @resource = Puppet::Type::File_line.new( + name: 'foo', path: tmpfile, line: 'foo = bar', match: '^foo\s*=.*$', multiple: 'asgadga', + ) + }.to raise_error(Puppet::Error, %r{Invalid value "asgadga"\. Valid values are true, false\.}) + end + + it 'replaces a line that matches' do + File.write(tmpfile, "foo1\nfoo=blah\nfoo2") + @provider.create + expect(File.read(tmpfile).chomp).to eql("foo1\nfoo = bar\nfoo2") + end + + it 'adds a new line if no lines match' do + File.write(tmpfile, "foo1\nfoo2") + @provider.create + expect(File.read(tmpfile)).to eql("foo1\nfoo2\nfoo = bar\n") + end + + it 'does nothing if the exact line already exists' do + File.write(tmpfile, "foo1\nfoo = bar\nfoo2") + @provider.create + expect(File.read(tmpfile).chomp).to eql("foo1\nfoo = bar\nfoo2") + end + end + + describe 'using match+append_on_no_match - when there is a match' do + it 'replaces line' do + @resource = Puppet::Type::File_line.new(name: 'foo', path: tmpfile, line: 'inserted = line', match: '^foo3$', append_on_no_match: false) + @provider = provider_class.new(@resource) + File.write(tmpfile, "foo1\nfoo = blah\nfoo2\nfoo = baz") + expect(File.read(tmpfile).chomp).to eql("foo1\nfoo = blah\nfoo2\nfoo = baz") + end + end + + describe 'using match+append_on_no_match - when there is no match' do + it 'does not add line after no matches found' do + @resource = Puppet::Type::File_line.new(name: 'foo', path: tmpfile, line: 'inserted = line', match: '^foo3$', append_on_no_match: false) + @provider = provider_class.new(@resource) + File.write(tmpfile, "foo1\nfoo = blah\nfoo2\nfoo = baz") + expect(File.read(tmpfile).chomp).to eql("foo1\nfoo = blah\nfoo2\nfoo = baz") + end + end + end + + context 'when after' do + let :resource do + Puppet::Type::File_line.new( + name: 'foo', + path: tmpfile, + line: 'inserted = line', + after: '^foo1', + ) + end + + let :provider do + provider_class.new(resource) + end + + context 'when match and after set' do + shared_context 'resource_create' do + let(:match) { '^foo2$' } + let(:after) { '^foo1$' } + let(:resource) do + Puppet::Type::File_line.new( + name: 'foo', + path: tmpfile, + line: 'inserted = line', + after:, + match:, + ) + end + end + + before :each do + File.write(tmpfile, "foo1\nfoo2\nfoo = baz") + end + + describe 'inserts at match' do + include_context 'resource_create' + it { + provider.create + expect(File.read(tmpfile).chomp).to eq("foo1\ninserted = line\nfoo = baz") + } + end + + describe 'inserts a new line after when no match' do + include_context 'resource_create' do + let(:match) { '^nevergoingtomatch$' } + end + it { + provider.create + expect(File.read(tmpfile).chomp).to eq("foo1\ninserted = line\nfoo2\nfoo = baz") + } + end + + describe 'append to end of file if no match for both after and match' do + include_context 'resource_create' do + let(:match) { '^nevergoingtomatch$' } + let(:after) { '^stillneverafter' } + end + it { + provider.create + expect(File.read(tmpfile).chomp).to eq("foo1\nfoo2\nfoo = baz\ninserted = line") + } + end + end + + context 'with one line matching the after expression' do + before :each do + File.write(tmpfile, "foo1\nfoo = blah\nfoo2\nfoo = baz") + end + + it 'inserts the specified line after the line matching the "after" expression' do + provider.create + expect(File.read(tmpfile).chomp).to eql("foo1\ninserted = line\nfoo = blah\nfoo2\nfoo = baz") + end + end + + context 'with multiple lines matching the after expression' do + before :each do + File.write(tmpfile, "foo1\nfoo = blah\nfoo2\nfoo1\nfoo = baz") + end + + it 'errors out stating "One or no line must match the pattern"' do + expect { provider.create }.to raise_error(Puppet::Error, %r{One or no line must match the pattern}) + end + + it 'adds the line after all lines matching the after expression' do + @resource = Puppet::Type::File_line.new(name: 'foo', path: tmpfile, line: 'inserted = line', after: '^foo1$', multiple: true) + @provider = provider_class.new(@resource) + @provider.create + expect(File.read(tmpfile).chomp).to eql("foo1\ninserted = line\nfoo = blah\nfoo2\nfoo1\ninserted = line\nfoo = baz") + end + end + + context 'with no lines matching the after expression' do + let :content do + "foo3\nfoo = blah\nfoo2\nfoo = baz\n" + end + + before :each do + File.write(tmpfile, content) + end + + it 'appends the specified line to the file' do + provider.create + expect(File.read(tmpfile)).to eq("#{content}#{resource[:line]}\n") + end + end + end + + context 'when removing with a line' do + before :each do + # TODO: these should be ported over to use the PuppetLabs spec_helper + # file fixtures once the following pull request has been merged: + # https://github.com/puppetlabs/puppetlabs-stdlib/pull/73/files + @resource = Puppet::Type::File_line.new( + name: 'foo', + path: tmpfile, + line: 'foo', + ensure: 'absent', + ) + @provider = provider_class.new(@resource) + end + + it 'removes the line if it exists' do + File.write(tmpfile, "foo1\nfoo\nfoo2") + @provider.destroy + expect(File.read(tmpfile)).to eql("foo1\nfoo2") + end + + it 'removes the line without touching the last new line' do + File.write(tmpfile, "foo1\nfoo\nfoo2\n") + @provider.destroy + expect(File.read(tmpfile)).to eql("foo1\nfoo2\n") + end + + it 'removes any occurence of the line' do + File.write(tmpfile, "foo1\nfoo\nfoo2\nfoo\nfoo") + @provider.destroy + expect(File.read(tmpfile)).to eql("foo1\nfoo2\n") + end + + it 'example in the docs' do + @resource = Puppet::Type::File_line.new(name: 'bashrc_proxy', ensure: 'absent', path: tmpfile, line: 'export HTTP_PROXY=http://squid.puppetlabs.vm:3128') + @provider = provider_class.new(@resource) + File.write(tmpfile, "foo1\nfoo2\nexport HTTP_PROXY=http://squid.puppetlabs.vm:3128\nfoo4\n") + @provider.destroy + expect(File.read(tmpfile)).to eql("foo1\nfoo2\nfoo4\n") + end + end + + context 'when removing with a match' do + before :each do + @resource = Puppet::Type::File_line.new( + name: 'foo', + path: tmpfile, + line: 'foo2', + ensure: 'absent', + match: 'o$', + match_for_absence: true, + ) + @provider = provider_class.new(@resource) + end + + it 'finds a line to match' do + File.write(tmpfile, "foo1\nfoo\nfoo2") + expect(@provider.exists?).to be true + end + + it 'removes one line if it matches' do + File.write(tmpfile, "foo1\nfoo\nfoo2") + @provider.destroy + expect(File.read(tmpfile)).to eql("foo1\nfoo2") + end + + it 'the line parameter is actually not used at all but is silently ignored if here' do + @resource = Puppet::Type::File_line.new(name: 'foo', path: tmpfile, line: 'supercalifragilisticexpialidocious', ensure: 'absent', match: 'o$', match_for_absence: true) + @provider = provider_class.new(@resource) + File.write(tmpfile, "foo1\nfoo\nfoo2") + @provider.destroy + expect(File.read(tmpfile)).to eql("foo1\nfoo2") + end + + it 'and may not be here and does not need to be here' do + @resource = Puppet::Type::File_line.new(name: 'foo', path: tmpfile, ensure: 'absent', match: 'o$', match_for_absence: true) + @provider = provider_class.new(@resource) + File.write(tmpfile, "foo1\nfoo\nfoo2") + @provider.destroy + expect(File.read(tmpfile)).to eql("foo1\nfoo2") + end + + it 'raises an error if more than one line matches' do + File.write(tmpfile, "foo1\nfoo\nfoo2\nfoo\nfoo") + expect { @provider.destroy }.to raise_error(Puppet::Error, %r{More than one line}) + end + + it 'removes multiple lines if :multiple is true' do + @resource = Puppet::Type::File_line.new(name: 'foo', path: tmpfile, line: 'foo2', ensure: 'absent', match: 'o$', multiple: true, match_for_absence: true) + @provider = provider_class.new(@resource) + File.write(tmpfile, "foo1\nfoo\nfoo2\nfoo\nfoo") + @provider.destroy + expect(File.read(tmpfile)).to eql("foo1\nfoo2\n") + end + + it 'ignores the match if match_for_absence is not specified' do + @resource = Puppet::Type::File_line.new(name: 'foo', path: tmpfile, line: 'foo2', ensure: 'absent', match: 'o$') + @provider = provider_class.new(@resource) + File.write(tmpfile, "foo1\nfoo\nfoo2") + @provider.destroy + expect(File.read(tmpfile)).to eql("foo1\nfoo\n") + end + + it 'ignores the match if match_for_absence is false' do + @resource = Puppet::Type::File_line.new(name: 'foo', path: tmpfile, line: 'foo2', ensure: 'absent', match: 'o$', match_for_absence: false) + @provider = provider_class.new(@resource) + File.write(tmpfile, "foo1\nfoo\nfoo2") + @provider.destroy + expect(File.read(tmpfile)).to eql("foo1\nfoo\n") + end + + it 'example in the docs' do + @resource = Puppet::Type::File_line.new( + name: 'bashrc_proxy', ensure: 'absent', path: tmpfile, line: 'export HTTP_PROXY=http://squid.puppetlabs.vm:3128', + match: '^export\ HTTP_PROXY\=', match_for_absence: true + ) + @provider = provider_class.new(@resource) + File.write(tmpfile, "foo1\nfoo2\nexport HTTP_PROXY=foo\nfoo4\n") + @provider.destroy + expect(File.read(tmpfile)).to eql("foo1\nfoo2\nfoo4\n") + end + + it 'example in the docs showing line is redundant' do + @resource = Puppet::Type::File_line.new(name: 'bashrc_proxy', ensure: 'absent', path: tmpfile, match: '^export\ HTTP_PROXY\=', match_for_absence: true) + @provider = provider_class.new(@resource) + File.write(tmpfile, "foo1\nfoo2\nexport HTTP_PROXY=foo\nfoo4\n") + @provider.destroy + expect(File.read(tmpfile)).to eql("foo1\nfoo2\nfoo4\n") + end + end + # rubocop:enable RSpec/InstanceVariable +end diff --git a/spec/unit/puppet/provider/file_line/ruby_spec.rb b/spec/unit/puppet/provider/file_line/ruby_spec.rb old mode 100755 new mode 100644 index 23e649cc9..0577e3017 --- a/spec/unit/puppet/provider/file_line/ruby_spec.rb +++ b/spec/unit/puppet/provider/file_line/ruby_spec.rb @@ -1,440 +1,268 @@ -#! /usr/bin/env ruby -S rspec +# frozen_string_literal: true + require 'spec_helper' -require 'tempfile' + provider_class = Puppet::Type.type(:file_line).provider(:ruby) -describe provider_class do - context "when adding" do - let :tmpfile do - tmp = Tempfile.new('tmp') - path = tmp.path - tmp.close! - path - end - let :resource do - Puppet::Type::File_line.new( - {:name => 'foo', :path => tmpfile, :line => 'foo'} - ) - end - let :provider do - provider_class.new(resource) - end +# Ā These tests fail on windows when run as part of the rake task. Individually they pass +describe provider_class, unless: Puppet::Util::Platform.windows? do + include PuppetlabsSpec::Files - it 'should detect if the line exists in the file' do - File.open(tmpfile, 'w') do |fh| - fh.write('foo') - end - expect(provider.exists?).to be_truthy - end - it 'should detect if the line does not exist in the file' do - File.open(tmpfile, 'w') do |fh| - fh.write('foo1') - end - expect(provider.exists?).to be_nil - end - it 'should append to an existing file when creating' do - provider.create - expect(File.read(tmpfile).chomp).to eq('foo') - end + let :tmpfile do + tmpfilename('file_line_test') end - context 'when using replace' do - before :each do - # TODO: these should be ported over to use the PuppetLabs spec_helper - # file fixtures once the following pull request has been merged: - # https://github.com/puppetlabs/puppetlabs-stdlib/pull/73/files - tmp = Tempfile.new('tmp') - @tmpfile = tmp.path - tmp.close! - @resource = Puppet::Type::File_line.new( - { - :name => 'foo', - :path => @tmpfile, - :line => 'foo = bar', - :match => '^foo\s*=.*$', - :replace => false, - } - ) - @provider = provider_class.new(@resource) - end + let :content do + '' + end + let :params do + {} + end + let :resource do + Puppet::Type::File_line.new({ + name: 'foo', + path: tmpfile, + line: 'foo' + }.merge(params)) + end + let :provider do + provider_class.new(resource) + end + + before :each do + File.write(tmpfile, content) + end + + describe 'line parameter' do + context 'when line exists' do + let(:content) { 'foo' } - it 'should not replace the matching line' do - File.open(@tmpfile, 'w') do |fh| - fh.write("foo1\nfoo=blah\nfoo2\nfoo3") + it 'detects the line' do + expect(provider).to be_exists end - expect(@provider.exists?).to be_truthy - @provider.create - expect(File.read(@tmpfile).chomp).to eql("foo1\nfoo=blah\nfoo2\nfoo3") end - it 'should append the line if no matches are found' do - File.open(@tmpfile, 'w') do |fh| - fh.write("foo1\nfoo2") + context 'when line does not exist' do + let(:content) { 'foo bar' } + + it 'requests changes' do + expect(provider).not_to be_exists end - expect(@provider.exists?).to be_nil - @provider.create - expect(File.read(@tmpfile).chomp).to eql("foo1\nfoo2\nfoo = bar") - end - it 'should raise an error with invalid values' do - expect { - @resource = Puppet::Type::File_line.new( - { - :name => 'foo', - :path => @tmpfile, - :line => 'foo = bar', - :match => '^foo\s*=.*$', - :replace => 'asgadga', - } - ) - }.to raise_error(Puppet::Error, /Invalid value "asgadga"\. Valid values are true, false\./) + it 'appends the line' do + provider.create + expect(File.read(tmpfile).chomp).to eq("foo bar\nfoo") + end end end - context "when matching" do - before :each do - # TODO: these should be ported over to use the PuppetLabs spec_helper - # file fixtures once the following pull request has been merged: - # https://github.com/puppetlabs/puppetlabs-stdlib/pull/73/files - tmp = Tempfile.new('tmp') - @tmpfile = tmp.path - tmp.close! - @resource = Puppet::Type::File_line.new( - { - :name => 'foo', - :path => @tmpfile, - :line => 'foo = bar', - :match => '^foo\s*=.*$', - } - ) - @provider = provider_class.new(@resource) - end - describe 'using match' do - it 'should raise an error if more than one line matches, and should not have modified the file' do - File.open(@tmpfile, 'w') do |fh| - fh.write("foo1\nfoo=blah\nfoo2\nfoo=baz") - end - expect(@provider.exists?).to be_nil - expect { @provider.create }.to raise_error(Puppet::Error, /More than one line.*matches/) - expect(File.read(@tmpfile)).to eql("foo1\nfoo=blah\nfoo2\nfoo=baz") - end + describe 'match parameter' do + let(:params) { { match: '^bar' } } - it 'should replace all lines that matches' do - @resource = Puppet::Type::File_line.new( - { - :name => 'foo', - :path => @tmpfile, - :line => 'foo = bar', - :match => '^foo\s*=.*$', - :multiple => true, - } - ) - @provider = provider_class.new(@resource) - File.open(@tmpfile, 'w') do |fh| - fh.write("foo1\nfoo=blah\nfoo2\nfoo=baz") - end - expect(@provider.exists?).to be_nil - @provider.create - expect(File.read(@tmpfile).chomp).to eql("foo1\nfoo = bar\nfoo2\nfoo = bar") - end + describe 'does not match line - line does not exist - replacing' do + let(:content) { "foo bar\nbar" } - it 'should raise an error with invalid values' do - expect { - @resource = Puppet::Type::File_line.new( - { - :name => 'foo', - :path => @tmpfile, - :line => 'foo = bar', - :match => '^foo\s*=.*$', - :multiple => 'asgadga', - } - ) - }.to raise_error(Puppet::Error, /Invalid value "asgadga"\. Valid values are true, false\./) + it 'requests changes' do + expect(provider).not_to be_exists end - it 'should replace a line that matches' do - File.open(@tmpfile, 'w') do |fh| - fh.write("foo1\nfoo=blah\nfoo2") - end - expect(@provider.exists?).to be_nil - @provider.create - expect(File.read(@tmpfile).chomp).to eql("foo1\nfoo = bar\nfoo2") - end - it 'should add a new line if no lines match' do - File.open(@tmpfile, 'w') do |fh| - fh.write("foo1\nfoo2") - end - expect(@provider.exists?).to be_nil - @provider.create - expect(File.read(@tmpfile)).to eql("foo1\nfoo2\nfoo = bar\n") - end - it 'should do nothing if the exact line already exists' do - File.open(@tmpfile, 'w') do |fh| - fh.write("foo1\nfoo = bar\nfoo2") - end - expect(@provider.exists?).to be_truthy - @provider.create - expect(File.read(@tmpfile).chomp).to eql("foo1\nfoo = bar\nfoo2") + it 'replaces the match' do + provider.create + expect(File.read(tmpfile).chomp).to eq("foo bar\nfoo") end end - describe 'using after' do - let :resource do - Puppet::Type::File_line.new( - { - :name => 'foo', - :path => @tmpfile, - :line => 'inserted = line', - :after => '^foo1', - } - ) - end + describe 'does not match line - line does not exist - appending' do + let(:params) { super().merge(replace: false) } + let(:content) { "foo bar\nbar" } - let :provider do - provider_class.new(resource) + it 'does not request changes' do + expect(provider).to be_exists end - context 'match and after set' do - shared_context 'resource_create' do - let(:match) { '^foo2$' } - let(:after) { '^foo1$' } - let(:resource) { - Puppet::Type::File_line.new( - { - :name => 'foo', - :path => @tmpfile, - :line => 'inserted = line', - :after => after, - :match => match, - } - ) - } - end - before :each do - File.open(@tmpfile, 'w') do |fh| - fh.write("foo1\nfoo2\nfoo = baz") - end - end - describe 'inserts at match' do - include_context 'resource_create' - it { - provider.create - expect(File.read(@tmpfile).chomp).to eq("foo1\ninserted = line\nfoo = baz") - } - end - describe 'inserts a new line after when no match' do - include_context 'resource_create' do - let(:match) { '^nevergoingtomatch$' } - end - it { - provider.create - expect(File.read(@tmpfile).chomp).to eq("foo1\ninserted = line\nfoo2\nfoo = baz") - } - end - describe 'append to end of file if no match for both after and match' do - include_context 'resource_create' do - let(:match) { '^nevergoingtomatch$' } - let(:after) { '^stillneverafter' } - end - it { - provider.create - expect(File.read(@tmpfile).chomp).to eq("foo1\nfoo2\nfoo = baz\ninserted = line") - } - end + end + + context 'when does not match line - line exists' do + let(:content) { "foo\nbar" } + + it 'detects the line' do + expect(provider).to be_exists end - context 'with one line matching the after expression' do - before :each do - File.open(@tmpfile, 'w') do |fh| - fh.write("foo1\nfoo = blah\nfoo2\nfoo = baz") - end - end - - it 'inserts the specified line after the line matching the "after" expression' do - provider.create - expect(File.read(@tmpfile).chomp).to eql("foo1\ninserted = line\nfoo = blah\nfoo2\nfoo = baz") - end + end + + context 'when matches line - line exists' do + let(:params) { { match: '^foo' } } + let(:content) { "foo\nbar" } + + it 'detects the line' do + expect(provider).to be_exists end + end + + context 'when matches line - line does not exist' do + let(:params) { { match: '^foo' } } + let(:content) { "foo bar\nbar" } - context 'with multiple lines matching the after expression' do - before :each do - File.open(@tmpfile, 'w') do |fh| - fh.write("foo1\nfoo = blah\nfoo2\nfoo1\nfoo = baz") - end - end - - it 'errors out stating "One or no line must match the pattern"' do - expect { provider.create }.to raise_error(Puppet::Error, /One or no line must match the pattern/) - end - - it 'adds the line after all lines matching the after expression' do - @resource = Puppet::Type::File_line.new( - { - :name => 'foo', - :path => @tmpfile, - :line => 'inserted = line', - :after => '^foo1$', - :multiple => true, - } - ) - @provider = provider_class.new(@resource) - expect(@provider.exists?).to be_nil - @provider.create - expect(File.read(@tmpfile).chomp).to eql("foo1\ninserted = line\nfoo = blah\nfoo2\nfoo1\ninserted = line\nfoo = baz") - end + it 'requests changes' do + expect(provider).not_to be_exists end - context 'with no lines matching the after expression' do - let :content do - "foo3\nfoo = blah\nfoo2\nfoo = baz\n" - end - - before :each do - File.open(@tmpfile, 'w') do |fh| - fh.write(content) - end - end - - it 'appends the specified line to the file' do - provider.create - expect(File.read(@tmpfile)).to eq(content << resource[:line] << "\n") - end + it 'replaces the match' do + provider.create + expect(File.read(tmpfile).chomp).to eq("foo\nbar") end end end - context "when removing" do - before :each do - # TODO: these should be ported over to use the PuppetLabs spec_helper - # file fixtures once the following pull request has been merged: - # https://github.com/puppetlabs/puppetlabs-stdlib/pull/73/files - tmp = Tempfile.new('tmp') - @tmpfile = tmp.path - tmp.close! - @resource = Puppet::Type::File_line.new( - { - :name => 'foo', - :path => @tmpfile, - :line => 'foo', - :ensure => 'absent', - } - ) - @provider = provider_class.new(@resource) + describe 'append_on_no_match' do + let(:params) do + { + append_on_no_match: false, + match: '^foo1$' + } end - it 'should remove the line if it exists' do - File.open(@tmpfile, 'w') do |fh| - fh.write("foo1\nfoo\nfoo2") + + context 'when matching' do + let(:content) { "foo1\nbar" } + + it 'requests changes' do + expect(provider).not_to be_exists end - @provider.destroy - expect(File.read(@tmpfile)).to eql("foo1\nfoo2") - end - it 'should remove the line without touching the last new line' do - File.open(@tmpfile, 'w') do |fh| - fh.write("foo1\nfoo\nfoo2\n") + it 'replaces the match' do + provider.create + expect(File.read(tmpfile).chomp).to eql("foo\nbar") end - @provider.destroy - expect(File.read(@tmpfile)).to eql("foo1\nfoo2\n") end - it 'should remove any occurence of the line' do - File.open(@tmpfile, 'w') do |fh| - fh.write("foo1\nfoo\nfoo2\nfoo\nfoo") + context 'when not matching' do + let(:content) { "foo3\nbar" } + + it 'does not affect the file' do + expect(provider).to be_exists end - @provider.destroy - expect(File.read(@tmpfile)).to eql("foo1\nfoo2\n") end end - context "when removing with a match" do - before :each do - # TODO: these should be ported over to use the PuppetLabs spec_helper - # file fixtures once the following pull request has been merged: - # https://github.com/puppetlabs/puppetlabs-stdlib/pull/73/files - tmp = Tempfile.new('tmp') - @tmpfile = tmp.path - tmp.close! - @resource = Puppet::Type::File_line.new( + describe 'replace_all_matches_not_matching_line' do + context 'when replace is false' do + let(:params) do { - :name => 'foo', - :path => @tmpfile, - :line => 'foo2', - :ensure => 'absent', - :match => 'o$', - :match_for_absence => true, + replace_all_matches_not_matching_line: true, + replace: false } - ) - @provider = provider_class.new(@resource) - end + end - it 'should remove one line if it matches' do - File.open(@tmpfile, 'w') do |fh| - fh.write("foo1\nfoo\nfoo2") + it 'raises an error' do + expect { provider.exists? }.to raise_error(Puppet::Error, %r{replace must be true}) end - @provider.destroy - expect(File.read(@tmpfile)).to eql("foo1\nfoo2") end - it 'should raise an error if more than one line matches' do - File.open(@tmpfile, 'w') do |fh| - fh.write("foo1\nfoo\nfoo2\nfoo\nfoo") + context 'when match matches line - when there are more matches than lines' do + let(:params) do + { + replace_all_matches_not_matching_line: true, + match: '^foo', + multiple: true + } + end + let(:content) { "foo\nfoo bar\nbar\nfoo baz" } + + it 'requests changes' do + expect(provider).not_to be_exists + end + + it 'replaces the matches' do + provider.create + expect(File.read(tmpfile).chomp).to eql("foo\nfoo\nbar\nfoo") end - expect { @provider.destroy }.to raise_error(Puppet::Error, /More than one line/) end - it 'should remove multiple lines if :multiple is true' do - @resource = Puppet::Type::File_line.new( + context 'when match matches line - when there are the same matches and lines' do + let(:params) do { - :name => 'foo', - :path => @tmpfile, - :line => 'foo2', - :ensure => 'absent', - :match => 'o$', - :multiple => true, - :match_for_absence => true, + replace_all_matches_not_matching_line: true, + match: '^foo', + multiple: true } - ) - @provider = provider_class.new(@resource) - File.open(@tmpfile, 'w') do |fh| - fh.write("foo1\nfoo\nfoo2\nfoo\nfoo") end - @provider.destroy - expect(File.read(@tmpfile)).to eql("foo1\nfoo2\n") + let(:content) { "foo\nfoo\nbar" } + + it 'does not request changes' do + expect(provider).to be_exists + end end - it 'should ignore the match if match_for_absense is not specified' do - @resource = Puppet::Type::File_line.new( + context 'when match does not match line - when there are more matches than lines' do + let(:params) do { - :name => 'foo', - :path => @tmpfile, - :line => 'foo2', - :ensure => 'absent', - :match => 'o$', + replace_all_matches_not_matching_line: true, + match: '^bar', + multiple: true } - ) - @provider = provider_class.new(@resource) - File.open(@tmpfile, 'w') do |fh| - fh.write("foo1\nfoo\nfoo2") end - @provider.destroy - expect(File.read(@tmpfile)).to eql("foo1\nfoo\n") + let(:content) { "foo\nfoo bar\nbar\nbar baz" } + + it 'requests changes' do + expect(provider).not_to be_exists + end + + it 'replaces the matches' do + provider.create + expect(File.read(tmpfile).chomp).to eql("foo\nfoo bar\nfoo\nfoo") + end end - it 'should ignore the match if match_for_absense is false' do - @resource = Puppet::Type::File_line.new( + context 'when match does not match line - when there are the same matches and lines' do + let(:params) do { - :name => 'foo', - :path => @tmpfile, - :line => 'foo2', - :ensure => 'absent', - :match => 'o$', - :match_for_absence => false, + replace_all_matches_not_matching_line: true, + match: '^bar', + multiple: true } - ) - @provider = provider_class.new(@resource) - File.open(@tmpfile, 'w') do |fh| - fh.write("foo1\nfoo\nfoo2") end - @provider.destroy - expect(File.read(@tmpfile)).to eql("foo1\nfoo\n") + let(:content) { "foo\nfoo\nbar\nbar baz" } + + it 'requests changes' do + expect(provider).not_to be_exists + end + + it 'replaces the matches' do + provider.create + expect(File.read(tmpfile).chomp).to eql("foo\nfoo\nfoo\nfoo") + end + end + end + + context 'when match does not match line - when there are no matches' do + let(:params) do + { + replace_all_matches_not_matching_line: true, + match: '^bar', + multiple: true + } end + let(:content) { "foo\nfoo bar" } + it 'does not request changes' do + expect(provider).to be_exists + end end + context 'when match does not match line - when there are no matches or lines' do + let(:params) do + { + replace_all_matches_not_matching_line: true, + match: '^bar', + multiple: true + } + end + let(:content) { 'foo bar' } + + it 'requests changes' do + expect(provider).not_to be_exists + end + + it 'appends the line' do + provider.create + expect(File.read(tmpfile).chomp).to eql("foo bar\nfoo") + end + end end diff --git a/spec/unit/puppet/provider/file_line/ruby_use_cases_spec.rb b/spec/unit/puppet/provider/file_line/ruby_use_cases_spec.rb new file mode 100644 index 000000000..b3578a679 --- /dev/null +++ b/spec/unit/puppet/provider/file_line/ruby_use_cases_spec.rb @@ -0,0 +1,137 @@ +# frozen_string_literal: true + +require 'spec_helper' + +provider_class = Puppet::Type.type(:file_line).provider(:ruby) +# Ā These tests fail on windows when run as part of the rake task. Individually they pass +describe provider_class, unless: Puppet::Util::Platform.windows? do + include PuppetlabsSpec::Files + + let :tmpfile do + tmpfilename('file_line_test') + end + let :content do + '' + end + let :params do + {} + end + let :resource do + Puppet::Type::File_line.new({ + name: 'foo', + path: tmpfile, + line: 'foo' + }.merge(params)) + end + let :provider do + provider_class.new(resource) + end + + before :each do + File.write(tmpfile, content) + end + + describe 'customer use cases - no lines' do + describe 'MODULES-5003' do + let(:params) do + { + line: "*\thard\tcore\t0", + match: "^[ \t]*\\*[ \t]+hard[ \t]+core[ \t]+.*", + multiple: true + } + end + let(:content) { "* hard core 90\n* hard core 10\n" } + + it 'requests changes' do + expect(provider).not_to be_exists + end + + it 'replaces the matches' do + provider.create + expect(File.read(tmpfile).chomp).to eq("* hard core 0\n* hard core 0") + end + end + + describe 'MODULES-5003 - one match, one line - just ensure the line exists' do + let(:params) do + { + line: "*\thard\tcore\t0", + match: "^[ \t]*\\*[ \t]+hard[ \t]+core[ \t]+.*", + multiple: true + } + end + let(:content) { "* hard core 90\n* hard core 0\n" } + + it 'does not request changes' do + expect(provider).to be_exists + end + end + + describe 'MODULES-5003 - one match, one line - replace all matches, even when line exists' do + let(:params) do + { + line: "*\thard\tcore\t0", + match: "^[ \t]*\\*[ \t]+hard[ \t]+core[ \t]+.*", + multiple: true + }.merge(replace_all_matches_not_matching_line: true) + end + let(:content) { "* hard core 90\n* hard core 0\n" } + + it 'requests changes' do + expect(provider).not_to be_exists + end + + it 'replaces the matches' do + provider.create + expect(File.read(tmpfile).chomp).to eq("* hard core 0\n* hard core 0") + end + end + + describe 'MODULES-5651 - match, no line' do + let(:params) do + { + line: 'LogLevel=notice', + match: '^#LogLevel$' + } + end + let(:content) { "#LogLevel\nstuff" } + + it 'requests changes' do + expect(provider).not_to be_exists + end + + it 'replaces the match' do + provider.create + expect(File.read(tmpfile).chomp).to eq("LogLevel=notice\nstuff") + end + end + + describe 'MODULES-5651 - match, line' do + let(:params) do + { + line: 'LogLevel=notice', + match: '^#LogLevel$' + } + end + let(:content) { "#Loglevel\nLogLevel=notice\nstuff" } + + it 'does not request changes' do + expect(provider).to be_exists + end + end + + describe 'MODULES-5651 - no match, line' do + let(:params) do + { + line: 'LogLevel=notice', + match: '^#LogLevel$' + } + end + let(:content) { "LogLevel=notice\nstuff" } + + it 'does not request changes' do + expect(provider).to be_exists + end + end + end +end diff --git a/spec/unit/puppet/type/anchor_spec.rb b/spec/unit/puppet/type/anchor_spec.rb old mode 100755 new mode 100644 index c738a272b..9dc4ebd65 --- a/spec/unit/puppet/type/anchor_spec.rb +++ b/spec/unit/puppet/type/anchor_spec.rb @@ -1,11 +1,11 @@ -#!/usr/bin/env ruby +# frozen_string_literal: true require 'spec_helper' -anchor = Puppet::Type.type(:anchor).new(:name => "ntp::begin") +anchor = Puppet::Type.type(:anchor).new(name: 'ntp::begin') describe anchor do - it "should stringify normally" do - expect(anchor.to_s).to eq("Anchor[ntp::begin]") + it 'stringifies normally' do + expect(anchor.to_s).to eq('Anchor[ntp::begin]') end end diff --git a/spec/unit/puppet/type/file_line_spec.rb b/spec/unit/puppet/type/file_line_spec.rb old mode 100755 new mode 100644 index f1430f263..17c4d8c7e --- a/spec/unit/puppet/type/file_line_spec.rb +++ b/spec/unit/puppet/type/file_line_spec.rb @@ -1,71 +1,126 @@ -#! /usr/bin/env ruby -S rspec +# frozen_string_literal: true + require 'spec_helper' require 'tempfile' describe Puppet::Type.type(:file_line) do + let :tmp_path do + if Puppet::Util::Platform.windows? + 'C:\tmp\path' + else + '/tmp/path' + end + end + let :my_path do + if Puppet::Util::Platform.windows? + 'C:\my\path' + else + '/my/path' + end + end let :file_line do - Puppet::Type.type(:file_line).new(:name => 'foo', :line => 'line', :path => '/tmp/path') + Puppet::Type.type(:file_line).new(name: 'foo', line: 'line', path: tmp_path) end - it 'should accept a line and path' do + + it 'accepts a line' do file_line[:line] = 'my_line' expect(file_line[:line]).to eq('my_line') - file_line[:path] = '/my/path' - expect(file_line[:path]).to eq('/my/path') end - it 'should accept a match regex' do + + it 'accepts a path' do + file_line[:path] = my_path + expect(file_line[:path]).to eq(my_path) + end + + it 'accepts a match regex' do file_line[:match] = '^foo.*$' expect(file_line[:match]).to eq('^foo.*$') end - it 'should accept a match regex that does not match the specified line' do + + it 'accepts a match regex that does not match the specified line' do + expect { + Puppet::Type.type(:file_line).new( + name: 'foo', path: my_path, line: 'foo=bar', match: '^bar=blah$', + ) + }.not_to raise_error + end + + it 'accepts a match regex that does match the specified line' do + expect { + Puppet::Type.type(:file_line).new( + name: 'foo', path: my_path, line: 'foo=bar', match: '^\s*foo=.*$', + ) + }.not_to raise_error + end + + it 'accepts utf8 characters' do expect { Puppet::Type.type(:file_line).new( - :name => 'foo', - :path => '/my/path', - :line => 'foo=bar', - :match => '^bar=blah$' - )}.not_to raise_error + name: 'ƒồỗ', path: my_path, line: 'ƒồỗ=ŃŒĆ„Ń', match: '^ŃŒĆ„Ń=βļάħ$', + ) + }.not_to raise_error end - it 'should accept a match regex that does match the specified line' do + + it 'accepts double byte characters' do expect { Puppet::Type.type(:file_line).new( - :name => 'foo', - :path => '/my/path', - :line => 'foo=bar', - :match => '^\s*foo=.*$' - )}.not_to raise_error + name: 'ćƒ•ćƒ¼ćƒćƒ¼', path: my_path, line: '恓恮=恝悌', match: '^恓恮=恂恂$', + ) + }.not_to raise_error end - it 'should accept posix filenames' do - file_line[:path] = '/tmp/path' - expect(file_line[:path]).to eq('/tmp/path') + + it 'accepts posix filenames' do + file_line[:path] = tmp_path + expect(file_line[:path]).to eq(tmp_path) end - it 'should not accept unqualified path' do - expect { file_line[:path] = 'file' }.to raise_error(Puppet::Error, /File paths must be fully qualified/) + + it 'does not accept unqualified path' do + expect { file_line[:path] = 'file' }.to raise_error(Puppet::Error, %r{File paths must be fully qualified}) end - it 'should require that a line is specified' do - expect { Puppet::Type.type(:file_line).new(:name => 'foo', :path => '/tmp/file') }.to raise_error(Puppet::Error, /Both line and path are required attributes/) + + it 'requires that a line is specified' do + expect { Puppet::Type.type(:file_line).new(name: 'foo', path: tmp_path) }.to raise_error(Puppet::Error, %r{line is a required attribute}) end - it 'should require that a file is specified' do - expect { Puppet::Type.type(:file_line).new(:name => 'foo', :line => 'path') }.to raise_error(Puppet::Error, /Both line and path are required attributes/) + + it 'does not require that a line is specified when matching for absence' do + expect { Puppet::Type.type(:file_line).new(name: 'foo', path: tmp_path, ensure: :absent, match_for_absence: :true, match: 'match') }.not_to raise_error + end + + it 'although if a line is specified anyway when matching for absence it still works and the line is silently ignored' do + expect { Puppet::Type.type(:file_line).new(name: 'foo', path: tmp_path, line: 'i_am_irrelevant', ensure: :absent, match_for_absence: :true, match: 'match') }.not_to raise_error end - it 'should default to ensure => present' do + + it 'requires that a file is specified' do + expect { Puppet::Type.type(:file_line).new(name: 'foo', line: 'path') }.to raise_error(Puppet::Error, %r{path is a required attribute}) + end + + it 'defaults to ensure => present' do expect(file_line[:ensure]).to eq :present end - it 'should default to replace => true' do + + it 'defaults to replace => true' do expect(file_line[:replace]).to eq :true end - it "should autorequire the file it manages" do + it 'defaults to encoding => UTF-8' do + expect(file_line[:encoding]).to eq 'UTF-8' + end + + it 'accepts encoding => iso-8859-1' do + expect { Puppet::Type.type(:file_line).new(name: 'foo', path: tmp_path, ensure: :present, encoding: 'iso-8859-1', line: 'bar') }.not_to raise_error + end + + it 'autorequires the file it manages' do catalog = Puppet::Resource::Catalog.new - file = Puppet::Type.type(:file).new(:name => "/tmp/path") + file = Puppet::Type.type(:file).new(name: tmp_path) catalog.add_resource file catalog.add_resource file_line - relationship = file_line.autorequire.find do |rel| - (rel.source.to_s == "File[/tmp/path]") and (rel.target.to_s == file_line.to_s) + (rel.source.to_s == "File[#{tmp_path}]") && (rel.target.to_s == file_line.to_s) end expect(relationship).to be_a Puppet::Relationship end - it "should not autorequire the file it manages if it is not managed" do + it 'does not autorequire the file it manages if it is not managed' do catalog = Puppet::Resource::Catalog.new catalog.add_resource file_line expect(file_line.autorequire).to be_empty diff --git a/types/absolutepath.pp b/types/absolutepath.pp new file mode 100644 index 000000000..906bd6960 --- /dev/null +++ b/types/absolutepath.pp @@ -0,0 +1,2 @@ +# @summary A strict absolutepath type +type Stdlib::Absolutepath = Variant[Stdlib::Windowspath, Stdlib::Unixpath] diff --git a/types/base32.pp b/types/base32.pp new file mode 100644 index 000000000..9c8574d82 --- /dev/null +++ b/types/base32.pp @@ -0,0 +1,2 @@ +# @summary Type to match base32 String +type Stdlib::Base32 = Pattern[/\A[a-z2-7]+={,6}\z/, /\A[A-Z2-7]+={,6}\z/] diff --git a/types/base64.pp b/types/base64.pp new file mode 100644 index 000000000..3fc198f6c --- /dev/null +++ b/types/base64.pp @@ -0,0 +1,2 @@ +# @summary Type to match base64 String +type Stdlib::Base64 = Pattern[/\A[a-zA-Z0-9\/\+]+={,2}\z/] diff --git a/types/createresources.pp b/types/createresources.pp new file mode 100644 index 000000000..f78443cde --- /dev/null +++ b/types/createresources.pp @@ -0,0 +1,17 @@ +# @summary A type description used for the create_resources function +# +# @example As a class parameter +# class myclass ( +# Stdlib::CreateResources $myresources = {}, +# ) { +# # Using create_resources +# create_resources('myresource', $myresources) +# +# # Using iteration +# $myresources.each |$myresource_name, $myresource_attrs| { +# myresource { $myresource_name: +# * => $myresource_attrs, +# } +# } +# } +type Stdlib::CreateResources = Hash[String[1], Hash[String[1], Any]] diff --git a/types/datasize.pp b/types/datasize.pp new file mode 100644 index 000000000..6892c0171 --- /dev/null +++ b/types/datasize.pp @@ -0,0 +1,2 @@ +# @summary Validate the size of data +type Stdlib::Datasize = Pattern[/^\d+(?i:[kmgt]b?|b)$/] diff --git a/types/dns/zone.pp b/types/dns/zone.pp new file mode 100644 index 000000000..bdd3220db --- /dev/null +++ b/types/dns/zone.pp @@ -0,0 +1,2 @@ +# @summary Validate a DNS zone name +type Stdlib::Dns::Zone = Pattern[/\A((([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])\.)+|\.)\z/] diff --git a/types/email.pp b/types/email.pp new file mode 100644 index 000000000..6103edb64 --- /dev/null +++ b/types/email.pp @@ -0,0 +1,5 @@ +# @summary Validate an e-mail address +# https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address +# lint:ignore:140chars +type Stdlib::Email = Pattern[/\A[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\z/] +# lint:endignore diff --git a/types/ensure/file.pp b/types/ensure/file.pp new file mode 100644 index 000000000..6d5928715 --- /dev/null +++ b/types/ensure/file.pp @@ -0,0 +1,2 @@ +# @summary Validate the value of the ensure parameter for a file +type Stdlib::Ensure::File = Enum['present', 'file', 'directory', 'link', 'absent'] diff --git a/types/ensure/file/directory.pp b/types/ensure/file/directory.pp new file mode 100644 index 000000000..1c4d2686d --- /dev/null +++ b/types/ensure/file/directory.pp @@ -0,0 +1,2 @@ +# Validate the ensure parameter of a "directory" file resource +type Stdlib::Ensure::File::Directory = Enum['directory', 'absent'] diff --git a/types/ensure/file/file.pp b/types/ensure/file/file.pp new file mode 100644 index 000000000..d35deafe5 --- /dev/null +++ b/types/ensure/file/file.pp @@ -0,0 +1,2 @@ +# Validate the ensure parameter of a "file" file resource +type Stdlib::Ensure::File::File = Enum['file', 'absent'] diff --git a/types/ensure/file/link.pp b/types/ensure/file/link.pp new file mode 100644 index 000000000..bc1276dbe --- /dev/null +++ b/types/ensure/file/link.pp @@ -0,0 +1,2 @@ +# Validate the ensure parameter of a "link" file resource +type Stdlib::Ensure::File::Link = Enum['link', 'absent'] diff --git a/types/ensure/package.pp b/types/ensure/package.pp new file mode 100644 index 000000000..3f6ad47c7 --- /dev/null +++ b/types/ensure/package.pp @@ -0,0 +1,2 @@ +# @summary Validate the value of the ensure parameter for a package +type Stdlib::Ensure::Package = Variant[Enum['present', 'absent', 'purged', 'disabled', 'installed', 'latest'], String[1]] diff --git a/types/ensure/service.pp b/types/ensure/service.pp new file mode 100644 index 000000000..af9c513a3 --- /dev/null +++ b/types/ensure/service.pp @@ -0,0 +1,2 @@ +# @summary Validate the value of the ensure parameter of a service resource +type Stdlib::Ensure::Service = Enum['stopped', 'running'] diff --git a/types/filemode.pp b/types/filemode.pp new file mode 100644 index 000000000..2974a05f2 --- /dev/null +++ b/types/filemode.pp @@ -0,0 +1,5 @@ +# @summary Validate a file mode +# See `man chmod.1` for the regular expression for symbolic mode +# lint:ignore:140chars +type Stdlib::Filemode = Pattern[/\A(([0-7]{1,4})|(([ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=][0-7]+)(,([ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=][0-7]+))*))\z/] +# lint:endignore diff --git a/types/filesource.pp b/types/filesource.pp new file mode 100644 index 000000000..9c12d9ed2 --- /dev/null +++ b/types/filesource.pp @@ -0,0 +1,9 @@ +# @summary Validate the source parameter on file types +type Stdlib::Filesource = Variant[ + Stdlib::Absolutepath, + Stdlib::HTTPUrl, + Pattern[ + /\Afile:\/\/\/([^\n\/\0]+(\/)?)+\z/, + /\Apuppet:\/\/(([\w-]+\.?)+)?\/([^\n\/\0]+(\/)?)+\z/, + ], +] diff --git a/types/fqdn.pp b/types/fqdn.pp new file mode 100644 index 000000000..c2fbe09ae --- /dev/null +++ b/types/fqdn.pp @@ -0,0 +1,2 @@ +# @summary Validate a Fully Qualified Domain Name +type Stdlib::Fqdn = Pattern[/\A(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])\z/] diff --git a/types/host.pp b/types/host.pp new file mode 100644 index 000000000..46f349bac --- /dev/null +++ b/types/host.pp @@ -0,0 +1,2 @@ +# @summary Validate a host (FQDN or IP address) +type Stdlib::Host = Variant[Stdlib::Fqdn, Stdlib::IP::Address] diff --git a/types/http/method.pp b/types/http/method.pp new file mode 100644 index 000000000..3b50ff0b8 --- /dev/null +++ b/types/http/method.pp @@ -0,0 +1,43 @@ +# @summary Valid HTTP method verbs +# @see https://www.iana.org/assignments/http-methods/http-methods.xhtml +type Stdlib::Http::Method = Enum[ + 'ACL', + 'BASELINE-CONTROL', + 'BIND', + 'CHECKIN', + 'CHECKOUT', + 'CONNECT', + 'COPY', + 'DELETE', + 'GET', + 'HEAD', + 'LABEL', + 'LINK', + 'LOCK', + 'MERGE', + 'MKACTIVITY', + 'MKCALENDAR', + 'MKCOL', + 'MKREDIRECTREF', + 'MKWORKSPACE', + 'MOVE', + 'OPTIONS', + 'ORDERPATCH', + 'PATCH', + 'POST', + 'PRI', + 'PROPFIND', + 'PROPPATCH', + 'PUT', + 'REBIND', + 'REPORT', + 'SEARCH', + 'TRACE', + 'UNBIND', + 'UNCHECKOUT', + 'UNLINK', + 'UNLOCK', + 'UPDATE', + 'UPDATEREDIRECTREF', + 'VERSION-CONTROL', +] diff --git a/types/http/status.pp b/types/http/status.pp new file mode 100644 index 000000000..08a23fdc7 --- /dev/null +++ b/types/http/status.pp @@ -0,0 +1,3 @@ +# @summary A valid HTTP status code per RFC9110 +# @see https://httpwg.org/specs/rfc9110.html#overview.of.status.codes +type Stdlib::Http::Status = Integer[100, 599] diff --git a/types/httpstatus.pp b/types/httpstatus.pp new file mode 100644 index 000000000..1a73221eb --- /dev/null +++ b/types/httpstatus.pp @@ -0,0 +1,4 @@ +# @summary Validate a HTTP status code +# @deprecated Use Stdlib::Http::Status +# @see Stdlib::Http::Status +type Stdlib::HttpStatus = Stdlib::Http::Status diff --git a/types/httpsurl.pp b/types/httpsurl.pp new file mode 100644 index 000000000..1c878c3ba --- /dev/null +++ b/types/httpsurl.pp @@ -0,0 +1,2 @@ +# @summary Validate a HTTPS URL +type Stdlib::HTTPSUrl = Pattern[/(?i:\Ahttps:\/\/.*\z)/] diff --git a/types/httpurl.pp b/types/httpurl.pp new file mode 100644 index 000000000..2cf0bd970 --- /dev/null +++ b/types/httpurl.pp @@ -0,0 +1,2 @@ +# @summary Validate a HTTP(S) URL +type Stdlib::HTTPUrl = Pattern[/(?i:\Ahttps?:\/\/.*\z)/] diff --git a/types/ip/address.pp b/types/ip/address.pp new file mode 100644 index 000000000..b73d3a1f5 --- /dev/null +++ b/types/ip/address.pp @@ -0,0 +1,5 @@ +# @summary Validate an IP address +type Stdlib::IP::Address = Variant[ + Stdlib::IP::Address::V4, + Stdlib::IP::Address::V6, +] diff --git a/types/ip/address/cidr.pp b/types/ip/address/cidr.pp new file mode 100644 index 000000000..9894d26eb --- /dev/null +++ b/types/ip/address/cidr.pp @@ -0,0 +1,5 @@ +# Validate an IP address with subnet +type Stdlib::IP::Address::CIDR = Variant[ + Stdlib::IP::Address::V4::CIDR, + Stdlib::IP::Address::V6::CIDR, +] diff --git a/types/ip/address/nosubnet.pp b/types/ip/address/nosubnet.pp new file mode 100644 index 000000000..2f24b5ed3 --- /dev/null +++ b/types/ip/address/nosubnet.pp @@ -0,0 +1,5 @@ +# Validate an IP address without subnet +type Stdlib::IP::Address::Nosubnet = Variant[ + Stdlib::IP::Address::V4::Nosubnet, + Stdlib::IP::Address::V6::Nosubnet, +] diff --git a/types/ip/address/v4.pp b/types/ip/address/v4.pp new file mode 100644 index 000000000..33f8f6fce --- /dev/null +++ b/types/ip/address/v4.pp @@ -0,0 +1,5 @@ +# Validate an IPv4 address +type Stdlib::IP::Address::V4 = Variant[ + Stdlib::IP::Address::V4::CIDR, + Stdlib::IP::Address::V4::Nosubnet, +] diff --git a/types/ip/address/v4/cidr.pp b/types/ip/address/v4/cidr.pp new file mode 100644 index 000000000..f8befdf43 --- /dev/null +++ b/types/ip/address/v4/cidr.pp @@ -0,0 +1,3 @@ +# lint:ignore:140chars +type Stdlib::IP::Address::V4::CIDR = Pattern[/\A([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}\/([0-9]|[12][0-9]|3[0-2])\z/] +# lint:endignore diff --git a/types/ip/address/v4/nosubnet.pp b/types/ip/address/v4/nosubnet.pp new file mode 100644 index 000000000..daa798fe2 --- /dev/null +++ b/types/ip/address/v4/nosubnet.pp @@ -0,0 +1,3 @@ +# lint:ignore:140chars +type Stdlib::IP::Address::V4::Nosubnet = Pattern[/\A([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}\z/] +# lint:endignore diff --git a/types/ip/address/v6.pp b/types/ip/address/v6.pp new file mode 100644 index 000000000..e8ca7eb31 --- /dev/null +++ b/types/ip/address/v6.pp @@ -0,0 +1,7 @@ +# Validate an IPv6 address +type Stdlib::IP::Address::V6 = Variant[ + Stdlib::IP::Address::V6::Full, + Stdlib::IP::Address::V6::Compressed, + Stdlib::IP::Address::V6::Alternative, + Stdlib::IP::Address::V6::Nosubnet, +] diff --git a/types/ip/address/v6/alternative.pp b/types/ip/address/v6/alternative.pp new file mode 100644 index 000000000..5900fe49f --- /dev/null +++ b/types/ip/address/v6/alternative.pp @@ -0,0 +1,11 @@ +# lint:ignore:140chars +type Stdlib::IP::Address::V6::Alternative = Pattern[ + /\A([[:xdigit:]]{1,4}:){6}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/, + /\A([[:xdigit:]]{1,4}:){5}:([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/, + /\A([[:xdigit:]]{1,4}:){4}(:[[:xdigit:]]{1,4}){0,1}:([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/, + /\A([[:xdigit:]]{1,4}:){3}(:[[:xdigit:]]{1,4}){0,2}:([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/, + /\A([[:xdigit:]]{1,4}:){2}(:[[:xdigit:]]{1,4}){0,3}:([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/, + /\A([[:xdigit:]]{1,4}:){1}(:[[:xdigit:]]{1,4}){0,4}:([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/, + /\A:(:[[:xdigit:]]{1,4}){0,5}:([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/, +] +# lint:endignore diff --git a/types/ip/address/v6/cidr.pp b/types/ip/address/v6/cidr.pp new file mode 100644 index 000000000..9fce3ba5e --- /dev/null +++ b/types/ip/address/v6/cidr.pp @@ -0,0 +1,3 @@ +# lint:ignore:140chars +type Stdlib::IP::Address::V6::CIDR = Pattern[/\A((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*\/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])?\z/] +# lint:endignore diff --git a/types/ip/address/v6/compressed.pp b/types/ip/address/v6/compressed.pp new file mode 100644 index 000000000..44f08df63 --- /dev/null +++ b/types/ip/address/v6/compressed.pp @@ -0,0 +1,11 @@ +# Validate a compressed IPv6 address +type Stdlib::IP::Address::V6::Compressed = Pattern[ + /\A:(:|(:[[:xdigit:]]{1,4}){1,7})(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/, + /\A([[:xdigit:]]{1,4}:){1}(:|(:[[:xdigit:]]{1,4}){1,6})(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/, + /\A([[:xdigit:]]{1,4}:){2}(:|(:[[:xdigit:]]{1,4}){1,5})(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/, + /\A([[:xdigit:]]{1,4}:){3}(:|(:[[:xdigit:]]{1,4}){1,4})(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/, + /\A([[:xdigit:]]{1,4}:){4}(:|(:[[:xdigit:]]{1,4}){1,3})(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/, + /\A([[:xdigit:]]{1,4}:){5}(:|(:[[:xdigit:]]{1,4}){1,2})(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/, + /\A([[:xdigit:]]{1,4}:){6}(:|(:[[:xdigit:]]{1,4}){1,1})(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/, + /\A([[:xdigit:]]{1,4}:){7}:(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/, +] diff --git a/types/ip/address/v6/full.pp b/types/ip/address/v6/full.pp new file mode 100644 index 000000000..f0c23212a --- /dev/null +++ b/types/ip/address/v6/full.pp @@ -0,0 +1,2 @@ +# Validate a full IPv6 address +type Stdlib::IP::Address::V6::Full = Pattern[/\A[[:xdigit:]]{1,4}(:[[:xdigit:]]{1,4}){7}(\/(1([01][0-9]|2[0-8])|[1-9][0-9]|[0-9]))?\z/] diff --git a/types/ip/address/v6/nosubnet.pp b/types/ip/address/v6/nosubnet.pp new file mode 100644 index 000000000..f2345c1b4 --- /dev/null +++ b/types/ip/address/v6/nosubnet.pp @@ -0,0 +1,6 @@ +# Validate an IPv6 address without subnet +type Stdlib::IP::Address::V6::Nosubnet = Variant[ + Stdlib::IP::Address::V6::Nosubnet::Full, + Stdlib::IP::Address::V6::Nosubnet::Compressed, + Stdlib::IP::Address::V6::Nosubnet::Alternative, +] diff --git a/types/ip/address/v6/nosubnet/alternative.pp b/types/ip/address/v6/nosubnet/alternative.pp new file mode 100644 index 000000000..376da0ac9 --- /dev/null +++ b/types/ip/address/v6/nosubnet/alternative.pp @@ -0,0 +1,11 @@ +# lint:ignore:140chars +type Stdlib::IP::Address::V6::Nosubnet::Alternative = Pattern[ + /\A([[:xdigit:]]{1,4}:){6}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}\z/, + /\A([[:xdigit:]]{1,4}:){5}:([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}\z/, + /\A([[:xdigit:]]{1,4}:){4}(:[[:xdigit:]]{1,4}){0,1}:([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}\z/, + /\A([[:xdigit:]]{1,4}:){3}(:[[:xdigit:]]{1,4}){0,2}:([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}\z/, + /\A([[:xdigit:]]{1,4}:){2}(:[[:xdigit:]]{1,4}){0,3}:([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}\z/, + /\A([[:xdigit:]]{1,4}:){1}(:[[:xdigit:]]{1,4}){0,4}:([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}\z/, + /\A:(:[[:xdigit:]]{1,4}){0,5}:([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}\z/, +] +# lint:endignore diff --git a/types/ip/address/v6/nosubnet/compressed.pp b/types/ip/address/v6/nosubnet/compressed.pp new file mode 100644 index 000000000..01b1f96b0 --- /dev/null +++ b/types/ip/address/v6/nosubnet/compressed.pp @@ -0,0 +1,11 @@ +# Validate compressed IPv6 address without subnet +type Stdlib::IP::Address::V6::Nosubnet::Compressed = Pattern[ + /\A:(:|(:[[:xdigit:]]{1,4}){1,7})\z/, + /\A([[:xdigit:]]{1,4}:){1}(:|(:[[:xdigit:]]{1,4}){1,6})\z/, + /\A([[:xdigit:]]{1,4}:){2}(:|(:[[:xdigit:]]{1,4}){1,5})\z/, + /\A([[:xdigit:]]{1,4}:){3}(:|(:[[:xdigit:]]{1,4}){1,4})\z/, + /\A([[:xdigit:]]{1,4}:){4}(:|(:[[:xdigit:]]{1,4}){1,3})\z/, + /\A([[:xdigit:]]{1,4}:){5}(:|(:[[:xdigit:]]{1,4}){1,2})\z/, + /\A([[:xdigit:]]{1,4}:){6}(:|(:[[:xdigit:]]{1,4}){1,1})\z/, + /\A([[:xdigit:]]{1,4}:){7}:\z/, +] diff --git a/types/ip/address/v6/nosubnet/full.pp b/types/ip/address/v6/nosubnet/full.pp new file mode 100644 index 000000000..4bfedcdaf --- /dev/null +++ b/types/ip/address/v6/nosubnet/full.pp @@ -0,0 +1,2 @@ +# Validate full IPv6 address without subnet +type Stdlib::IP::Address::V6::Nosubnet::Full = Pattern[/\A[[:xdigit:]]{1,4}(:[[:xdigit:]]{1,4}){7}\z/] diff --git a/types/mac.pp b/types/mac.pp new file mode 100644 index 000000000..283c861c9 --- /dev/null +++ b/types/mac.pp @@ -0,0 +1,5 @@ +# @summary A type for a MAC address +type Stdlib::MAC = Pattern[ + /\A([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})\z/, + /\A([0-9A-Fa-f]{2}[:-]){19}([0-9A-Fa-f]{2})\z/, +] diff --git a/types/objectstore.pp b/types/objectstore.pp new file mode 100644 index 000000000..69c344b08 --- /dev/null +++ b/types/objectstore.pp @@ -0,0 +1,5 @@ +# @summary Validate an ObjectStore +type Stdlib::ObjectStore = Variant[ + Stdlib::ObjectStore::GSUri, + Stdlib::ObjectStore::S3Uri, +] diff --git a/types/objectstore/gsuri.pp b/types/objectstore/gsuri.pp new file mode 100644 index 000000000..28f4f3b52 --- /dev/null +++ b/types/objectstore/gsuri.pp @@ -0,0 +1,2 @@ +# @summary Validate a Google Cloud object store URI +type Stdlib::ObjectStore::GSUri = Pattern[/\Ags:\/\/.*\z/] diff --git a/types/objectstore/s3uri.pp b/types/objectstore/s3uri.pp new file mode 100644 index 000000000..eb03b3040 --- /dev/null +++ b/types/objectstore/s3uri.pp @@ -0,0 +1,2 @@ +# @summary Validate an Amazon Web Services S3 object store URI +type Stdlib::ObjectStore::S3Uri = Pattern[/\As3:\/\/.*\z/] diff --git a/types/port.pp b/types/port.pp new file mode 100644 index 000000000..eef4590a0 --- /dev/null +++ b/types/port.pp @@ -0,0 +1,2 @@ +# @summary Validate a port number +type Stdlib::Port = Integer[0, 65535] diff --git a/types/port/dynamic.pp b/types/port/dynamic.pp new file mode 100644 index 000000000..743261f0f --- /dev/null +++ b/types/port/dynamic.pp @@ -0,0 +1,2 @@ +# @summary Validate a dynamic port number +type Stdlib::Port::Dynamic = Integer[49152, 65535] diff --git a/types/port/ephemeral.pp b/types/port/ephemeral.pp new file mode 100644 index 000000000..2d3ed84c2 --- /dev/null +++ b/types/port/ephemeral.pp @@ -0,0 +1,2 @@ +# @summary Validate an ephemeral port number +type Stdlib::Port::Ephemeral = Stdlib::Port::Dynamic diff --git a/types/port/privileged.pp b/types/port/privileged.pp new file mode 100644 index 000000000..c00784c6a --- /dev/null +++ b/types/port/privileged.pp @@ -0,0 +1,2 @@ +# @summary Validate a priviliged port number +type Stdlib::Port::Privileged = Integer[1, 1023] diff --git a/types/port/registered.pp b/types/port/registered.pp new file mode 100644 index 000000000..17ce92117 --- /dev/null +++ b/types/port/registered.pp @@ -0,0 +1,2 @@ +# @summary Validate a registered port number +type Stdlib::Port::Registered = Stdlib::Port::User diff --git a/types/port/unprivileged.pp b/types/port/unprivileged.pp new file mode 100644 index 000000000..01b7433ad --- /dev/null +++ b/types/port/unprivileged.pp @@ -0,0 +1,2 @@ +# @summary Validate an unprivileged port number +type Stdlib::Port::Unprivileged = Integer[1024, 65535] diff --git a/types/port/user.pp b/types/port/user.pp new file mode 100644 index 000000000..1cc626ad5 --- /dev/null +++ b/types/port/user.pp @@ -0,0 +1,2 @@ +# @summary Validate a port number usable by a user +type Stdlib::Port::User = Integer[1024, 49151] diff --git a/types/syslogfacility.pp b/types/syslogfacility.pp new file mode 100644 index 000000000..733ba7601 --- /dev/null +++ b/types/syslogfacility.pp @@ -0,0 +1,27 @@ +# @summary Validate a syslog facility +type Stdlib::Syslogfacility = Enum[ + 'kern', + 'user', + 'mail', + 'daemon', + 'auth', + 'syslog', + 'lpr', + 'news', + 'uucp', + 'cron', + 'authpriv', + 'ftp', + 'ntp', + 'security', + 'console', + 'solaris-cron', + 'local0', + 'local1', + 'local2', + 'local3', + 'local4', + 'local5', + 'local6', + 'local7', +] diff --git a/types/unixpath.pp b/types/unixpath.pp new file mode 100644 index 000000000..e610a107c --- /dev/null +++ b/types/unixpath.pp @@ -0,0 +1,3 @@ +# @summary Validate a UNIX path +# this regex rejects any path component that does not start with "/" or is NUL +type Stdlib::Unixpath = Pattern[/\A\/([^\n\/\0]+\/*)*\z/] diff --git a/types/windowspath.pp b/types/windowspath.pp new file mode 100644 index 000000000..6943cf614 --- /dev/null +++ b/types/windowspath.pp @@ -0,0 +1,2 @@ +# @summary Validate a Windows path +type Stdlib::Windowspath = Pattern[/\A(([a-zA-Z]:[\\\/])|([\\\/][\\\/][^\\\/]+[\\\/][^\\\/]+)|([\\\/][\\\/]\?[\\\/][^\\\/]+)).*\z/] diff --git a/types/yes_no.pp b/types/yes_no.pp new file mode 100644 index 000000000..2545cbc26 --- /dev/null +++ b/types/yes_no.pp @@ -0,0 +1,2 @@ +# @summary Validate a yes / no value +type Stdlib::Yes_no = Pattern[/\A(?i:(yes|no))\z/]