diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 0000000..cacadf2 --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,3 @@ +# Vox Pupuli Security Policy + +Our vulnerabilities reporting process is at https://voxpupuli.org/security/ diff --git a/.msync.yml b/.msync.yml index 8864fc0..4c7999c 100644 --- a/.msync.yml +++ b/.msync.yml @@ -1 +1 @@ -modulesync_config_version: '2.12.0' +modulesync_config_version: '3.0.0' diff --git a/.rubocop.yml b/.rubocop.yml index c2ebc88..0dd998a 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,546 +1,549 @@ require: rubocop-rspec AllCops: # Puppet Server 5 defaults to jruby 1.7 so TargetRubyVersion must stay at 1.9 until we drop support for puppet 5 TargetRubyVersion: 1.9 Include: - ./**/*.rb Exclude: - files/**/* - vendor/**/* - .vendor/**/* - pkg/**/* - spec/fixtures/**/* - Gemfile - Rakefile - Guardfile - Vagrantfile Lint/ConditionPosition: Enabled: True Lint/ElseLayout: Enabled: True Lint/UnreachableCode: Enabled: True Lint/UselessComparison: Enabled: True Lint/EnsureReturn: Enabled: True Lint/HandleExceptions: Enabled: True Lint/LiteralInCondition: Enabled: True Lint/ShadowingOuterLocalVariable: Enabled: True Lint/LiteralInInterpolation: Enabled: True Style/HashSyntax: Enabled: True Style/RedundantReturn: Enabled: True Layout/EndOfLine: Enabled: False Lint/AmbiguousOperator: Enabled: True Lint/AssignmentInCondition: Enabled: True Layout/SpaceBeforeComment: Enabled: True Style/AndOr: Enabled: True Style/RedundantSelf: Enabled: True Metrics/BlockLength: Enabled: False # Method length is not necessarily an indicator of code quality Metrics/MethodLength: Enabled: False # Module length is not necessarily an indicator of code quality Metrics/ModuleLength: Enabled: False Style/WhileUntilModifier: Enabled: True Lint/AmbiguousRegexpLiteral: Enabled: True Security/Eval: Enabled: True Lint/BlockAlignment: Enabled: True Lint/DefEndAlignment: Enabled: True Lint/EndAlignment: Enabled: True Lint/DeprecatedClassMethods: Enabled: True Lint/Loop: Enabled: True Lint/ParenthesesAsGroupedExpression: Enabled: True Lint/RescueException: Enabled: True Lint/StringConversionInInterpolation: Enabled: True Lint/UnusedBlockArgument: Enabled: True Lint/UnusedMethodArgument: Enabled: True Lint/UselessAccessModifier: Enabled: True Lint/UselessAssignment: Enabled: True Lint/Void: Enabled: True Layout/AccessModifierIndentation: Enabled: True Style/AccessorMethodName: Enabled: True Style/Alias: Enabled: True Layout/AlignArray: Enabled: True Layout/AlignHash: Enabled: True Layout/AlignParameters: Enabled: True Metrics/BlockNesting: Enabled: True Style/AsciiComments: Enabled: True Style/Attr: Enabled: True Style/BracesAroundHashParameters: - Enabled: True + Enabled: False Style/CaseEquality: Enabled: True Layout/CaseIndentation: Enabled: True Style/CharacterLiteral: Enabled: True Style/ClassAndModuleCamelCase: Enabled: True Style/ClassAndModuleChildren: Enabled: False Style/ClassCheck: Enabled: True # Class length is not necessarily an indicator of code quality Metrics/ClassLength: Enabled: False Style/ClassMethods: Enabled: True Style/ClassVars: Enabled: True Style/WhenThen: Enabled: True Style/WordArray: Enabled: True Style/UnneededPercentQ: Enabled: True Layout/Tab: Enabled: True Layout/SpaceBeforeSemicolon: Enabled: True Layout/TrailingBlankLines: Enabled: True Layout/SpaceInsideBlockBraces: Enabled: True Layout/SpaceInsideBrackets: Enabled: True Layout/SpaceInsideHashLiteralBraces: Enabled: True Layout/SpaceInsideParens: Enabled: True Layout/LeadingCommentSpace: Enabled: True Layout/SpaceBeforeFirstArg: Enabled: True Layout/SpaceAfterColon: Enabled: True Layout/SpaceAfterComma: Enabled: True Layout/SpaceAfterMethodName: Enabled: True Layout/SpaceAfterNot: Enabled: True Layout/SpaceAfterSemicolon: Enabled: True Layout/SpaceAroundEqualsInParameterDefault: Enabled: True Layout/SpaceAroundOperators: Enabled: True Layout/SpaceBeforeBlockBraces: Enabled: True Layout/SpaceBeforeComma: Enabled: True Style/CollectionMethods: Enabled: True Layout/CommentIndentation: Enabled: True Style/ColonMethodCall: Enabled: True Style/CommentAnnotation: Enabled: True # 'Complexity' is very relative Metrics/CyclomaticComplexity: Enabled: False Style/ConstantName: Enabled: True Style/Documentation: Enabled: False Style/DefWithParentheses: Enabled: True Style/PreferredHashMethods: Enabled: True Layout/DotPosition: EnforcedStyle: trailing Style/DoubleNegation: Enabled: True Style/EachWithObject: Enabled: True Layout/EmptyLineBetweenDefs: Enabled: True Layout/IndentArray: Enabled: True Layout/IndentHash: Enabled: True Layout/IndentationConsistency: Enabled: True Layout/IndentationWidth: Enabled: True Layout/EmptyLines: Enabled: True Layout/EmptyLinesAroundAccessModifier: Enabled: True Style/EmptyLiteral: Enabled: True # Configuration parameters: AllowURI, URISchemes. Metrics/LineLength: Enabled: False Style/MethodCallWithoutArgsParentheses: Enabled: True Style/MethodDefParentheses: Enabled: True Style/LineEndConcatenation: Enabled: True Layout/TrailingWhitespace: Enabled: True Style/StringLiterals: Enabled: True Style/TrailingCommaInArguments: Enabled: True Style/TrailingCommaInLiteral: Enabled: True Style/GlobalVars: Enabled: True Style/GuardClause: Enabled: True Style/IfUnlessModifier: Enabled: True Style/MultilineIfThen: Enabled: True Style/NegatedIf: Enabled: True Style/NegatedWhile: Enabled: True Style/Next: Enabled: True Style/SingleLineBlockParams: Enabled: True Style/SingleLineMethods: Enabled: True Style/SpecialGlobalVars: Enabled: True Style/TrivialAccessors: Enabled: True Style/UnlessElse: Enabled: True Style/VariableInterpolation: Enabled: True Style/VariableName: Enabled: True Style/WhileUntilDo: Enabled: True Style/EvenOdd: Enabled: True Style/FileName: Enabled: True Style/For: Enabled: True Style/Lambda: Enabled: True Style/MethodName: Enabled: True Style/MultilineTernaryOperator: Enabled: True Style/NestedTernaryOperator: Enabled: True Style/NilComparison: Enabled: True Style/FormatString: Enabled: True Style/MultilineBlockChain: Enabled: True Style/Semicolon: Enabled: True Style/SignalException: Enabled: True Style/NonNilCheck: Enabled: True Style/Not: Enabled: True Style/NumericLiterals: Enabled: True Style/OneLineConditional: Enabled: True Style/OpMethod: Enabled: True Style/ParenthesesAroundCondition: Enabled: True Style/PercentLiteralDelimiters: Enabled: True Style/PerlBackrefs: Enabled: True Style/PredicateName: Enabled: True Style/RedundantException: Enabled: True Style/SelfAssignment: Enabled: True Style/Proc: Enabled: True Style/RaiseArgs: Enabled: True Style/RedundantBegin: Enabled: True Style/RescueModifier: Enabled: True # based on https://github.com/voxpupuli/modulesync_config/issues/168 Style/RegexpLiteral: EnforcedStyle: percent_r Enabled: True Lint/UnderscorePrefixedVariableName: Enabled: True Metrics/ParameterLists: Enabled: False Lint/RequireParentheses: Enabled: True Style/ModuleFunction: Enabled: True Lint/Debugger: Enabled: True Style/IfWithSemicolon: Enabled: True Style/Encoding: Enabled: True Style/BlockDelimiters: Enabled: True Layout/MultilineBlockLayout: Enabled: True # 'Complexity' is very relative Metrics/AbcSize: Enabled: False # 'Complexity' is very relative Metrics/PerceivedComplexity: Enabled: False Lint/UselessAssignment: Enabled: True Layout/ClosingParenthesisIndentation: Enabled: True # RSpec RSpec/BeforeAfterAll: Exclude: - spec/acceptance/**/* # We don't use rspec in this way RSpec/DescribeClass: Enabled: False # Example length is not necessarily an indicator of code quality RSpec/ExampleLength: Enabled: False RSpec/NamedSubject: Enabled: False # disabled for now since they cause a lot of issues # these issues aren't easy to fix RSpec/RepeatedDescription: Enabled: False RSpec/NestedGroups: Enabled: False +RSpec/MultipleExpectations: + Enabled: false + # this is broken on ruby1.9 Layout/IndentHeredoc: Enabled: False # disable Yaml safe_load. This is needed to support ruby2.0.0 development envs Security/YAMLLoad: Enabled: false # This affects hiera interpolation, as well as some configs that we push. Style/FormatStringToken: Enabled: false # This is useful, but sometimes a little too picky about where unit tests files # are located. RSpec/FilePath: Enabled: false diff --git a/.travis.yml b/.travis.yml index dff2f17..c380857 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,47 +1,48 @@ --- +os: linux dist: bionic language: ruby cache: bundler before_install: - yes | gem update --system - bundle --version script: - 'bundle exec rake $CHECK' -matrix: +jobs: fast_finish: true include: - rvm: 2.4.4 bundler_args: --without system_tests development release env: PUPPET_VERSION="~> 5.0" CHECK=test - rvm: 2.5.3 bundler_args: --without system_tests development release env: PUPPET_VERSION="~> 6.0" CHECK=test_with_coveralls - rvm: 2.5.3 bundler_args: --without system_tests development release env: PUPPET_VERSION="~> 6.0" CHECK=rubocop - rvm: 2.4.4 bundler_args: --without system_tests development release env: PUPPET_VERSION="~> 5.0" CHECK=build DEPLOY_TO_FORGE=yes branches: only: - master - /^v\d/ notifications: email: false webhooks: https://voxpupu.li/incoming/travis irc: on_success: always on_failure: always channels: - "chat.freenode.org#voxpupuli-notifications" deploy: provider: puppetforge - user: puppet + username: puppet password: secure: "S8pxtUQSCxezeHuMTOa2nmbOC1Ln37evcDBd6rcAPse4DhrwzdJ7Ijme2tE+cPcdyYgO66jL0wWUBNia+10vOoYs1mCMj3mUq2bgySRhML0CQxGIvKYu8R6PbijljSK7LYplD1THQRgFLyHQ+f4Mh7+8yFpjXSmxuAQMdCPfPv8=" on: tags: true # all_branches is required to use tags all_branches: true # Only publish the build marked with "DEPLOY_TO_FORGE" condition: "$DEPLOY_TO_FORGE = yes" diff --git a/Gemfile b/Gemfile index 4d187cc..8592cd6 100644 --- a/Gemfile +++ b/Gemfile @@ -1,68 +1,48 @@ 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 group :test do - gem 'voxpupuli-test', :require => false - gem 'coveralls', :require => false - gem 'simplecov-console', :require => false + gem 'voxpupuli-test', '~> 2.0', :require => false + gem 'coveralls', :require => false + gem 'simplecov-console', :require => false end group :development do gem 'travis', :require => false gem 'travis-lint', :require => false gem 'guard-rake', :require => false gem 'overcommit', '>= 0.39.1', :require => false end group :system_tests do - gem 'winrm', :require => false - if beaker_version = ENV['BEAKER_VERSION'] - gem 'beaker', *location_for(beaker_version) - else - gem 'beaker', '>= 4.2.0', :require => false - end - if beaker_rspec_version = ENV['BEAKER_RSPEC_VERSION'] - gem 'beaker-rspec', *location_for(beaker_rspec_version) - else - gem 'beaker-rspec', :require => false - end - gem 'serverspec', :require => false - gem 'beaker-hostgenerator', '>= 1.1.22', :require => false - gem 'beaker-docker', :require => false - gem 'beaker-puppet', :require => false - gem 'beaker-puppet_install_helper', :require => false - gem 'beaker-module_install_helper', :require => false - gem 'rbnacl', '>= 4', :require => false - gem 'rbnacl-libsodium', :require => false - gem 'bcrypt_pbkdf', :require => false - gem 'ed25519', :require => false + gem 'voxpupuli-acceptance', :require => false end group :release do gem 'github_changelog_generator', :require => false, :git => 'https://github.com/voxpupuli/github-changelog-generator', :branch => 'voxpupuli_essential_fixes' gem 'puppet-blacksmith', :require => false gem 'voxpupuli-release', :require => false gem 'puppet-strings', '>= 2.2', :require => false end if facterversion = ENV['FACTER_GEM_VERSION'] gem 'facter', facterversion.to_s, :require => false, :groups => [:test] else gem 'facter', :require => false, :groups => [:test] end ENV['PUPPET_VERSION'].nil? ? puppetversion = '~> 6.0' : puppetversion = ENV['PUPPET_VERSION'].to_s gem 'puppet', puppetversion, :require => false, :groups => [:test] # vim: syntax=ruby diff --git a/examples/bad_source.pp b/examples/bad_source.pp index 6bfd4ec..57407e8 100644 --- a/examples/bad_source.pp +++ b/examples/bad_source.pp @@ -1,5 +1,4 @@ archive { '/tmp/jta-1.1.jar': ensure => present, source => $bad_variable, } - diff --git a/manifests/artifactory.pp b/manifests/artifactory.pp index 6c60172..e951e4a 100644 --- a/manifests/artifactory.pp +++ b/manifests/artifactory.pp @@ -1,105 +1,104 @@ # Define: archive::artifactory # ============================ # # archive wrapper for downloading files from artifactory # # Parameters # ---------- # # * path: fully qualified filepath for the download the file or use archive_path and only supply filename. (namevar). # * ensure: ensure the file is present/absent. # * url: artifactory download URL. # * owner: file owner (see archive params for defaults). # * group: file group (see archive params for defaults). # * mode: file mode (see archive params for defaults). # * archive_path: the parent directory of local filepath. # * extract: whether to extract the files (true/false). # * creates: the file created when the archive is extracted (true/false). # * cleanup: remove archive file after file extraction (true/false). # # Examples # -------- # # archive::artifactory { '/tmp/logo.png': # url => 'https://repo.jfrog.org/artifactory/distributions/images/Artifactory_120x75.png', # owner => 'root', # group => 'root', # mode => '0644', # } # # $dirname = 'gradle-1.0-milestone-4-20110723151213+0300' # $filename = "${dirname}-bin.zip" # # archive::artifactory { $filename: # archive_path => '/tmp', # url => "http://repo.jfrog.org/artifactory/distributions/org/gradle/${filename}", # extract => true, # extract_path => '/opt', # creates => "/opt/${dirname}", # cleanup => true, # } # define archive::artifactory ( Stdlib::HTTPUrl $url, String $path = $name, Enum['present', 'absent'] $ensure = present, Optional[String] $owner = undef, Optional[String] $group = undef, Optional[String] $mode = undef, Optional[Boolean] $extract = undef, Optional[String] $extract_path = undef, Optional[String] $creates = undef, Optional[Boolean] $cleanup = undef, Optional[Stdlib::Absolutepath] $archive_path = undef, ) { - include archive::params if $archive_path { $file_path = "${archive_path}/${name}" } else { $file_path = $path } assert_type(Stdlib::Absolutepath, $file_path) |$expected, $actual| { fail("archive::artifactory[${name}]: \$name or \$archive_path must be '${expected}', not '${actual}'") } $maven2_data = archive::parse_artifactory_url($url) - if $maven2_data and $maven2_data['folder_iteg_rev'] == 'SNAPSHOT'{ + if $maven2_data and $maven2_data['folder_iteg_rev'] == 'SNAPSHOT' { # URL represents a SNAPSHOT version. eg 'http://artifactory.example.com/artifactory/repo/com/example/artifact/0.0.1-SNAPSHOT/artifact-0.0.1-SNAPSHOT.zip' # Only Artifactory Pro lets you download this directly but the corresponding fileinfo endpoint (where the sha1 checksum is published) doesn't exist. # This means we can't use the artifactory_sha1 function $latest_url_data = archive::artifactory_latest_url($url, $maven2_data) $file_url = $latest_url_data['url'] $sha1 = $latest_url_data['sha1'] } else { $file_url = $url $sha1 = archive::artifactory_checksum($url,'sha1') } archive { $file_path: ensure => $ensure, path => $file_path, extract => $extract, extract_path => $extract_path, source => $file_url, checksum => $sha1, checksum_type => 'sha1', creates => $creates, cleanup => $cleanup, } $file_owner = pick($owner, $archive::params::owner) $file_group = pick($group, $archive::params::group) $file_mode = pick($mode, $archive::params::mode) file { $file_path: owner => $file_owner, group => $file_group, mode => $file_mode, require => Archive[$file_path], } } diff --git a/manifests/go.pp b/manifests/go.pp index f9a9285..d814bfb 100644 --- a/manifests/go.pp +++ b/manifests/go.pp @@ -1,61 +1,60 @@ # download from go define archive::go ( String $server, Integer $port, String $url_path, String $md5_url_path, String $username, String $password, Enum['present', 'absent'] $ensure = present, String $path = $name, Optional[String] $owner = undef, Optional[String] $group = undef, Optional[String] $mode = undef, Optional[Boolean] $extract = undef, Optional[String] $extract_path = undef, Optional[String] $creates = undef, Optional[Boolean] $cleanup = undef, Optional[Stdlib::Compat::Absolute_path] $archive_path = undef, ) { - include archive::params if $archive_path { $file_path = "${archive_path}/${name}" } else { $file_path = $path } if $file_path !~ Stdlib::Compat::Absolute_path { fail("archive::go[${name}]: \$name or \$archive_path must be an absolute path!") # lint:ignore:trailing_comma } $go_url = "http://${server}:${port}" $file_url = "${go_url}/${url_path}" $md5_url = "${go_url}/${md5_url_path}" archive { $file_path: ensure => $ensure, path => $file_path, extract => $extract, extract_path => $extract_path, source => $file_url, checksum => archive::go_md5($username, $password, $name, $md5_url), checksum_type => 'md5', creates => $creates, cleanup => $cleanup, username => $username, password => $password, } $file_owner = pick($owner, $archive::params::owner) $file_group = pick($group, $archive::params::group) $file_mode = pick($mode, $archive::params::mode) file { $file_path: owner => $file_owner, group => $file_group, mode => $file_mode, require => Archive[$file_path], } } diff --git a/manifests/init.pp b/manifests/init.pp index 5437296..6e67b63 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -1,70 +1,69 @@ # @summary Manages archive module's dependencies. # # @example On Windows, ensure 7zip is installed using the default `chocolatey` provider. # include archive # # @example On Windows, install a 7zip MSI with the native `windows` package provider. # class { 'archive': # seven_zip_name => '7-Zip 9.20 (x64 edition)', # seven_zip_source => 'C:/Windows/Temp/7z920-x64.msi', # seven_zip_provider => 'windows', # } # # @example Install the AWS CLI tool. (Not supported on Windows). # class { 'archive': # aws_cli_install => true, # } # # @param seven_zip_name # 7zip package name. This parameter only applies to Windows. # @param seven_zip_provider # 7zip package provider. This parameter only applies to Windows where it defaults to `chocolatey`. Can be set to an empty string, (or `undef` via hiera), if you don't want this module to manage 7zip. # @param seven_zip_source # Alternative package source for 7zip. This parameter only applies to Windows. # @param aws_cli_install # Installs the AWS CLI command needed for downloading from S3 buckets. This parameter is currently not implemented on Windows. # class archive ( Optional[String[1]] $seven_zip_name = $archive::params::seven_zip_name, Optional[Enum['chocolatey','windows','']] $seven_zip_provider = $archive::params::seven_zip_provider, Optional[String[1]] $seven_zip_source = undef, Boolean $aws_cli_install = false, ) inherits archive::params { - if $facts['os']['family'] == 'Windows' and !($seven_zip_provider in ['', undef]) { package { '7zip': ensure => present, name => $seven_zip_name, source => $seven_zip_source, provider => $seven_zip_provider, } } if $aws_cli_install { # TODO: Windows support. if $facts['os']['family'] != 'Windows' { # Using bundled install option: # http://docs.aws.amazon.com/cli/latest/userguide/installing.html#install-bundle-other-os file { '/opt/awscli-bundle': ensure => 'directory', } archive { 'awscli-bundle.zip': ensure => present, - path => '/opt/awscli-bundle/awscli-bundle.zip', + path => '/opt/awscli-bundle/awscli-bundle.zip', source => 'https://s3.amazonaws.com/aws-cli/awscli-bundle.zip', extract => true, extract_path => '/opt', creates => '/opt/awscli-bundle/install', cleanup => true, } exec { 'install_aws_cli': command => '/opt/awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws', refreshonly => true, subscribe => Archive['awscli-bundle.zip'], } } } } diff --git a/manifests/nexus.pp b/manifests/nexus.pp index 17e27df..f070ddd 100644 --- a/manifests/nexus.pp +++ b/manifests/nexus.pp @@ -1,114 +1,122 @@ # define: archive::nexus # ====================== # # archive wrapper for downloading files from Nexus using REST API. Nexus API: # https://repository.sonatype.org/nexus-restlet1x-plugin/default/docs/path__artifact_maven_content.html # # Parameters # ---------- # # Examples # -------- # # archive::nexus { '/tmp/jtstand-ui-0.98.jar': # url => 'https://oss.sonatype.org', # gav => 'org.codehaus.jtstand:jtstand-ui:0.98', # repository => 'codehaus-releases', # packaging => 'jar', # extract => false, # } # define archive::nexus ( String $url, String $gav, String $repository, Enum['present', 'absent'] $ensure = present, Enum['none', 'md5', 'sha1', 'sha2','sha256', 'sha384', 'sha512'] $checksum_type = 'md5', Boolean $checksum_verify = true, String $packaging = 'jar', Boolean $use_nexus3_urls = false, Optional[String] $classifier = undef, Optional[String] $extension = undef, Optional[String] $username = undef, Optional[String] $password = undef, Optional[String] $user = undef, Optional[String] $owner = undef, Optional[String] $group = undef, Optional[String] $mode = undef, Optional[Boolean] $extract = undef, Optional[String] $extract_path = undef, Optional[String] $extract_flags = undef, Optional[String] $extract_command = undef, Optional[String] $creates = undef, Optional[Boolean] $cleanup = undef, Optional[String] $proxy_server = undef, Optional[String] $proxy_type = undef, Optional[Boolean] $allow_insecure = undef, ) { - include archive::params $artifact_info = split($gav, ':') $group_id = $artifact_info[0] $artifact_id = $artifact_info[1] $version = $artifact_info[2] $query_params = { - 'g' => $group_id, 'a' => $artifact_id, 'v' => $version, 'r' => $repository, 'p' => $packaging, 'c' => $classifier, 'e' => $extension, - }.filter |$keys, $values| { $values != undef } if $use_nexus3_urls { if $classifier { $c = "-${classifier}" } else { $c = '' } - $artifact_url = sprintf('%s/repository/%s/%s/%s/%s/%s-%s%s.%s', $url, - $repository, regsubst($group_id, '\.', '/', 'G'), $artifact_id, - $version, $artifact_id, $version, $c, $packaging) + + $artifact_url = sprintf( + '%s/repository/%s/%s/%s/%s/%s-%s%s.%s', + $url, + $repository, + regsubst($group_id, '\.', '/', 'G'), + $artifact_id, + $version, + $artifact_id, + $version, + $c, + $packaging + ) + $checksum_url = sprintf('%s.%s', $artifact_url, $checksum_type) } else { $artifact_url = archive::assemble_nexus_url($url, $query_params) $checksum_url = regsubst($artifact_url, "p=${packaging}", "p=${packaging}.${checksum_type}") } archive { $name: ensure => $ensure, source => $artifact_url, username => $username, password => $password, checksum_url => $checksum_url, checksum_type => $checksum_type, checksum_verify => $checksum_verify, extract => $extract, extract_path => $extract_path, extract_flags => $extract_flags, extract_command => $extract_command, user => $user, group => $group, creates => $creates, cleanup => $cleanup, proxy_server => $proxy_server, proxy_type => $proxy_type, allow_insecure => $allow_insecure, } $file_owner = pick($owner, $archive::params::owner) $file_group = pick($group, $archive::params::group) $file_mode = pick($mode, $archive::params::mode) file { $name: owner => $file_owner, group => $file_group, mode => $file_mode, require => Archive[$name], } } diff --git a/spec/support/shared_behaviour.rb b/spec/support/shared_behaviour.rb index 08e08ca..9f4e455 100644 --- a/spec/support/shared_behaviour.rb +++ b/spec/support/shared_behaviour.rb @@ -1,107 +1,106 @@ -# rubocop:disable RSpec/MultipleExpectations require 'spec_helper' require 'tmpdir' RSpec.shared_examples 'an archive provider' do |provider_class| describe provider_class do let(:resource) do Puppet::Type::Archive.new(name: '/tmp/example.zip', source: 'http://home.lan/example.zip') end let(:provider) do provider_class.new(resource) end let(:zipfile) do File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'files', 'test.zip')) end it '#checksum?' do Dir.mktmpdir do |dir| resource[:path] = File.join(dir, resource[:filename]) FileUtils.cp(zipfile, resource[:path]) resource[:checksum] = '377ec712d7fdb7266221db3441e3af2055448ead' resource[:checksum_type] = :sha1 expect(provider.checksum?).to eq true resource[:checksum] = '557e2ebb67b35d1fddff18090b6bc26b' resource[:checksum_type] = :md5 expect(provider.checksum?).to eq true resource[:checksum] = '557e2ebb67b35d1fddff18090b6bc26b' resource[:checksum_type] = :sha1 expect(provider.checksum?).to eq false end end it '#extract' do skip 'jruby not supported' if defined? JRUBY_VERSION Dir.mktmpdir do |dir| resource[:path] = File.join(dir, resource[:filename]) extracted_file = File.join(dir, 'test') FileUtils.cp(zipfile, resource[:path]) resource[:extract] = :true resource[:creates] = extracted_file resource[:extract_path] = dir provider.extract expect(File.read(extracted_file)).to eq "hello world\n" end end it '#extracted?' do skip 'jruby not supported' if defined? JRUBY_VERSION Dir.mktmpdir do |dir| resource[:path] = File.join(dir, resource[:filename]) extracted_file = File.join(dir, 'test') FileUtils.cp(zipfile, resource[:path]) resource[:extract] = :true resource[:creates] = extracted_file resource[:extract_path] = dir expect(provider.extracted?).to eq false provider.extract expect(provider.extracted?).to eq true end end it '#cleanup' do skip 'jruby not supported' if defined? JRUBY_VERSION Dir.mktmpdir do |dir| resource[:path] = File.join(dir, resource[:filename]) extracted_file = File.join(dir, 'test') FileUtils.cp(zipfile, resource[:path]) resource[:extract] = :true resource[:cleanup] = :true resource[:creates] = extracted_file resource[:extract_path] = dir provider.extract provider.cleanup expect(File.exist?(resource[:path])).to eq false end end it '#create' do skip 'jruby not supported' if defined? JRUBY_VERSION Dir.mktmpdir do |dir| resource[:path] = File.join(dir, resource[:filename]) extracted_file = File.join(dir, 'test') FileUtils.cp(zipfile, resource[:path]) resource[:extract] = :true resource[:cleanup] = :true resource[:creates] = extracted_file resource[:extract_path] = dir provider.create expect(File.read(extracted_file)).to eq "hello world\n" expect(File.exist?(resource[:path])).to eq false end end end end diff --git a/spec/unit/puppet_x/bodeco/archive_spec.rb b/spec/unit/puppet_x/bodeco/archive_spec.rb index f4efd0f..11f352d 100644 --- a/spec/unit/puppet_x/bodeco/archive_spec.rb +++ b/spec/unit/puppet_x/bodeco/archive_spec.rb @@ -1,152 +1,152 @@ require 'spec_helper' require 'puppet_x/bodeco/archive' describe PuppetX::Bodeco::Archive do let(:zipfile) do File.expand_path(File.join(__dir__, '..', '..', '..', '..', 'files', 'test.zip')) end describe '#checksum' do include_context 'uses temp dir' subject { described_class.new(tempfile) } let(:tempfile) { File.join(temp_dir, 'test.zip') } before { FileUtils.cp(zipfile, tempfile) } it { expect(subject.checksum(:none)).to be nil } it { expect(subject.checksum(:md5)).to eq '557e2ebb67b35d1fddff18090b6bc26b' } it { expect(subject.checksum(:sha1)).to eq '377ec712d7fdb7266221db3441e3af2055448ead' } end describe '#parse_flags' do subject { described_class.new('test.tar.gz') } it { expect(subject.send(:parse_flags, 'xf', :undef, 'tar')).to eq 'xf' } it { expect(subject.send(:parse_flags, 'xf', 'xvf', 'tar')).to eq 'xvf' } it { expect(subject.send(:parse_flags, 'xf', { 'tar' => 'xzf', '7z' => '-y x' }, 'tar')).to eq 'xzf' } end describe '#command' do subject { |example| described_class.new(example.metadata[:filename]) } before { allow(Facter).to receive(:value).with(:osfamily).and_return(os) } - after { expect(Facter).to have_received(:value).with(:osfamily).at_least(:twice) } + after { expect(Facter).to have_received(:value).with(:osfamily).at_least(:twice) } # rubocop:disable RSpec/ExpectInHook describe 'on RedHat' do let(:os) { 'RedHat' } describe 'tar.gz', filename: 'test.tar.gz' do it { expect(subject.send(:command, :undef)).to eq 'tar xzf test.tar.gz' } it { expect(subject.send(:command, 'xvf')).to eq 'tar xvf test.tar.gz' } end describe 'tar.bz2', filename: 'test.tar.bz2' do it { expect(subject.send(:command, :undef)).to eq 'tar xjf test.tar.bz2' } it { expect(subject.send(:command, 'xjf')).to eq 'tar xjf test.tar.bz2' } end describe 'tar.xz', filename: 'test.tar.xz' do it { expect(subject.send(:command, :undef)).to eq 'unxz -dc test.tar.xz | tar xf -' } end describe 'gz', filename: 'test.gz' do it { expect(subject.send(:command, :undef)).to eq 'gunzip -d test.gz' } end describe 'bz2', filename: 'test.bz2' do it { expect(subject.send(:command, :undef)).to eq 'bunzip2 -d test.bz2' } end describe 'zip' do describe 'filename', filename: 'test.zip' do it { expect(subject.send(:command, :undef)).to eq 'unzip -o test.zip' } it { expect(subject.send(:command, '-a')).to eq 'unzip -a test.zip' } end describe 'path with space', filename: '/tmp/fun folder/test.zip' do it { expect(subject.send(:command, :undef)).to eq 'unzip -o /tmp/fun\ folder/test.zip' } it { expect(subject.send(:command, '-a')).to eq 'unzip -a /tmp/fun\ folder/test.zip' } end end end system_v = %w[Solaris AIX] system_v.each do |os| describe "on #{os}" do let(:os) { os } describe 'tar.gz', filename: 'test.tar.gz' do it { expect(subject.send(:command, :undef)).to eq 'gunzip -dc test.tar.gz | tar xf -' } it { expect(subject.send(:command, 'gunzip' => '-dc', 'tar' => 'xvf')).to eq 'gunzip -dc test.tar.gz | tar xvf -' } end describe 'tar.bz2', filename: 'test.tar.bz2' do it { expect(subject.send(:command, :undef)).to eq 'bunzip2 -dc test.tar.bz2 | tar xf -' } it { expect(subject.send(:command, 'bunzip' => '-dc', 'tar' => 'xvf')).to eq 'bunzip2 -dc test.tar.bz2 | tar xvf -' } end describe 'tar.xz', filename: 'test.tar.xz' do it { expect(subject.send(:command, :undef)).to eq 'unxz -dc test.tar.xz | tar xf -' } end describe 'gz', filename: 'test.gz' do it { expect(subject.send(:command, :undef)).to eq 'gunzip -d test.gz' } end describe 'zip' do describe 'filename', filename: 'test.zip' do it { expect(subject.send(:command, :undef)).to eq 'unzip -o test.zip' } it { expect(subject.send(:command, '-a')).to eq 'unzip -a test.zip' } end describe 'path with space' do subject { described_class.new('/tmp/fun folder/test.zip') } it { expect(subject.send(:command, :undef)).to eq 'unzip -o /tmp/fun\ folder/test.zip' } it { expect(subject.send(:command, '-a')).to eq 'unzip -a /tmp/fun\ folder/test.zip' } end end describe 'tar.Z' do subject { described_class.new('test.tar.Z') } it { expect(subject.send(:command, :undef)).to eq 'uncompress -c test.tar.Z | tar xf -' } end end end describe 'on Windows' do let(:os) { 'windows' } # rubocop:disable RSpec/SubjectStub before { allow(subject).to receive(:win_7zip).and_return(zip_cmd) } # rubocop:enable RSpec/SubjectStub context '7z.exe' do let(:zip_cmd) { '7z.exe' } describe 'tar.gz', filename: 'test.tar.gz' do it { expect(subject.send(:command, :undef)).to eq '7z.exe x -aoa "test.tar.gz"' } it { expect(subject.send(:command, 'x -aot')).to eq '7z.exe x -aot "test.tar.gz"' } end describe 'zip' do describe 'filename', filename: 'test.zip' do it { expect(subject.send(:command, :undef)).to eq '7z.exe x -aoa "test.zip"' } end describe 'path with space', filename: 'C:/Program Files/test.zip' do it { expect(subject.send(:command, :undef)).to eq '7z.exe x -aoa "C:/Program Files/test.zip"' } end end end describe 'powershell', filename: 'C:/Program Files/test.zip' do let(:zip_cmd) { 'powershell' } it { expect(subject.send(:command, :undef)).to eq 'powershell' } end end end end